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);
}
在上面的sql动态解析时,会将第一个做如下处理:
- 基于
prefix
,开始部分加上(
- 基于
suffix
,结束部分加上)
- 多个组织的语句都以
,
结尾,在最后拼接好的字符串是以,
结尾,会基于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);
}
- 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);
}
- 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);
}
文章来源:https://blog.csdn.net/weixin_61427900/article/details/134909123
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!