MyBatis之动态SQL

本文深入探讨MyBatis框架中的动态SQL应用,包括条件查询、批量删除与更新操作的实现方式,通过具体代码示例展示如何根据参数动态构建SQL语句。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用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));

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值