IF标签
不使用if标签,所产生的问题
通过mybatis提供的各种标签方法实现动态拼接sql。
需求:根据性别和名字查询用户
查询sql:
SELECT id, username, birthday, sex, address FROM user
WHERE sex = 1 AND username LIKE ‘%刘%’
<!-- 根据性别和名字查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
select id, username, birthday, sex, address FROM `user`
WHERE sex = #{sex} AND username LIKE '%${username}%'
</select>
编写Mapper接口,如下图
测试:
@Test
public void testQueryUserByWhere() {
// 获取sqlSession,和spring整合后由spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
//获取mapper对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setSex("1");
user.setUsername("刘");
List<User> userList = userMapper.queryUserByWhere(user);
for (User user2 : userList) {
System.out.println(user2);
}
sqlSession.close();
}
结果图:
假设注释掉//user.setSex(“1”);
sql就会变成这样:
SELECT id, username, birthday, sex, address FROM user
WHERE sex = null AND username LIKE ‘%刘%’
这样肯定查询不到数据
不使用if标签,那么将会需要编写多条sql去解决这个问题
使用if标签
改造UserMapper.xml,如下:
<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
WHERE 1=1
<if test="sex != null and sex != ''">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE
'%${username}%'
</if>
</select>
where 1=1 方便后面拼接and
结果:
Where标签
上面的sql还有where 1=1 这样的语句,很麻烦
可以使用where标签进行改造
改造UserMapper.xml,如下
where 1=1 等同 <where>...</where>
结果:
Sql片段(提取sql中的列,可重复使用)
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。
把上面例子中的id, username, birthday, sex, address提取出来,作为sql片段,如下:
<!-- 根据性别和名字查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
select <include refid="userField"></include> FROM `user`
<where>
<if test="sex!=null and sex!=''">
AND sex = #{sex}
</if>
<if test="username!=null and username!=''">
AND username LIKE '%${username}%'
</if>
</where>
</select>
<sql id="userField">
id, username, birthday, sex, address
</sql>
结果:
foreach标签(解决参数为list或数组问题)
向sql传递数组或List,mybatis使用foreach解析,如下:
根据多个id查询用户信息
查询sql:
SELECT * FROM user WHERE id IN (1,10,24)
此时不能传三个值(1,10,24),这样太麻烦,可以传递一个数组,解决该问题
创建实体类
import java.util.List;
public class QueryVo {
public User user;
public List<Integer> ids;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}
编写UserMapper.java:
编写UserMapper.xml:
<select id="queryUserByIds" parameterType="queryVo" resultType="user">
select * from user
<!-- foreach标签,进行遍历 -->
<!-- collection:遍历的集合,这里是QueryVo的ids属性 -->
<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
<!-- open:在前面添加的sql片段 -->
<!-- close:在结尾处添加的sql片段 -->
<!-- separator:指定遍历的元素之间使用的分隔符 -->
<where>
<foreach collection="ids" item="i" open="id in(" close=")" separator=",">
#{i}
</foreach>
</where>
</select>
编写测试方法:
@Test
public void testQueryUserByIds() {
// 获取sqlSession,和spring整合后由spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
//获取mapper对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
QueryVo queryVo = new QueryVo();
List<Integer> ids = new ArrayList<Integer>();
ids.add(10);
ids.add(16);
ids.add(25);
ids.add(32);
queryVo.setIds(ids);
List<User> userList = userMapper.queryUserByIds(queryVo );
for (User user2 : userList) {
System.out.println(user2);
}
sqlSession.close();
}
结果: