4

私の Play アプリには、100 を超える列を持つデータベース テーブルをクエリするメソッドがあります。そのようなクエリごとにケース クラスを定義することはできません。これは、途方もなく大きくなり、データベースのテーブルを変更するたびに変更する必要があるためです。

私はこのアプローチを使用しています。クエリの結果は次のようになります。

Map(columnName1 -> columnVal1, columnName2 -> columnVal2, ...)

コードの例:

implicit val getListStringResult = GetResult[List[Any]] (
    r => (1 to r.numColumns).map(_ => r.nextObject).toList
)

def getSomething(): Map[String, Any] = DB.withSession {
    val columns = MTable.getTables(None, None, None, None).list.filter(_.name.name == "myTable").head.getColumns.list.map(_.column) 
    val result = sql"""SELECT * FROM myTable LIMIT 1""".as[List[Any]].firstOption.map(columns zip _ toMap).get
}

クエリが単一のデータベースと単一のテーブルでのみ実行される場合、これは問題になりません。次のように、クエリで複数のテーブルとデータベースを使用できるようにする必要があります。

def getSomething(): Map[String, Any] = DB.withSession {

    //The line below is no longer valid because of multiple tables/databases
    val columns = MTable.getTables(None, None, None, None).list.filter(_.name.name == "table1").head.getColumns.list.map(_.column) 
    val result = sql"""
        SELECT      * 
        FROM        db1.table1
        LEFT JOIN   db2.table2 ON db2.table2.col1 = db1.table1.col1
        LIMIT       1
    """.as[List[Any]].firstOption.map(columns zip _ toMap).get

}

同じアプローチを列名の取得に使用することはできなくなりました。この問題は、PHP PDO や Java JDBCTemplate などを使用する場合には存在しません。これらは特別な労力を必要とせずに列名を取得します。

私の質問は、Slick でこれを達成するにはどうすればよいですか?

4

2 に答える 2

0

null 以外の列 (小文字のキー) を持つマップを生成する別のバリ​​アント:

private implicit val getMap = GetResult[Map[String, Any]](r => {
    val metadata = r.rs.getMetaData
    (1 to r.numColumns).flatMap(i => {
        val columnName = metadata.getColumnName(i).toLowerCase
        val columnValue = r.nextObjectOption
        columnValue.map(columnName -> _)
    }).toMap
})
于 2014-08-21T05:15:43.397 に答える