Có hai cách để đạt được điều đó.
. Sử dụng UseStringTemplate3StatementLocator
chú thích này hy vọng Group Files với câu lệnh SQL trong StringTemplate
Nói rằng tôi có tập tin này PersonExternalizedSqlDAO
// PersonExternalizedSqlDAO.java
package com.daoexp.dao;
@@ExternalizedSqlViaStringTemplate3
@RegisterMapper(PersonMapper.class)
public interface PersonExternalizedSqlDAO {
@SqlQuery
List<Person> getPersonByNames(@BindIn("names") List<String> names);
}
Vì chúng ta đang sử dụng UseStringTemplate3StatementLocator
chúng ta phải tạo *.sql.stg
file trong đường dẫn cùng lớp. Đối với ví dụ: trong resources/com/daoexp/dao/PersonExternalizedSqlDAO.sql.stg
group PersonExternalizedSqlDAO;
getPersonByNames(names) ::= <<
select * from person where name in (<names>)
>>
Bây giờ bạn sẽ có thể truy vấn mà không cần bất kỳ vấn đề.
. Cách tiếp cận khác là sử dụng ArgumentFactory
xử lý loại dữ liệu tùy chỉnh của bạn (trong trường hợp này là Danh sách) cho JDBI với @Bind
. Đây là cách tiếp cận thích hợp nhất.
Vì vậy, tạo này nhà máy luận danh sách
public class ListArgumentFactory implements ArgumentFactory<List> {
@Override
public boolean accepts(Class<?> expectedType, Object value, StatementContext ctx) {
return value instanceof List;
}
@Override
public Argument build(Class<?> expectedType, final List value, StatementContext ctx) {
return new Argument() {
@Override
public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException {
String type = null;
if(value.get(0).getClass() == String.class){
type = "varchar";
} else if(value.get(0).getClass() == Integer.class){
// For integer and so on...
} else {
// throw error.. type not handled
}
Array array = ctx.getConnection().createArrayOf(type, value.toArray());
statement.setArray(position, array);
}
};
}
}
gì lớp này không?
- chấp nhận trường hợp của Danh sách
- chuyển đổi danh sách số nguyên/chuỗi mảng và liên kết với tuyên bố sẵn sàng
Hãy chắc chắn rằng bạn đăng ký nhà máy lập luận này với ví dụ DBI của bạn.
final DBIFactory factory = new DBIFactory();
final DBI jdbi = factory.build(environment, configuration.getDataSourceFactory(), "h2");
jdbi.registerArgumentFactory(new ListArgumentFactory());
Bây giờ bạn sẽ có thể truy vấn sử dụng List
theo cách đơn giản hơn (nghĩa là), bạn phải sử dụng @Bind
. Đó là nó.
@RegisterMapper(PersonMapper.class)
public interface PersonDAO {
@SqlQuery("select * from person where name = any(:names)")
List<Person> getPersonByNames(@Bind("names") List<String> names);
}
Tham khảo:
Thông tin bổ sung:
// PersonMapper.java
public class PersonMapper implements ResultSetMapper<Person> {
public Person map(int index, ResultSet r, StatementContext ctx) throws SQLException {
Person person = new Person();
person.setId(r.getInt("id"));
person.setName(r.getString("name"));
return person;
}
}
Có vẻ như tôi không thể sử dụng phương pháp hai do cơ sở dữ liệu SQL của tôi là MySQL. nơi các kiểu mảng không được hỗ trợ (createArrayOf). Tôi đã sử dụng phương thức đầu tiên của bạn bằng tệp sql.stg. Cảm ơn nhiều! Và btw, ExternalizedSqlViaStringTemplate3 không được dùng nữa, sử dụng UseStringTemplate3StatementLocator. – Kenneth
Tôi nhận ngoại lệ trong giải pháp 1 là, gây ra: org.skife.jdbi.v2.exceptions.UnableToExecuteStatementException: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Bạn có lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn cho cú pháp đúng để sử dụng gần 'getPersonByNames' ở dòng 1, tôi nghĩ rằng chuỗi sql không được thay thế. – dkb
Dường như phương thức hai cũng không được hỗ trợ trong Oracle: 'Gây ra bởi: java.sql.SQLException: Tính năng không được hỗ trợ tại oracle.jdbc.driver.PhysicalConnection.createArrayOf (PhysicalConnection.java:9283)' –