Knex 的 where
也可使用 Builder,藉此我們可動態組合 SQL。
Version
Knex 0.20.13
Knex-fp 0.0.10
Knex
import { log } from 'wink-fp'
let wherePrice = true
let whereTitle = true
mySQL ('books')
.where (x => {
if (wherePrice) x.where ('price', '>', 100)
if (whereTitle) x.where ('title', 'like', '%JavaScript%')
return x
})
.then (log)
Knex 的 where
非常靈活,能傳入 string,也能傳入 function。
若傳入 function 則視為 builder 使用,可根據條件動態組合 SQL。
Extract Function
import { log } from 'wink-fp'
let wherePrice = true
let whereTitle = true
let buildSQL = x => {
if (wherePrice) x.where('price', '>', 100)
if (whereTitle) x.where('title', 'like', '%JavaScript%')
return x
}
mySQL ('books')
.where (buildSQL)
.then (log)
可將 where
的 callback 抽成 named function 增加可讀性。
Higher Order Function
import { pipe } from 'ramda'
import { log } from 'wink-fp'
let wherePrice = true
let whereTitle = true
let genPrice = v => x => v ? x.where ('price', '>', 100) : x
let genTitle = v => x => v ? x.where ('title', 'like', '%JavaScript%') : x
let buildSQL = pipe (
genPrice (wherePrice),
genTitle (whereTitle)
)
mySQL ('books')
.where (buildSQL)
.then (log)
可將動態組合 SQL 部分抽成 genPrice
與 genTitle
higher order function,buildSQL
改以 pipe
組合,如此寫法可讀性更高,且也更容易重複使用。
Knex-fp
import { pipeK, where } from 'knex-fp'
import { identity } from 'ramda'
import { log } from 'wink-fp'
let wherePrice = true
let whereTitle = true
let genPrice = v => v ? where ('price', '>', 100) : identity
let genTitle = v => v ? where ('title', 'like', '%JavaScript%') : identity
let buildSQL = pipe (
genPrice (wherePrice),
genTitle (whereTitle)
)
pipeK (
where (buildSQL)
) (log) (mySQL ('books'))
也可使用 Knex-fp 的 pipeK
與 where
組合。
import { pipeK, where } from 'knex-fp'
import { identity } from 'ramda'
import { log } from 'wink-fp'
let wherePrice = true
let whereTitle = true
let genPrice = v => v ? where ('price', '>', 100) : identity
let genTitle = v => v ? where ('title', 'like', '%JavaScript%') : identity
pipeK (
genPrice (wherePrice),
genTitle (whereTitle)
) (log) (mySQL ('books'))
事實上若使用 Knex-fp,連 buildSQL
也不需要了,直接將 genPrice
與 genTitle
寫在 pipeK
即可,這就是 Function Pipeline 強悍之處。
Conclusion
- Knex 因為是 Method Chaining,所以特別在
where
提供 builder 動態建立 SQL,若使用 Knex-fp,因為 Function Pipeline 本身就是組合,可直接取代 builder