1、Mybatis中的动态sql的实现
通过mybatis提供的各种标签方法实现动态拼接sql。
2、 If 标签(注意要做不等于空字符串校验)
<!-- 传递pojo综合查询用户信息 -->
<select id="findUserList" parameterType="user" resultType="user">
select * from user
where 1=1
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</select>
3、Where标签 (可以自动处理第一个and,也可以用1=1来实现)
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
4、Foreach标签(向sql传递POJO或者List或者数组)
4.1 foreach标签,应用的情况
传入多个id查询用户信息,用下边两个sql实现:
SELECT * FROM USERS WHERE username LIKE '%张%' AND (id=10 OR id =89 OR id=16)
SELECT * FROM USERS WHERE username LIKE '%张%' id IN (10,89,16)
4.2 传入POJO
4.2.1 POJO的实现
public class QueryVo {
// 传递多个用户id
private List<Integer> ids = new ArrayList<Integer>();
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}
4.2.2 mapper.xml
<!-- 用于foreach的动态SQL -->
<select id="userListForeach" resultType="com.baowei.entity.User"
parameterType="com.baowei.entity.QueryVo">
select * from user
<where>
<if test="ids != null and ids.size > 0">
<foreach collection="ids" open=" and id in(" close=")" item="id"
separator=",">
#{id}
</foreach>
</if>
</where>
</select>
4.2.3 测试代码
public class TestDongTaiSQL {
private SqlSession sqlSession;
@Before
public void setUp() throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void testuserListForeach() {
List<Integer> ids = Arrays.asList(1, 10, 3);
// 获取mapper接口的代理对象
DynamicSQLMapper dynamicSQLMapper = sqlSession
.getMapper(DynamicSQLMapper.class);
QueryVo queryVo = new QueryVo();
queryVo.setIds(ids);
// 调用代理对象方法
List<User> users = dynamicSQLMapper.userListForeach(queryVo);
System.out.println(users);
// 关闭session
// session.close();
}
}
4.3 传入List
传递List类型在编写mapper.xml没有区别,唯一不同的是只有一个List参数时它的参数名为list
4.3.1 Mapper.xml
<!--传递单个list -->
<select id="useListForeachOne" parameterType="java.util.List"
resultType="user">
select * from user
<where>
<!-- 传递List,List中是pojo -->
<if test="list!=null">
<foreach collection="list" item="item" open="and id in("
separator="," close=")">
#{item.id}
</foreach>
</if>
</where>
</select>
4.3.2 Mapper.java代码
// 使用单个的list
List<User> useListForeachOne(List<User> users);
4.3.3 测试代码
public void testoneuserListForeach() {
// 获取session
SqlSession session = sqlSessionFactory.openSession();
// 获取mapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
// 构造查询条件List
List<User> userlist = new ArrayList<User>();
User user = new User();
user.setId(1);
userlist.add(user);
user = new User();
user.setId(10);
userlist.add(user);
// 传递userlist列表查询用户列表
// 调用代理对象方法
List<User> list = userMapper.useListForeachOne(userlist);
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 关闭session
session.close();
}
4.4 传入数组(数值中是pojo)
4.4.1 Mapper.xml
<!-- 传递数组综合查询用户信息 -->
<select id="selectUserByArray" parameterType="Object[]" resultType="user">
select * from user
<where>
<!-- 传递数组 -->
<if test="array!=null">
<foreach collection="array" index="index" item="item" open="and id in(" separator="," close=")">
#{item.id}
</foreach>
</if>
</where>
</select>
sql只接收一个数组参数,这时sql解析参数的名称mybatis固定为array,如果数组是通过一个pojo传递到sql则参数的名称为pojo中的属性名。
index:为数组的下标。
item:为数组每个元素的名称,名称随意定义
open:循环开始
close:循环结束
separator:中间分隔输出
4.4.2 Mapper接口
public List<User> selectUserByArray(Object[] userlist) throws Exception;
4.4.3 测试代码
public void testselectUserByArray()throws Exception{
//获取session
SqlSession session = sqlSessionFactory.openSession();
//获限mapper接口实例
UserMapper userMapper = session.getMapper(UserMapper.class);
//构造查询条件List
Object[] userlist = new Object[2];
User user = new User();
user.setId(1);
userlist[0]=user;
user = new User();
user.setId(2);
userlist[1]=user;
//传递user对象查询用户列表
List<User>list = userMapper.selectUserByArray(userlist);
//关闭session
session.close();
}
5、SQL片段
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,如下:
<!-- 传递pojo综合查询用户信息 -->
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</where>
</select>
将where条件,也会是IF标签抽取出来
<sql id="query_user_where">
<if test="id!=null and id!=''">
and id=#{id}
</if>
<if test="username!=null and username!=''">
and username like '%${username}%'
</if>
</sql>
使用include引用
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<include refid="query_user_where"/>
</where>
</select>
引用其它mapper.xml的sql片段,引用时需要加上namespace
<include refid="namespace.sql片段”/>