Mybatis之动态SQL

2023-12-15 15:57:34

动态sql是Mybatis的强大功能之一,能够完成不同条件下不同的sql拼接。

标签

如图是gitee上创建仓库的页面:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
可以分为两种字段,必填字段和非必填字段,在创建仓库时无法确定用户是否会传入”仓库介绍“字段,如果用户不填写,那么前端传过来的就是Null, 在sql中""和null是不相等的,因此需要使用标签来判断。

语法格式:


  • 中的test会产生一个boolean类型的结果,如果为true,那么执行if标签的内容;如果为false,那么不执行if里面的内容。
  • test中的参数,是传入对象的属性,不是数据库字段

咱们这里使用的数据表和前几篇一致,为articleinfo和userinfo表
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
需求:在用户注册环节,photo字段非必填。

photo字段可以标签,当photo字段不为空,则添加;为空就不添加。并且要注意 , 放的位置,不能跟着password后面,因为如果photo字段为空,就会造成sql语法错误

int addUser(Userinfo userinfo);
<insert id="addUser">
	insert into userinfo (username, password
	<if test="photo!=null">
		, photo
	</if>
	)
	values (#{username}, #{password}
	<if test="photo!=null">
		, #{photo}
	</if>
	)
</insert>
@Test
void addUser() {
	Userinfo userinfo = new Userinfo();
	userinfo.setUsername("张三");
	userinfo.setPassword("2345");
	userinfo.setPhoto(null); //在sql中”“不等于Null
	userMapper.addUser(userinfo);
	System.out.println(userinfo);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

标签

在用户注册的时候,只有一个photo字段是非必填项,如果所有字段都是非必填项,可以考虑使用标签结合标签,对多个字段都采取动态生成的方式。
标签中有如下属性:

  • prefix: 表示整个语句块,以prefix的值作为前缀
  • suffix: 表示整个语句块,以suffix为值作为后缀
  • prefixOverrides: 表示整个语句块要去除掉的前缀
  • suffixOverrides: 表示整个语句块要去除掉的后缀
int addUser2(Userinfo userinfo);
<insert id="addUser2" useGeneratedKeys="true" keyColumn="id">
	insert into userinfo
	<trim prefix="(" suffix=")" suffixOverrides=",">
		<if test="username != null">
			username,
		</if>
		<if test="password != null">
			password,
		</if>
		<if test="photo != null">
			photo,
		</if>
	</trim>
	values
	<trim prefix="(" suffix=")" suffixOverrides=",">
		<if test="username != null">
			#{username},
		</if>
		<if test="password != null">
			#{password},
		</if>
		<if test="photo != null">
			#{photo},
		</if>
	</trim>
</insert>
@Test
void addUser2() {
	Userinfo userinfo = new Userinfo();
	userinfo.setUsername("王五");
	userinfo.setPassword("45667");
	userinfo.setPhoto(null);
	userMapper.addUser2(userinfo);
	System.out.println(userinfo);
}

image.png
在上面的sql动态解析时,会将第一个做如下处理:

  1. 基于prefix,开始部分加上(
  2. 基于suffix,结束部分加上)
  3. 多个组织的语句都以,结尾,在最后拼接好的字符串是以,结尾,会基于suffixOverrides去掉最后一个,

标签

顾名思义和mysql中的where作用一样,都是用来条件查询。

需求:跟据前端提供的用户名和密码(都是非必传的参数)查询用户信息

List<Userinfo> selectByParam(@Param("username") String username,
                           @Param("password") String password);
<select id="selectByParam" resultType="com.example.demo.entity.Userinfo">
	select * from userinfo
	<where>
		<if test="username != null">
			username = #{username}
		</if>
		<if test="password != null">
			and password = #{password}
		</if>
	</where>
</select>
@Test
void selectByParam() {
	List<Userinfo> list = userMapper.selectByParam(null, "admin");
	System.out.println(list);
}

image.png

  • where标签通常需要配合if标签一起使用
  • where标签会删除最前面的and关键字(所以上面的例子中就把password前面的and关键字去除)
  • where标签如果里面没有内容,那么他不会生成where sql语句

标签

顾名思义和mysql的set作用一样,都是用来更新数据。

需求:前端传递Userinfo给后端(部分属性是非必填),请根据id修改用户信息

int update(Userinfo userinfo);
<update id="update">
	update userinfo
	<set>
		<if test="username != null">
			username = #{username},
		</if>
		<if test="password != null">
			password = #{password},
		</if>
		<if test="photo != null">
			photo = #{photo}
		</if>
	</set>
	where id = #{id}
</update>
@Test
void update() {
	Userinfo userinfo = new Userinfo();
	userinfo.setUsername("张三");
	userinfo.setPassword(null);
	userinfo.setPhoto("bbb.png");
	userinfo.setId(1);
	userMapper.update(userinfo);
	System.out.println(userinfo);
}

image.png

  • set标签通常配合 if 标签一起使用
  • set标签会自动去除最后一个逗号

标签

顾名思义用来循环遍历的,标签有如下属性:

  • collection: 绑定方法参数中的集合,如List,Set,Map
  • item: 遍历时的对象
  • open:语句块开头的字符串
  • close: 语句块结束的字符串
  • separator: 每次遍历之间间隔的字符串

需求:根据多个文章id删除文章数据

int dels(List<Integer> list);
<delete id="dels">
	delete from userinfo
	where id in
	<foreach collection="list" item="item" open="(" close=")" separator=",">
		#{item}
	</foreach>
</delete>
@Test
void dels() {
	List<Integer> list = new ArrayList<>();
	list.add(1);
	list.add(3);
	int dels = userMapper.dels(list);
	Assertions.assertEquals(2, dels);
}

image.png

文章来源:https://blog.csdn.net/weixin_61427900/article/details/134909123
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。