1.多Where条件查询:

在sql中经常会出现类似 SELECT * FROM table WHERE clauseA AND clauseB形式的情况,这种功能在MyBatis中如何实现?可以有两种实现方式:自定义对象传参、使用集合来传参。这2种方式在实际项目中都比较常用,需要熟练。


1.1 自定义参数对象:

我们还是以上一篇文章中的表test_order_mm,作为实例来实现该功能。假设,我们要执行的sql语句为:select * from test_order_mm where order_address = 'beijing' and price > 50,我们需要替换2个实际值为参数。因为sql语句中有大于号“>”,在配置Mapper文件时,需要做转义。XML中做转义的方法是使用CDATA标签,如下所示:

CDATA 部分由 "<![CDATA[" 开始,由 "]]>" 结束,即:
<![CDATA[ xxxx...... ]]>
<![CDATA[  select * from test_order_mm where order_address = 'beijing' and price > 50 ]]>

同时,我们需要将2个值换为参数形式,转换如下:

<![CDATA[  select * from test_order_mm where order_address = #{} and price > #{} ]]>

上边符号#{}还是采用了预编译的方式。

创建查询对象类,封装查询条件,必须有相应的get和set方法。在sql语句的参数内(也就是#{}内)填入查询对象的属性名。#{}通过查询对象属性的get方法来取值。

(1)创建查询类/对象QueryCondition1TestOrderMm.java

package com.vip.model;

public class QueryCondition1TestOrderMm {	
	//每一个属性对应着sql语句的一个where查询条件。
	private String address;
	private double price;
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
}

上边是定义的查询类,该类中的每一个属性,就是对应的sql语句的每一个Where条件的一个参数。

(2)配置TestOrderMm.xml:

<select id="selectByParameters" parameterType="com.vip.model.QueryCondition1TestOrderMm" resultMap="orderResultMap">
		<![CDATA[ select * from test_order_mm where order_address = #{address} and price > #{price} ]]>
</select>

该select配置参数类型就是定义的查询类,返回值仍然是OrderResultMap。#{}内的参数必须和查询类中定义的属性完全一致。

(3)测试类AppTest.java:

//测试多Where条件查询,通过传递查询对象的方式实现。
QueryCondition1TestOrderMm qc1 = new QueryCondition1TestOrderMm();
qc1.setAddress("beijing");
qc1.setPrice(50);
List<TestOrderMm> tombypar = sqlsession.selectList("com.vip.mapping.TestOrderMm.selectByParameters",qc1);
for(TestOrderMm tom_si: tombypar)
{
	System.out.println(tom_si);
}

运行结果:

DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@7ce3cb8e]
DEBUG - ==>  Preparing: select * from test_order_mm where order_address = ? and price > ? 
DEBUG - ==> Parameters: beijing(String), 50.0(Double)
TestOrderMm [id=5, orderNo=0005, orderAddress=beijing, price=93.21]
TestOrderMm [id=6, orderNo=0006, orderAddress=beijing, price=56.0]


1.2 使用集合(java.util.Map)来实现:

也可以使用Map来替代参数对象。#{}里面填写的内容是map的key值,当然传给sql语句的参数就是这个key对应的value。

(1) Mapper配置:

<select id="selectByParameters1" parameterType="java.util.Map" resultMap="orderResultMap">
		<![CDATA[ select * from test_order_mm where order_address = #{address} and price > #{price} ]]>
</select>

参数类型,修改为java.util.Map,其余不变。

(2) 测试类AppTest.java:

//测试多Where条件查询,通过传递Map对象的方式实现。
Map<String,Object> map = new HashMap<String,Object>();
map.put("address", "shanghai");
map.put("price", 56);
List<TestOrderMm> tombypar1 = sqlsession.selectList("com.vip.mapping.TestOrderMm.selectByParameters",map);
for(TestOrderMm tom_si: tombypar1)
{
	System.out.println(tom_si);
}

传递给selectList方法的第二个参数是,map对象。

(3)运行结果:

DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@7ce3cb8e]
DEBUG - ==>  Preparing: select * from test_order_mm where order_address = ? and price > ? 
DEBUG - ==> Parameters: shanghai(String), 56(Integer)
TestOrderMm [id=3, orderNo=0003, orderAddress=shanghai, price=134.13]


2.模糊查询实现方式:

在应用中,会经常用到模糊查询,使用like查询。下面使用mybatis实现:

首先,需要解释下#{}和${}之间的区别,前者是预编译的,可以有效的放置sql注入***,更安全;后者正好相反。所以尽量使用前者。

其实,使用这2种格式都可以完成,只不过如果使用#{},必须将key “address”的value设置为“%ang%”,

如下代码:

map.put("address", "%ang%");

上边做法比较容易出错,所以还是建议使用${}直接传String,并和%符号拼接成like语句后边的参数。


mapper:

<select id="selectByLike" parameterType="java.util.Map" resultMap="orderResultMap">
	select * from test_order_mm where order_address like '%${address}%'
</select>

测试类:

//模糊查询使用${}:
Map<String,Object> map1 = new HashMap<String,Object>();
map1.put("address", "ang");
List<TestOrderMm> tombypar2 = sqlsession.selectList("com.vip.mapping.TestOrderMm.selectByLike",map1);
for(TestOrderMm tom_si: tombypar2)
{
	System.out.println(tom_si);

结果:

DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@7ce3cb8e]
DEBUG - ==>  Preparing: select * from test_order_mm where order_address like '%ang%' 
DEBUG - ==> Parameters: 
TestOrderMm [id=3, orderNo=0003, orderAddress=shanghai, price=134.13]
TestOrderMm [id=4, orderNo=0004, orderAddress=hangzhou, price=23.87]
TestOrderMm [id=7, orderNo=0007, orderAddress=shanghai, price=49.0]
TestOrderMm [id=8, orderNo=0008, orderAddress=guangzhou, price=902.0]

注意,在上边DEBUG的日志中,Preparing的sql中,不再是?,而直接将值替换了,不进行预编译了。