使用slick codegen

时间:2016-04-29 14:17:49

标签: scala slick slick-3.0

我正在开发一个使用光滑的scala项目作为它的数据库访问库。我正在尝试使用以下定义更新一行,其中有一个复合键。

class TableName(tag: Tag) extends Table[TableName](tag, "table_name"){
    def keyPart1 = column[String]("key_part_1", O.Length(100, varying = true))
    def keyPart2 = column[String]("key_part_2", O.Length(100, varying = true))
    // More columns defined
    def pk = primaryKey("t_composite_pk", (keyPart1, keyPart2))
    def * (keyPart1, keyPart2, ..more columns..) <> (TableNameRow.tupled, TableNameRow)
}

使用来自JdbcActionComponent的insertOrUpdate或update方法将无法插入或更新值。复合主键中有一个known issue,它将阻止这些方法正常运行,因为它无法确定它应该与哪个标识符相关。但是有一个解决方法。如果将O.PrimaryKey值添加为组成复合主键的行的参数,则光滑将能够正确地确定键。

class TableName(tag: Tag) extends Table[TableName](tag, "table_name"){
    def keyPart1 = column[String]("key_part_1", O.Length(100, varying = true), O.PrimaryKey)
    def keyPart2 = column[String]("key_part_2", O.Length(100, varying = true), O.PrimaryKey)
    // More columns defined
    def pk = primaryKey("t_composite_pk", (keyPart1, keyPart2))
    def * (keyPart1, keyPart2, ..more columns..) <> (TableNameRow.tupled, TableNameRow)
}

现在已将项目迁移到使用slick codegen,现在可以从数据库的模式动态生成代码模式。这个生成的模式没有解决复合主键的问题。

是否有一种方法可以使用复合主键创建灵活的codegen函数,以允许使用insertOrUpdate或更新? Codegen确实支持复合主键,但它仅用于生成以下值:

/** Primary key of TableName(database name table_name_pk) */
val pk = primaryKey("table_name_pk", (keyPart1, keyPart2)) 

然而,这似乎不足以使光滑能够正确识别行。如果无法使用,是否有其他方法可用于更新这些行?

1 个答案:

答案 0 :(得分:0)

通过审查有关更新的其他帖子确定的解决方法是使用此post中的过滤器(...)。update(...)。可以使用以下方法进行更新:

// Where the following was defined by the codegen
/** Collection-like TableQuery object for table TableName*/
lazy val TableName = new TableQuery(tag => new TableName(tag))

// We can then filter on the primary key values
def updateMethod(row: TableNameRow) = 
    TableName
       .filter(x => x.keyPart1 === row.keyPart1 && x.keyPart2 === row.keyPart2)
       .update(row)

它可以应用于允许使用复合键更新行,前提是我们通过过滤器模拟键。但是,这是一种解决方法,不允许使用JdbcActionComponent中的某些函数。