Hai,
Pertama-tama, terima kasih untuk perpustakaan yang luar biasa ini.
Kesalahan yang saya alami adalah sebagai berikut:
Mengikat Daftar kosong
Tidak ada pabrik argumen yang terdaftar untuk '[]' tipe java.util.List
Bisakah Anda memberikan lebih banyak konteks? SQL apa yang Anda jalankan? Vendor basis data yang mana?
Hai @qualidafial ,
Sql: select * from invoice where invoice.id IN :ids
Vendor basis data: SQL Server 2017
Oke, itu masuk akal sekarang.
JDBC agak aneh ketika bekerja dengan array--Anda harus mengetahui nama tipe data yang digunakan oleh vendor database. Untuk membantu Jdbi menghubungkan titik-titik, Anda harus mendaftarkan nama tipe elemen array per nama kelas Java:
Jdbi jdbi = Jdbi.create(...);
...
jdbi.registerArrayType(int.class, "integer");
jdbi.registerArrayType(Integer.class, "integer");
Dengan demikian, kami dapat meningkatkan pesan pengecualian kami untuk mengarahkan pengguna ke arah yang benar.
@qualidafial Bro, ini yang terbaik, terima kasih banyak!
:+1: Sebagai peringatan, kami dapat menambahkan plugin SQL Server ke Jdbi jika Anda dapat mengarahkan saya ke beberapa dokumentasi sehingga saya tahu tipe data kustom apa yang didukung driver, dan pemetaan antara tipe Java dan tipe data JDBC nama.
Sepakat.
Tipe data dasar:
https://docs.microsoft.com/en-us/sql/connect/jdbc/using-basic-data-types
Tipe data lanjutan:
https://docs.microsoft.com/en-us/sql/connect/jdbc/using-advanced-data-types
@qualidafial FYI, ternyata pernyataan IN dengan SqlArray yang disiapkan tidak didukung oleh driver SQL Server JDBC
Anda juga dapat menggunakan @BindList
:
@SqlQuery("select * from invoice where invoice.id IN (<ids>)")
Set<Invoice> getInvoices(@BindList("ids") List<Integer> ids);
Ketahuilah bahwa vendor database yang berbeda mungkin membatasi jumlah item yang diizinkan dalam klausa WHERE column IN (a, b, c, ...)
dipisahkan koma.
Rupanya SQL server hanya mendukung parameter nilai tunggal, jadi saya membuat array secara manual, namun ini tidak aman untuk array String dan dapat memperkenalkan SQL Injection.
default List<LotInvoiceRef> getInvoices(List<Long> invoiceIds) {
final List<LotInvoiceRef> lotInvoiceRefs = invoiceIds.stream()
.map(String::valueOf)
.reduce((a, b) -> a + "," + b)
.map(this::getAllInvoiceRefs)
.orElse(new ArrayList<>());
return lotInvoiceRefs;
}
@georgerb silakan lihat komentar terakhir saya, yang seharusnya melindungi dari injeksi SQL
@qualidafial Saya suka pendekatan @BindList tapi saya butuh cara untuk mengizinkan daftar kosong untuk parameter yang @BindList secara eksplisit melarang.
@qualidafial nvm, Penggalian cepat ke dalam anotasi dan saya menggunakan ini: @BindList(value = "invoiceIds", onEmpty = BindList.EmptyHandling.NULL)
dan itu bekerja dengan sempurna
Sekali lagi, ini adalah kedudukan tertinggi. Apakah ada cara agar kita bisa berkontribusi? setidaknya membantu kalian dengan dokumentasi.
Terima kasih, Anda sangat baik. Kami :hati: tarik permintaan!
Dari percakapan ini saja saya mengumpulkan tiga kemungkinan perbaikan:
@BindList
(dan mungkin @DefineList
saat kami melakukannya).Jika Anda ingin mengirimkan masalah terpisah yang ditargetkan untuk masing-masing hal di atas. Kemudian kita bisa menutup yang ini dan melacak masing-masing secara terpisah.
Dan jika Anda memiliki ide untuk meningkatkan Jdbi yang ingin Anda jalankan, silakan lakukan! Plugin JPA, Kotlin, dan Vavr, serta banyak elemen Core dan SQL Object semuanya merupakan kiriman dari pengguna Jdbi.
@kualifikasi selesai. #993
Terima kasih! Menutup masalah ini demi #993
Komentar yang paling membantu
Oke, itu masuk akal sekarang.
JDBC agak aneh ketika bekerja dengan array--Anda harus mengetahui nama tipe data yang digunakan oleh vendor database. Untuk membantu Jdbi menghubungkan titik-titik, Anda harus mendaftarkan nama tipe elemen array per nama kelas Java: