タグ別アーカイブ: Slick

Slick3.0 トランザクション内で、クエリした結果を使って更新処理を行う

クエリした結果(リスト)から別の更新処理を行う方法です。

トランザクション内で処理するために、DBActionにまとめないとダメなのですが、
このへん、ちょっとややこしいですよね。

以下はTableAから得た結果(リスト)からTableBの削除を行う例です

val action =
(for {
   // TableAをクエリ
   list <- TableA.filter(name === "tateo").result
   // その結果を使ってTableBを削除
   _ <- DBIO.seq( list.map(r => TableB.filter(id === r.id).delete  ) : _*  )
} yield () ).transactionally

db.run(action)

SlickでANDとORを混在させたクエリを発行する

例えばこんなSQLを発行したかったりします。

select * from cities
where (population > 100000) and (class = '都' or class = '府')

Slickではこんな感じで書けます

Cities.filter(row => row.population > 100000 && ( class === '都' || class === '府' ))


“AND” は “&&”、”OR” は “||” で記述し、必要な箇所でカッコを記述すれば目的のクエリとなってくれました。

これが動的になった場合にはどうするか?
例えば 下記のSQLで都道府県の抽出が可変の場合(inで書けってのは無しで・・)

select * from cities
where (population > 100000)
  and (class = '都' or class = '府' or class = '道' or class ='県')

試行錯誤した末にfunctionを作って対応しました。

def classConditions(row:Cities,t:Boolean,d:Boolean,f:Boolean,k:Boolean):Rep[Boolean] = {
  var condition:Rep[Boolean] = true
  if (t) condition = condition || (row.class === "都")
  if (d) condition = condition || (row.class === "道")
  if (f) condition = condition || (row.class === "府")
  if (k) condition = condition || (row.class === "県")
  condition
}

Cities.filter(row => row.population > 100000 && ( classConditions(row,true,true,false,false) ))

このへんの情報がなかなか見つからずに苦労します。