MyBatis动态sql:更方便的拼接sql语句

if标签

  if标签是最常用的判断语句,相当于java中的if语句。在MyBatis中使用if标签,我们先看一下不使用if标签的时候会有什么情况。

<!-- 多条件查询 用过用户对象中的条件查询用户列表 -->
<select id="selectUserListByUser" parameterType="User" resultType="User">
	<!-- 查询用户性别 模糊查询用户名 查询用户cid 国籍id -->
	select * 
	from user 
	where 
	u_sex = #{u_sex} 
	and u_username like "%"#{u_username}"%" 
	and u_cid = #{u_cid}
</select>

  在上面的案例中,多条件查询用户性别u_sex,模糊查询用户名u_username,查询用户国籍c_id,返回一个集合。我们在使用条sql语句的时候,我们必须把所有的参数传过来,如果出现我只有查询用户性别u_sex,模糊查询用户名u_username的情况,我们又必须再写一条sql语句。而使用了if标签之后可以解决这个问题。

<!-- 多条件查询 用过用户对象中的条件查询用户列表 -->
<select id="selectUserListByUser" parameterType="User" resultType="User">
	<!-- 查询用户性别 模糊查询用户名 查询用户cid 国籍id -->
	select * 
	from user 
	where 
	<if test="u_sex!=null">
		u_sex = #{u_sex} 
	</if>';l.,
	<if test="u_username!=null">
		and u_username like "%"#{u_username}"%" 
	</if>
	<if test="u_cid!=null">
		and u_cid = #{u_cid}
	</if>
</select>

  在上面的案例中,当参数u_username传递进映射器时,如果参数不为空则再sql语句上拼接上对用户名的模糊查询,如果为空,则不拼接。这样我们就可以不用写多条sql语句了。但是,如果我们u_sex为空u_username不为空,在sql语句拼接时就会出现select * from user where and u_username like "%"#{u_username}"%"的错误语法格式。接下来的where标签可以解决这个问题。

where标签

  where标签,当标签内的条件成立时,才会加入where这个SQL关键字到组装的SQL里面,否则就不加入,where还可以去掉一些特殊的SQL语法,比如说and、or,它去掉的时前缀的and和or。

<select id="selectUserListByUser" parameterType="User" resultType="User">
	<!-- 查询用户性别 模糊查询用户名 查询用户cid 国籍id -->
	select * 
	from user 
	<where>
		<if test="u_sex!=null">
			u_sex = #{u_sex} 
		</if>
		<if test="u_username!=null">
			and u_username like "%"#{u_username}"%" 
		</if>
		<if test="u_cid!=null">
			and u_cid = #{u_cid}
		</if>
	</where>
</select>

  在上面的案例中,如果and全写在sql拼接语句的后面,当c_cid==null的话,使用where语句就去不掉结尾的and。接下来的trim标签可以解决这个问题。

trim标签

  trim标签是要去掉一些特殊的字符串,它又四个属性,prefix、suffix、prefixOverrides、suffixOverrides。下面通过一个例子说一下这四个属性分别代表的意义。

<select id="selectUserListByUser" parameterType="User" resultType="User">
	<!-- 查询用户性别 模糊查询用户名 查询用户cid 国籍id -->
	select * 
	from user 
	<trim prefix="where" suffixOverrides="and">
		<if test="u_sex!=null">
			u_sex = #{u_sex} and 
		</if>
		<if test="u_username!=null">
			u_username like "%"#{u_username}"%" and 
		</if>
		<if test="u_cid!=null">
			u_cid = #{u_cid}
		</if>
	</trim>
</select>

  prefix=“where”,的意思是在trim头标签加上where之后再拼接上trim内的SQL语句,如果将其换成suffix="where"的话,就会在trim内的的SQL语句后面接上where,显然在上面的案例中是不对的。
  suffixOverrides=“and”,的意思是去掉拼接语句尾部一些不合法的一些特殊字符,比如说and、or,如果将其换成prefixOverrides="and"的话,就是去掉拼接语句开头一些不合法的的特殊字符。

set标签

set标签在跟新表属性的时候,如果遇上不合法的逗号,会将其去掉。例如:

<update id="updateSetUser" parameterType="User">
	<!-- 修改用户名和用户密码以及性别以id为限制 -->
	update user
	set
	<if test="u_username!=null and u_username!=''">
		u_username = #{u_username},
	</if>
	<if test="u_password!=null and u_password!=''">
		u_password = #{u_password},
	</if>
	<if test="u_sex!=null and u_sex!=''">
		u_sex = #{u_sex}
	</if>
	where u_id = #{u_id}
