MyBatis学习_3_动态SQL

<if>元素

<if>元素是简单的条件判断,可用来实现某些简单的条件选择,书上举的例子是:当输入查询条件是,按条件模糊查询用户名,当什么都没输入时,查询所有用户名。我先说步骤,再说我的看法吧。
1.在UsrInfoMapper.xml映射文件中配置select语句块

<!--动态SQL之<if>元素  -->
 	<select id="findUserInfoUserNameWithIf" parameterType="userInfo" resultType="UserInfo">
 		select * from user_info ui 
 		<if test="userName!=null and userName!=''">
 			where ui.userName LIKE CONCAT(CONCAT('%',#{userName}),'%')
 		</if>
 	</select>

2.创建接口并声明方法

package com.mybatis.mapper;

import java.util.List;

import com.mybatis.pojo.UserInfo;

public interface UserInfoMapper {
	List<UserInfo> findUserInfoUserNameWithIf(UserInfo ui);
}

3.写测试方法

@Test
	public void testFindUserInfoUserNameWithIf() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		UserInfo ui = new UserInfo();
		ui.setUserName("j");//后面注释掉这行做测试
		List<UserInfo> list = uim.findUserInfoUserNameWithIf(ui);
		for (UserInfo uInfo : list) {
			System.out.println(uInfo.toString());
		}
	}

4.先测试正常设置了查询值的时候
在这里插入图片描述
再测试没有设置查询值的情况,也就是注释掉那行代码做测试
在这里插入图片描述
发现sql语句少了where的部分,查询的是全部用户
我是这么想的,在接受到表单数据时,加个if判断他不香吗?还能多写几种条件。

<where> <if>元素

当<if>元素较多时,可能会拼装成 where and 或者 where or 之类的关键字多余的错误SQL语句,这时候就应该用到<where>元素。
1.在UsrInfoMapper.xml映射文件中配置select语句块

<!--动态SQL之<where>元素  -->
 	<select id="findUserInfoByUserNameAndStatus" parameterType="UserInfo" resultType="UserInfo">
 		select * from user_info ui
 		<where>
 			<if test="userName!=null and userName!=''">
 			 ui.userName LIKE CONCAT(CONCAT('%',#{userName}),'%')
 			</if>
 			<if test="status>-1">
 				and ui.status = #{status}
 			</if>
 		</where>
 	</select>

2.创建接口并声明方法
在这里插入图片描述
3.写测试方法,主要测试以下几种情况
都输入了值时
在这里插入图片描述
当设置status值为-1时
在这里插入图片描述
当没有输入姓名查询条件时
在这里插入图片描述

<set> <if>元素

<set> 和 <if>元素可用来组装update语句,只有当<set>元素内的条件成立时,才会在组装SQL语句时加上set关键字.<set>元素内包含了<if>子元素,每个<if>元素包含的SQL后面会有一个逗号,拼接好的SQL语句中会包含多余的逗号,从而造成SQL语法错误,不过<set>元素能将SQL语句中的多余逗号剔除。

<!--动态SQL之<set><if>元素  -->
 	<update id="updateUserInfo" parameterType="UserInfo">
 		update user_info ui
 		<set>
 			<if test="userName!=null and userName!=''">
 				ui.userName = #{userName},
 			</if>
 			<if test="password!=null and password!=''">
 				ui.password = #{password}
 			</if>
 		</set>
 		where ui.id=#{id}
 	</update>

在这里插入图片描述

@Test
	public void testUpdateUserInfo() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		UserInfo ui = new UserInfo();
		ui.setId(3);
		//ui.setUserName("fzj");
		ui.setPassword("123");
		uim.updateUserInfo(ui);
	}

测试以下情形
都输入了值
在这里插入图片描述
没有输用户名
在这里插入图片描述
没有输密码
在这里插入图片描述
id肯定要输的,毕竟不再if里,还是试一下
在这里插入图片描述
我以为他会报错,说少传一个参数,但还是修改了,默认修改第0个,而表是从第一个开始,就相当于是没修改。

<trim>元素

使用<trim>元素,可以通过prefix属性在要拼装的SQL语句片段前加上前缀,通过suffix属性在要拼装的SQL语句片段之后加上后缀,通过prefixOverrides属性把要拼装的SQL语句片段首部的某些内容覆盖,通过suffixOverrides属性把要拼装的SQL语句片段尾部的某些内容覆盖。因此<trim>元素可用来替代<where>元素和<set>元素实现同样的功能。
使用<trim>元素替代<where>元素,从数据表user_info中按用户名模糊查询,同时查询指定状态的用户列表,实现步骤如下所示。
1.编写映射文件

<!--动态SQL之<trim>元素  -->
 	<select id="findUserInfoByUserNameWithIf_Trim" parameterType="UserInfo" resultType="UserInfo">
 		select * from user_info ui
 		<trim prefix="where" prefixOverrides="and|or">
 			<if test="userName!=null and userName!=''">
 				ui.userName LIKE CONCAT(CONCAT('%',#{userName}),'%')
 			</if>
 			<if test="status>-1">
 				and ui.status = #{status}
 			</if>
 		</trim>
 	</select>

prefix属性设置为where,将要拼装的SQL语句的前缀设置为where,即要使用where关键字来连接后面的SQL语句片段;prefixOverrides属性设置为and|or,是将要拼装的SQL语句片段首部多余的“and”或“or”关键字去除
接口
在这里插入图片描述
测试方法

@Test
	public void testFindUserInfoByUserNameWithIf_Trim() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		UserInfo ui = new UserInfo();
		ui.setUserName("j");
		ui.setStatus(1);
		List<UserInfo> list = uim.findUserInfoByUserNameWithIf_Trim(ui);
		for (UserInfo userInfo : list) {
			System.out.println(userInfo.toString());
		}
	}

运行结果和where,if的一样
在这里插入图片描述
接下来演示替代<set>

<!--动态SQL之<trim>元素<set>元素  -->
 	<update id="updateUserInfo_trim" parameterType="UserInfo">
 		update user_info ui
 		<trim prefix="set" suffixOverrides=",">
 			<if test="userName!=null and userName!=''">
 				ui.userName = #{userName},
 			</if>
 			<if test="password!=null and password!=''">
 				ui.password = #{password}
 			</if>
 		</trim>
 		where ui.id=#{id}
 	</update>

后续步骤省略。运行结果和<set>一样

<choose>、<when>和<otherwise>元素

在查询中,如果不想使用所有的条件,而只是想从多个选项中选择一个,可以使用MyBatis提供的<choose>、<when>和<otherwise>元素来实现。<choose>元素会按顺序判断<when>元素中的条件是否成立,如果有一个成立,则不再判断后面<when>元素中的条件是否成立,<choose>元素执行结束;如果所有<when>的条件都不满足,则执行<otherwise>元素中的SQL语句。
如果想从数据表user_info中根据userName或status进行查询,当userName不为空时则只按照userName查询,其他条件忽略;否则当status大于-1时,则只按照status查询;当userName和status都为空时,则查询所有用户记录,使用<choose>、<when>和<otherwise>元素实现这个示例的步骤如下所示。

<!--动态SQL之<choose><when><otherwise>元素  -->
 	<select id="findUserInfo_Choose" parameterType="UserInfo" resultType="UserInfo">
 		select * from user_info ui
 		<where>
 			<choose>
 				<when test="userName!=null and userName!=''">
 					ui.userName LIKE CONCAT(CONCAT('%',#{userName}),'%')
 				</when>
 				<when test="status>-1">
 					and ui.status = #{status}
 				</when>
 				<otherwise>
 				</otherwise>
 			</choose>
 		</where>
 	</select>

后续流程还是上面那一套,运行结果也一样,毕竟是替代嘛。

<foreach>元素

<foreach>元素主要是迭代一个集合,通常是用于in条件。例如SQL中的条件形如:where id in(一大串的id),这时可使用<foreach>元素,而不必去拼接id字符串。
<foreach>元素可以向SQL语句传递数组、List<E>等实例。List<E>实例使用list做为键,数组实例使用array做为键。
如果想从数据表user_info中查询id为1和3的用户记录,使用<foreach>元素的List实例的实现步骤如下所示。

<!--动态SQL之<foreach>元素,使用List<E>实例  -->
 	<select id="findUserInfoByIds" resultType="UserInfo">
 		select * from user_info ui where ui.id in
 		<foreach collection="list" item="ids" open="(" close=")" separator=",">
 			#{ids}
 		</foreach>
 	</select>

有以下几点要说明
item属性表示集合中每个元素迭代时的别名
open表示该语句的开始符号,separator表示每次迭代之间的分隔符号,close表示该语句结束符号
collections属性根据具体情况选择list或array

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面这个是<foreach>的List<E>实例的实现步骤
下面试一下arrea实例的实现

<!--动态SQL之<foreach>元素,使用array实例  -->
 	<select id="findUserInfoByIds2" resultType="UserInfo">
 		select * from user_info ui where ui.id in
 		<foreach collection="array" item="ids" open="(" close=")" separator=",">
 			#{ids}
 		</foreach>
 	</select>

在这里插入图片描述

@Test
	public void testFindUserInfoByIds2() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		//创建集合对象ids,保存用户id
		int[] ids = new int[2];
		ids[0]=1;
		ids[1]=2;
		List<UserInfo> userInfos=uim.findUserInfoByIds2(ids);
		for (UserInfo userInfo : userInfos) {
			System.out.println(userInfo.toString());
		}
	}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值