如何在 Slick 中参数化 table 名称

How to parameterize table name in Slick

class MyTable(tag: Tag) extends Table[MyEntity](tag, "1970Table") {
  def id = column[Int]("id")

  override def * = 
  (
   id
  ) <> (MyEntity.tupled, MyEntity.unapply)
}

val myTable = TableQuery[MyTable]

class MyRepository(val config: DatabaseConfig[JdbcProfile])
   extends MyRepository[MyTable, String] {
  override val table: config.profile.api.TableQuery[MyTable] = myTable

  def insert(me: MyEntity): Future[Int] = {
     db.run(table += me)
  }
}

我在我的另一个 类 中这样使用它:

  val myRepository = new MyRepository(dbConfig)

  myRepository.insert(myrecord)

问题

我不想使用硬编码的 table 名称,而是让 table 名称动态化。

我想更改 insert 方法,使其接受 year (int) 参数并根据年份参数选择正确的 table。即如果传入的年份是 1970 那么 table 名称是 1970Table 但如果传入的年份是 1980 那么 table 就是 1980Table .

尝试

class MyRepository(val config: DatabaseConfig[JdbcProfile]) {
  import config._
  import profile.api._

  abstract class MyTable(tag: Tag, name: String) extends Table[MyEntity](tag, name) {
    def id = column[Int]("id")
    override def * = (id) <> (MyEntity.tupled, MyEntity.unapply)
  }

  class Table1970(tag: Tag) extends MyTable[MyEntity](tag, "1970Table")
  class Table1980(tag: Tag) extends MyTable[MyEntity](tag, "1980Table")

  val table1970 = TableQuery[Table1970]
  val table1980 = TableQuery[Table1980]

  def insert(me: MyEntity, year: Int): Future[Int] = db.run {
    year match {
      case "1970" => table1970 += me
      case "1980" => table1980 += me 
    }
  }
}

现在

val myRepository = new MyRepository(dbConfig)
myRepository.insert(myrecord, "1970")

TableQuery 中有两个 apply 方法。 val myTable = TableQuery[MyTable] -
这个使用宏来创建 MyTable。 另一个是这样定义的:

def apply[E <: AbstractTable[_]](cons: Tag => E): TableQuery[E] =
    new TableQuery[E](cons)

所以你可以这样做

class MyTable(tag: Tag, tableName: String) extends Table[MyEntity](tag, tableName)
...
def myTable(name: String) = TableQuery[MyTable](tag =>  new MyTable(tag, name))

现在您可以预定义您需要的所有表格并使用它们或像这样进行操作

class MyRepository(val config: DatabaseConfig[JdbcProfile])
   extends MyRepository[MyTable, String] {
  override def table(year: Int): config.profile.api.TableQuery[MyTable] = myTable(year.toString)

  def insert(me: MyEntity, year: Int): Future[Int] = {
     db.run(table(year) += me)
  }
}