Saya mendapat SQL Query dengan parameter bernama :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);"
Ketika saya mencoba mengikat daftar Int ke parameter bernama
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()
}
Saya mendapatkan pengecualian berikut pada eksekusi:
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)
Jika saya menggunakan .bind("featureIds", 4138)
berhasil, oleh karena itu saya menganggap penamaan itu benar.
Ada yang punya ini? Bantuan apa pun diterima karena saya benar-benar bingung dengan yang ini :(
Oke... Saya menemukan solusi saat mencoba StringTemplateEngine. Ketika saya meletakkan parameter untuk daftar di <>
itu berfungsi.
"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)
berfungsi.
Mungkin tambahkan ini ke dokumentasi dan berikan contoh untuk bindList
? :)
Yap, bindList sebenarnya memperluas mendefinisikan <featureIds>
sebagai misalnya :__featureIds_0, :__featureIds_1, ...etc
dan mengikat elemen daftar ke variabel pengganti tersebut.
Jika Anda menggunakan Postgres, Anda dapat mengikat daftar sebagai array SQL menggunakan where featureIds = any(:featureIds)
dalam kueri dan menggunakan bindByType("featureIds", featureIds, new GenericType<List<Long>>() {})
.
Bukan untuk menjadi zombie, tetapi ketika menggunakan bindMap
dengan Map<String, Object>
untuk siapa kunci tunggal berisi List
, ini sepertinya tidak berhasil. Tampaknya parameter seperti itu perlu diikat secara terpisah dari peta dengan bindList
. Apakah ini akurat?
Contoh:
a,b,c
from
table
where
a = :some_string
and b = ANY(<list_of_strings>)
Dengan mengikat:
.bindMap(Map.of(
'some_string', 'foobar',
'list_of_strings', Lists.newArrayList('q', 'r', 's')
))
Akan memicu:
org.jdbi.v3.core.statement.UnableToCreateStatementException: Undefined attribute for token '<list_of_strings>'
Itu benar. bindMap
hanya mengikat argumen, sedangkan bindList
juga perlu mendefinisikan atribut agar templating berfungsi seperti yang diharapkan. Mereka tidak diatur untuk bekerja sama, meskipun itu mungkin saja berubah di masa depan.
Komentar yang paling membantu
Oke... Saya menemukan solusi saat mencoba StringTemplateEngine. Ketika saya meletakkan parameter untuk daftar di
<>
itu berfungsi."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)
berfungsi.Mungkin tambahkan ini ke dokumentasi dan berikan contoh untuk
bindList
? :)