この記事は「Opt Technologies Advent Calendar 2017」の7日目です。
はじめに
業務ではよくScalikeJDBCを使っているのですが、SQLSyntaxProvider系の挙動を中々覚えられないのでまとめてみました。
実験に使ったコード
ScalikeJDBC 3.1.0にて、以下のコードを用いました。
import scalikejdbc._
case class Member(id: Long, groupId: Long)
object Member extends SQLSyntaxSupport[Member] {
override val columnNames = Seq("id", "group_id")
}
val m = Member.syntax("m")
val m2 = Member.syntax("m2")
val s = SubQuery.syntax("s").include(m, m2)
挙動
ColumnSQLSyntaxProvider(Member.column
)
式 | 結果 | コメント |
---|---|---|
Member.column.columns | List(sqls"id", sqls"group_id") | |
Member.column.* | sqls"id, group_id" | |
Member.column.asterisk | sqls"*" | |
Member.column.groupId Member.column.field("groupId") Member.column.column("group_id") |
sqls"group_id" |
QuerySQLSyntaxProvider(m
)
式 | 結果 | コメント |
---|---|---|
m.columns | List(sqls"id", sqls"group_id") | |
m.* | sqls"m.id, m.group_id" | |
m.asterisk | sqls"m.*" | |
m.groupId m.field("groupId") m.column("group_id") |
sqls"m.group_id" |
ResultSQLSyntaxProvider(m.result
)
式 | 結果 | コメント |
---|---|---|
m.result.columns | List(sqls"id", sqls"group_id") | |
m.result.* | sqls"m.id as i_on_m, m.group_id as gi_on_m" | |
m.result.groupId m.result.field("groupId") m.result.column("group_id") |
sqls"m.group_id as gi_on_m" |
PartialResultSQLSyntaxProvider(m.result(sqls"foo")
)
式 | 結果 | コメント |
---|---|---|
m.result(sqls"foo").columns | List(sqls"id", sqls"group_id") | |
m.result(sqls"foo").groupId m.result(sqls"foo").field("groupId") m.result(sqls"foo").column("group_id") |
sqls"foo as gi_on_m" |
min(m.id) as i_on_m のように使う想定かと思います |
BaseResultNameSQLSyntaxProvider(m.resultName
)
式 | 結果 | コメント |
---|---|---|
m.resultName.columns | List(sqls"id", sqls"group_id") | |
m.resultName.namedColumns | List(sqls"i_on_m", sqls"gi_on_m") | |
m.resultName.* | sqls"i_on_m, gi_on_m" | |
m.resultName.groupId m.resultName.field("groupId") m.resultName.column("group_id") m.resultName.namedColumn("gi_on_m") |
sqls"gi_on_m" |
SubQuerySQLSyntaxProvider(s
)
式 | 結果 | コメント |
---|---|---|
s.* | sqls"s.i_on_m, s.gi_on_m, s.i_on_m2, s.gi_on_m2" | |
s.asterisk | sqls"s.*" | |
s(sqls"gi_on_m") | sqls"s.gi_on_m" |
SubQueryResultSQLSyntaxProvider(s.result
)
式 | 結果 | コメント |
---|---|---|
s.result.* | sqls"s.i_on_m as i_on_m_on_s, s.gi_on_m as gi_on_m_on_s, s.i_on_m2 as i_on_m2_on_s, s.gi_on_m2 as gi_on_m2_on_s" | |
s.result.column("gi_on_m") | InvalidColumnNameException | バグっぽかったのでPRしてみました |
SubQueryResultNameSQLSyntaxProvider(s.resultName
)
式 | 結果 | コメント |
---|---|---|
s.resultName.columns | ArrayBuffer(sqls"i_on_m_on_s", sqls"gi_on_m_on_s", sqls"i_on_m2_on_s", sqls"gi_on_m2_on_s") | ここだけListでなかったです |
s.resultName.* | sqls"i_on_m_on_s, gi_on_m_on_s, i_on_m2_on_s, gi_on_m2_on_s" | |
s.resultName(sqls"gi_on_m") s.resultName.column("gi_on_m_on_s") |
sqls"gi_on_m_on_s" |
PartialSubQuerySQLSyntaxProvider(s(m)
)
式 | 結果 | コメント |
---|---|---|
s(m).* | sqls"s.i_on_m_on_s, s.gi_on_m_on_s" | |
s(m).asterisk | sqls"s.*" | |
s(m).columns | List(sqls"id", sqls"group_id") | |
s(m).groupId s(m).field("groupId") s(m).column("group_id") s(m)(sqls"gi_on_m") |
sqls"s.gi_on_m" |
PartialSubQueryResultSQLSyntaxProvider(s(m).result
)
式 | 結果 | コメント |
---|---|---|
s(m).result.columns | List(sqls"id", sqls"group_id") | |
s(m).result.* | sqls"s.i_on_m as i_on_m_on_s, s.gi_on_m as gi_on_m_on_s" | |
s(m).result.field("gi_on_m") s(m).result.column("gi_on_m") |
sqls"s.gi_on_m as gi_on_m_on_s" | columnとfieldの引数が同じで少し違和感 |
s(m).result.groupId | InvalidColumnNameException | 不具合かも? |
PartialSubQueryResultNameSQLSyntaxProvider(s(m).resultName
)
式 | 結果 | コメント |
---|---|---|
s(m).resultName.columns s(m).resultName.namedColumns |
List(sqls"i_on_m_on_s", sqls"gi_on_m_on_s") | columnsとnamedColumnsが一致して少し違和感 |
s(m).resultName.* | sqls"iom_on_s, gom_on_s" | バグっぽかったのでPRしてみました |
s(m).resultName.groupId s(m).resultName.field("group_id") s(m).resultName.column("group_id") s(m).resultName(sqls"gi_on_m") |
sqls"gi_on_m_on_s" | columnとfieldの引数が同じで少し違和感 |
s(m).resultName.namedColumn("gi_on_m") | sqls"gi_on_m" |
おわりに
まとめてはみたものの、やはりSubQueryが絡むとややこしいですね。困った時に参考になればと思います。