Jdbi: BindList๊ฐ€ ์ฟผ๋ฆฌ์—์„œ ๋‚ด ๋ช…๋ช…๋œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๊ณ  ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2018๋…„ 02์›” 01์ผ  ยท  4์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: jdbi/jdbi

๋ช…๋ช…๋œ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š” SQL ์ฟผ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. :featureIds

const val selectGeoCoordinates = "SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN (:featureIds);"

Int ๋ชฉ๋ก์„ ๋ช…๋ช…๋œ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋ฐ”์ธ๋”ฉํ•˜๋ ค๊ณ  ํ•  ๋•Œ

val values: List<Int> = listOf(4138, 1752, 1161, 371, 1860, 5498)
val geoCoordinatesList = geo.withHandle<List<GeoCoordinates>, Exception> { handle ->
                handle.createQuery(selectGeoCoordinates).bindList("featureIds", values)
                        .mapTo<GeoCoordinates>().list()
            }

์‹คํ–‰ ์‹œ ๋‹ค์Œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

    Caused by: org.jdbi.v3.core.statement.UnableToExecuteStatementException: Unable to execute, no named parameter matches 'featureIds'. [statement:"SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN :featureIds ;", rewritten:"SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN :featureIds ;", parsed:"ParsedSql{sql='SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN ? ;', parameters=ParsedParameters{positional=false, parameterNames=[featureIds]}}", arguments:{ positional:{}, named:{__featureIds_0:4138,__featureIds_4:1860,__featureIds_3:371,__featureIds_2:1161,__featureIds_1:1752,__featureIds_5:5498}, finder:[]}]
    at org.jdbi.v3.core.statement.ArgumentBinder.lambda$bindNamed$0(ArgumentBinder.java:58)
    at java.util.Optional.orElseThrow(Optional.java:290)
    at org.jdbi.v3.core.statement.ArgumentBinder.bindNamed(ArgumentBinder.java:57)
    at org.jdbi.v3.core.statement.ArgumentBinder.bind(ArgumentBinder.java:27)
    at org.jdbi.v3.core.statement.SqlStatement.internalExecute(SqlStatement.java:1443)
    at org.jdbi.v3.core.result.ResultProducers.lambda$getResultSet$2(ResultProducers.java:59)
    at org.jdbi.v3.core.result.ResultIterable.lambda$of$0(ResultIterable.java:53)
    at org.jdbi.v3.core.result.ResultIterable.stream(ResultIterable.java:141)
    at org.jdbi.v3.core.result.ResultIterable.collect(ResultIterable.java:197)
    at org.jdbi.v3.core.result.ResultIterable.list(ResultIterable.java:186)

.bind("featureIds", 4138) ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž‘๋™ํ•˜๋ฏ€๋กœ ์ด๋ฆ„์ด ์ •ํ™•ํ•˜๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์ด๊ฒƒ์„ ์–ป์—ˆ์Šต๋‹ˆ๊นŒ? ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•ด ์™„์ „ํžˆ ์˜์•„ํ•ดํ•˜๋ฏ€๋กœ ์–ด๋–ค ๋„์›€์ด๋ผ๋„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค :(

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ข‹์•„... StringTemplateEngine์„ ์‹œ๋„ํ•˜๋Š” ๋™์•ˆ ์†”๋ฃจ์…˜์„ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ชฉ๋ก์— ๋Œ€ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ <> ์— ๋„ฃ์œผ๋ฉด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
"SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN (<featureIds>);"

.bindList("featureIds", values) ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ ๋ฌธ์„œ์— ์ถ”๊ฐ€ํ•˜๊ณ  bindList ์— ๋Œ€ํ•œ ์˜ˆ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? :)

๋ชจ๋“  4 ๋Œ“๊ธ€

์ข‹์•„... StringTemplateEngine์„ ์‹œ๋„ํ•˜๋Š” ๋™์•ˆ ์†”๋ฃจ์…˜์„ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ชฉ๋ก์— ๋Œ€ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ <> ์— ๋„ฃ์œผ๋ฉด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
"SELECT gg.feature_id, gg.latitude, gg.longitude, gg.order, gg.group FROM geo.geo_coordinates as gg WHERE gg.feature_id IN (<featureIds>);"

.bindList("featureIds", values) ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ ๋ฌธ์„œ์— ์ถ”๊ฐ€ํ•˜๊ณ  bindList ์— ๋Œ€ํ•œ ์˜ˆ๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? :)

์˜ˆ, bindList๋Š” ์‹ค์ œ๋กœ ํ™•์žฅํ•˜์—ฌ <featureIds> ๋ฅผ :__featureIds_0, :__featureIds_1, ...etc ์™€ ๊ฐ™์ด ์ •์˜ํ•˜๊ณ  ๋ชฉ๋ก ์š”์†Œ๋ฅผ ํ•ด๋‹น ๋Œ€์ฒด ๋ณ€์ˆ˜์— ๋ฐ”์ธ๋”ฉํ•ฉ๋‹ˆ๋‹ค.

Postgres๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์ฟผ๋ฆฌ์—์„œ where featureIds = any(:featureIds) ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  bindByType("featureIds", featureIds, new GenericType<List<Long>>() {}) ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชฉ๋ก์„ SQL ๋ฐฐ์—ด๋กœ ๋ฐ”์ธ๋”ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ข€๋น„๊ฐ€ ์•„๋‹ˆ๋ผ List ๊ฐ€ ํฌํ•จ๋œ ๋‹จ์ผ ํ‚ค์— ๋Œ€ํ•ด Map<String, Object> bindMap ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” bindList ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง€๋„์™€ ๋ณ„๋„๋กœ ๋ฐ”์ธ๋”ฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•ํ•ฉ๋‹ˆ๊นŒ?

์˜ˆ์‹œ:

  a,b,c
from
  table
where
  a = :some_string
  and b = ANY(<list_of_strings>)

๋‹ค์Œ์˜ ๋ฐ”์ธ๋”ฉ์œผ๋กœ:

.bindMap(Map.of(
  'some_string', 'foobar',
  'list_of_strings', Lists.newArrayList('q', 'r', 's')
))

ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค:

org.jdbi.v3.core.statement.UnableToCreateStatementException: Undefined attribute for token '<list_of_strings>' 

๋งž์Šต๋‹ˆ๋‹ค. bindMap ๋Š” ์ธ์ˆ˜๋งŒ ๋ฐ”์ธ๋”ฉํ•˜๋Š” ๋ฐ˜๋ฉด bindList ๋Š” ํ…œํ”Œ๋ฆฟ์ด ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๋„๋ก ์†์„ฑ๋„ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