3.3 参数
将参数绑定到SQL语句时有两种选择:位置或命名。
任何语句都可以使用位置或命名参数,但它们永远不能在同一个SQL语句中混合使用。在这种情况下,Jdbi无法确定它是否绑定了正确的参数,并将抛出异常。
3.3.1 位置参数
当SQL语句使用?
标记时,Jdbi可以将值绑定到相应索引处的参数(从0开始)
handle.createUpdate("insert into contacts (id, name) values (?, ?)")
.bind(0, 3)
.bind(1, "Chuck")
.execute();
String name = handle.createQuery("select name from contacts where id = ?")
.bind(0, 3)
.mapTo(String.class)
.findOnly();
- 除了execute,还有其他的特殊执行方法,比如findOnly
3.3.2 命名参数
当SQL语句使用冒号前缀的标记时:name
,Jdbi可以按名称绑定参数:
handle.createUpdate("insert into contacts (id, name) values (:id, :name)")
.bind("id", 3)
.bind("name", "Chuck")
.execute();
String name = handle.createQuery("select name from contacts where id = :id")
.bind("id", 3)
.mapTo(String.class)
.findOnly();
3.3.3 支持的参数类型
Jdbi支持以下类型作为SQL语句参数:
- 原生类型:
boolean
,byte
,short
,int
,long
,char
,float
,和double
- java.lang中:
Boolean
,Byte
,Short
,Integer
,Long
,Character
,Float
,Double
,String
,和Enum
- java.math中:
BigDecimal
- java.net: ,
Inet4Address
,Inet6Address
,URL
和URI
- java.sql中:
Blob
,Clob
,Date
,Time
,和Timestamp
- java.time:
Instant
,LocalDate
,LocalDateTime
,LocalTime
,OffsetDateTime
,ZonedDateTime
和ZoneId
- java.util:
Date
,Optional
(围绕任何其他受支持的类型),和UUID
-
java.util.Collection
和Java数组(存储为SQL数组)。根据数组元素的类型,可能需要一些额外的设置。
您还可以配置Jdbi以支持其他参数类型。稍后会详细介绍。
3.3.4 绑定参数
可以通过几种不同的方式绑定SQL语句的参数。
您可以绑定单个参数:
handle.createUpdate("insert into contacts (id, name) values (:id, :name)")
.bind("id", 1)
.bind("name", "Alice")
.execute();
您可以通过Map
一次绑定多个参数:
Map<String, Object> contact = new HashMap<>();
contact.put("id", 2)
contact.put("name", "Bob");
handle.createUpdate("insert into contacts (id, name) values (:id, :name)")
.bindMap(contact)
.execute();
- bindMap
您可以从一个List<T>
参数一次绑定多个值。请注意,这需要使用<boundValue>
表单来编写绑定(与:boundValue
大多数其他绑定相反)。
List<String> keys = new ArrayList<String>()
keys.add("user_name");
keys.add("street");
handle.createQuery("SELECT value FROM items WHERE kind in (<listOfKinds>)")
.bindList("listOfKinds", keys)
.mapTo(String.class)
.list();
// Or, using the 'vararg' definition
handle.createQuery("SELECT value FROM items WHERE kind in (<varargListOfKinds>)")
.bindList("varargListOfKinds", "user_name", "docs", "street", "library")
.mapTo(String.class)
.list();
- bindList
您可以从Java Bean的属性绑定多个参数:
Contact contact = new Contact();
contact.setId(3);
contact.setName("Cindy");
handle.createUpdate("insert into contacts (id, name) values (:id, :name)")
.bindBean(contact)
.execute();
- bindBean
您还可以绑定Object的public字段:
Object contact = new Object() {
public int id = 0;
public String name = "Cindy";
};
handle.createUpdate("insert into contacts (id, name) values (:id, :name)")
.bindFields(contact)
.execute();
- bindFields
或者,您可以绑定Object的public无参方法:
Object contact = new Object() {
public int theId() {
return 0;
}
public String theName() {
return "Cindy";
}
};
handle.createUpdate("insert into contacts (id, name) values (:theId, :theName)")
.bindMethods(contact)
.execute();
- bindMethods
您可以使用前缀限定每个绑定的bean 或对象。这可以帮助消除两个或多个绑定bean具有类似属性名称的情况下的歧义:
Folder folder = new Folder(1, "Important Documents");
Document document =
new Document(100, "memo.txt", "Business business business. Numbers.");
handle.createUpdate("insert into documents (id, folder_id, name, contents) " +
"values (:d.id, :f.id, :d.name, :d.contents)")
.bindBean("f", folder)
.bindMethods("f", folder)
.bindFields("d", document)
.execute();
- 可以为每个绑定指定别名
bindBean()
,bindFields()
和,bindMethods()
可用于绑定嵌套属性,例如:user.address.street
。bindMap()
不绑定嵌套属性 - 映射键应与绑定参数名称完全匹配。
网友评论