使用myBatis的动态sql语句可以更加灵活的对数据库进行操作。
例如上一篇博客里的 mapper 中有这样的代码
<select id="getUserName" resultType="java.lang.String">
select user_name from user_info where id=#{id}
</select>
根据 id 一个属性从用户表中获得用户名
但是假如我们需要传进去两个值进行查找,并且允许其中某个或者全部的值为空。例如下面这个方法,
List<UserInfo> select(@Param("userName")String userName,@Param("age")Integer age);
根据用户名或者年龄进行查找,或根据两个值进行精确查找。
此时我们就要用到动态 sql
在 select 标签里看一下他的子标签
这里我们要实现上面的功能选择插入where和if标签
<select id="select" resultType="com.jd.vo.UserInfo">
select id,user_name userName,password,real_name realName,age
from user_info
<where>
<if test="userName!=null">
and user_name like #{userName}
</if>
<if test="age!=null">
and age = #{age}
</if>
</where>
</select>
根据上述代码我们可以很明显的看到 <where></where> 标签代替了sql 语句中 where 的作用,而 if 标签里的 test 代表着假如传进的值不是空值的话就将里面的 sql 语句拼接。
在这里我们写一个Test测试一下
public static void main(String[] args) {
try {
InputStream inputStream = Resources.getResourceAsStream("mybatis_config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
IUserInfoDao userInfoDao = sqlSession.getMapper(IUserInfoDao.class);
for (UserInfo ui : userInfoDao.select(null, null)) {
System.out.println(ui.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
给出测试用的数据库
此时运行
控制台输出了表中的所有数据。这是因为我们在向 select 方法中传进的两个参数都是 null 而在mapper文件里的 if 标签进行判断发现不符合表达式所以不执行里面的 sql 语句,这样此次查询就没有限制条件,从而将所有数据查询了出来。
此时我们将传入的参数修改一下
运行
可以在控制台日志的第一行看到 sql 有了限制条件 age= ? 这是因为我们传进去的这个参数不为null,所以执行 if 语句中的 sql 语句
我们再改一下参数 ,进行精确查找。
运行
可以在控制台日志的第一行看到 sql 有了限制条件where user_name like ? and age= ?
下面我们看删除。简单的删除就直接 where id = #{id}。这里说一下批量删除,因为批量删除的 sql 语句为 where id in (值1,值2,值3,值4)。我们来看下面的代码
boolean delete (List<Integer> id);
<delete id="delete" >
delete from user_info
where id in
<foreach item = "id" collection="list" open= "(" close=")" separator=",">
#{id}
</foreach>
</delete>
delect 标签下面有一个 <foreach></foreach>标签,他要求传入一个 list 对象,并对这个 list 进行操作,即以 open 的值为开始
以 colse 的值为结束 ,以 ,分割 list 中的每个元素,以 id 为元素迭代时的别名。依次输出 list 的值。
我们再 test 中再写入如下代码。
List<Integer> list = new ArrayList<Integer>();
list.add(2);
list.add(3);
System.out.println(userInfoDao.delete(list));
运行
观察控制台输出,可看出限制语句 where id in ( ? , ? ) 正是我们所期待的 sql 语句。 而且成功删除了两条数据。
接下来我们看更新。更新这里有这样一个问题。再 set 语句 之后我们要进行多个值时,我们要用逗号进行隔开,而当我们在更新的时候某个值不用更新而传入的 null 这时怎么办。
这里我们看下面这个代码
boolean update(UserInfo info);
<update id="update">
update user_info
<set>
<if test="realName!=null">
real_name = #{realName},
</if>
<if test="age!=null">
age = #{age}
</if>
</set>
where id = #{id}
</update>
同样 update 里面有 <set></set>和<if></if>标签。注意这里第一个 要更新的 realName 后面有个逗号。而此时如果我们传进入的第二个参数为null <set></set> 标签会自动删除这个逗号,这样就成功的避免了因为逗号而带来的问题。
这里给出测试代码
UserInfo userInfo = new UserInfo();
userInfo.setId(1);
userInfo.setRealName("xiaoqiqi");
userInfo.setAge(33);
System.out.println(userInfoDao.update(userInfo));