</update>

  在上面这个案例中,如果if语句最后一个不成立而它上一个if语句成立的时候,在拼接SQL语句的时候,就会出现SQL语法的错误,而使用set标签可以很好的解决这个错误。下面是使用set标签的案例。

<update id="updateSetUser" parameterType="User">
	<!-- 修改用户名和用户密码以及性别以id为限制 -->
	update user
	<set>
		<if test="u_username!=null and u_username!=''">
			u_username = #{u_username},
		</if>
		<if test="u_password!=null and u_password!=''">
			u_password = #{u_password},
		</if>
		<if test="u_sex!=null and u_sex!=''">
			u_sex = #{u_sex}
		</if>
	</set>
	where u_id = #{u_id}
</update>

  如果最后一个条件u_sex!=null and u_sex!=''不成立,第二个条件u_password!=null and u_password!=''成立,则会把第二句拼接的SQL语句末尾的逗号去掉。

foreach标签

  foreach标签是一个循环语句,它的作用是遍历集合,它能够很好地支持数组和List、Set接口的集合,对此提供遍历的功能。
  比如说,我要查找数据库中id为1、3、5的用户,SQL语句应该这样写select * from user where u_id in(1,3,5)只能固定查3个id的用户,如果要查4个,必须再写一条sql语句,而foreach可以很好的解决这个问题。

<select id="selectUserListByIds" resultType="User">
	select *
	from user
	where u_id 
	in
	<foreach collection="array" item="id" open="(" close=")" separator=",">
		#{id}
	</foreach>
</select>
  • collection表示传入的是数组还是集合是数组用array,是集合用list、set等,但如果是包装类的话,则需要使用包装类里面数组或集合的字段名。
  • item表示用什么表示数据或者集合里面的数,即循环中当前的元素。
  • open、close表示用什么元素把集合两端包起来。
  • separate表示用什么分隔。
  • index表示当前元素在集合中的位置。

choose、when、otherwise标签

  choose、when、otherwise标签类似于java里面的wsitch…case…default…功能语句。下面是一个简单的案例。

<select id="selectUserByUser" parameterType="com.xiezhenyu.bean.User" resultType="com.xiezhenyu.bean.User">
	select *
	from user
	<where>
		<choose>
			<when test="u_id!=null">
				and u_id=#{u_id}
			</when>
			<when test="u_username!=null">
				and u_username=#{u_username}
			</when>
			<otherwise>
				and 1=2
			</otherwise>
		</choose>
	</where>
</select>

  当传过来的user的id不为空时,按照id为条件去查找,当传过来的id为空而username不为空时按照username去查找,当两个都为空时,查找不到。

sql标签

  在写sql语句的时候,有很多重复的语句片段,比如说,select * from user这句话就被重复了很多次,而使用sql标签可以将这些重复的字段提出来,什么时候用就引入一下就可以了。

<sql id="selectUser">
	select *
	from user
</sql>
<select id="selectUserListByIds" resultType="User">
	<include refid="selectUser"/>
	where u_id 
	in
	<foreach collection="array" item="id" open="(" close=")" separator="," index="2">
		#{id}
	</foreach>
</select>

bind标签

  bind标签的作用是用过ONGL表达式去定义一个上下文变量,这样更方便使用,例如在进行模糊查询时,MySQL需要用到%和参数连接。
定义接口方法

public List<User> selectUserLikeUsername(@Param("str")String str);

定义映射文件和一个新的变量,然后执行模糊查询

<select id="selectUserLikeUsername" parameterType="string" resultType="com.xiezhenyu.bean.User">
	<bind name="pattern" value="'%'+str+'%'"/>
	select *
	from user
	where
	u_username like #{pattern}
</select>

测试方法

@Test
public void Test11() throws IOException {
	String resource = "sqlMapConfig.xml";
	//读取配置文件
	InputStream in = Resources.getResourceAsStream(resource);
	//需要sqlSessionFactoryBulider
	SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
	//创建sqlSessionFactory
	SqlSessionFactory ssf = ssfb.build(in);
	//生产一个sqlSession
	SqlSession session = ssf.openSession();
	UserMapper mapper = session.getMapper(UserMapper.class);
	List<User> list = mapper.selectUserLikeUsername("王");
	for(User u : list) {
		System.out.println(u);
	}
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢以轩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值