mybatis动态sql

动态sql即可以根据条件动态地执行不同的sql语句,mybatis是通过在mapper.xml中添加逻辑判断来实现动态sql的,逻辑判断的标签主要有<if><choose><when><otherwise>等。

if标签

动态sql语句通常的表现就是判断sql语句中where子句部分,例如:

<select id="selByAccinAccout" resultType="log">
		select * from log where 1=1
		<!-- OGNL表达式,直接写key或对象的属性.不需要添加任何特字符号  -->
		<if test="accin!=null and accin!=''">
			and accin=#{accin}
		</if>
		<if test="accout!=null and accout!=''">
			and accout=#{accout}
		</if>
</select> 

上述sql语句的where子句中的“1=1”是恒定成立的,在这的作用是为了在两个if判断都不成立的时候,sql语句不报错。

当两个if判断都成立的时候sql语句的执行如下,where中的两个条件都会生效:

在这里插入图片描述

当两个if都不成立的时候该sql语句的where子句将只有条件“1=1”,即会查询出所有的记录:

在这里插入图片描述

where标签

上述示例sql语句中的where关键字也可以用where标签替代,如果where标签中的内容中第一个是and,sql语句映射将会去掉第一个and,并且只有在where标签中有内容的时候才会生成where关键字,当where标签中没有内容的时候不会生成关键字,这样就不在需要书写“where 1=1”来避免sql语句错误了,例如:

<select id="selByAccinAccout" resultType="log">
		select * from log 
		<where>
			<if test="accin!=null and accin!=''">
				and accin=#{accin}
			</if>
			<if test="accout!=null and accout!=''">
				and accout=#{accout}
			</if>
		</where>
</select> 

当只传入了accin的时候,执行的sql语句如下:

在这里插入图片描述

当只传入了accout的时候,执行的sql语句如下:

在这里插入图片描述

当参数accin和accout均传入的时候,执行的sql语句如下:

在这里插入图片描述

当参数accin和accout均没有被传入的时候,既不会生成where子句,执行的sql语句如下:

在这里插入图片描述

choose、when、otherwise标签

上面的例子中,是当所有的条件都执行的时候,所有的条件都会执行,但有时候我们并不想执行所有的条件,所以我们可以组合使用这三个标签,只要有一个条件成立则会其他的条件都不会执行,例如:

<select id="selByAccinAccout" resultType="log">
		select * from log 
		<where>
			<choose>
				<when test="accin!=null and accin!=''">
					and accin=#{accin}
				</when>
				<when test="accout!=null and accout!=''">
					and accout=#{accout}
				</when>
				<otherwise>
					and accin='abcd'
				</otherwise>
			</choose>
		</where>
</select> 

当两个when标签的条件都成立的时候,执行的sql语句如下:

在这里插入图片描述

因为accin的判断在前,所以当accin判断条件成立的时候,accout的判断尽管条件成立也没有执行。

当只有accout判断成立,即只传入accout参数的时候,执行的sql语句如下:

在这里插入图片描述

当两个when标签不成立的时候,将会执行otherwise标签的内容构成where子句:

在这里插入图片描述

set标签

update标签中使用set标签可以自动去掉最后一列条件的逗号,如果set标签中有内容sql语句映射则会生成set关键字,没有则不会生成set关键字。

<update id="upd" parameterType="log" >
		update log 
		<set>
			id=#{id},
			<if test="accIn!=null and accIn!=''">
				accin=#{accIn},
			</if>
			<if test="accOut!=null and accOut!=''">
				accout=#{accOut},
			</if>
		</set>
		where id=#{id}
</update> 

子句“where id=#{id}”是为了避免set标签中没有内容不生成set标签。

trim标签

trim标签主要是用于对sql语句进行裁剪,在sql语句(字符串)中增加、删减或替换字符。trim标签中,prefix属性表示在前面添加内容,prefixOverrides属性表示去掉前面内容,suffix属性表示在后面添加内容,suffixOverrieds属性表示去掉后面内容。

<select id="selByLog" parameterType="log" resultType="log">
	select * from log
	<trim >abc</trim>
</select> 

执行的sql语句为:

在这里插入图片描述

添加prefix元素:

<select id="selByLog" parameterType="log" resultType="log">
	select * from log
	<trim prefix="abc" >abc</trim>
</select> 

将会在“abc”的前面再增加一个“abc”,生成的sql语句将报错:
在这里插入图片描述

单独使用prefixOverrides元素:

<select id="selByLog" parameterType="log" resultType="log">
	select * from log
	<trim prefixOverrides="abc">abc</trim>
</select> 

生成的sql语句将会去掉“abc”,sql语句正确执行:

在这里插入图片描述

同时使用prefix元素和prefixOverrides元素:

<select id="selByLog" parameterType="log" resultType="log">
	select * from log
	<trim prefix="abc" prefixOverrides="abc">abc</trim>
</select>

去掉了一个“abc”又增加了一个“abc”,所以生成的sql语句中还存在一个“abc”:

在这里插入图片描述

bind标签

bind标签中,value对应传入实体类的某个字段,体类中需要该字段有相应的getter方法,name属性既给对应字段取的变量名。在value属性中可以使用字符串拼接等特殊处理。

<select id="selByLog" parameterType="log" resultType="log">
		<bind name="accin" value="'%'+accin+'%'"/>
		select * from log where accin like
		#{accin}
</select> 

在这里插入图片描述

foreach标签

用于循环传入参数的内容,还具备在内容的前后添加内容,还具备添加分隔符功能。常用在IN条件语句和批量插入中。

<insert id="ins" parameterType="list">
	insert into log values
	<trim suffixOverrides=",">
		<foreach collection="list" item="log">
			(default,#{log},2,2),
		</foreach>
	</trim>
</insert>

<select id="selIn" parameterType="list" resultType="log">
	select * from log where id in
	<foreach collection="list" item="abc" open="(" close=")" separator=",">
		#{abc}
	</foreach>
</select>

调用代码:

InputStream is = Resources.getResourceAsStream("mybatis.xml");
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//批量插入需指定底层JDBC 的PreparedStatement.addBatch();
		SqlSession session = factory.openSession(ExecutorType.BATCH);

LogMapper mapper = session.getMapper(LogMapper.class);
List<Integer> list = new ArrayList<>();
		for (int i = 0; i < 10000; i++) {
			list.add(i);
		}
		
		mapper.ins(list);
		mapper.selIn(list);
		session.commit();
		session.close();
		System.out.println("程序执行结束");

sql标签和include标签

如果某些sql语句片段希望复用,可以使用sql标签定义,然后再通过include标签引用。

<sql id="mysql">
	id,accin,accout,money
</sql>

<select id="">
	 select <include refid="mysql"></include>
	 from log
</select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值