当前位置: 首页 > news >正文

Mybatis-动态SQL

1. <if>标签

我们在注册用户或者别的业务场景的时候会出现这样一个问题.

注册分为两种字段: 必填字段和非必填字段,那如果在添加用户的时候有不确定的字段传入,程序应该如何实现,这时候就需要使用动态标签来判断了,比如添加的性别gender为非必填字段,具体实现如下:

接口定义:

Integer insertUserByCondition(UserInfo userInfo);

XML实现

<insert id="insertUserByCondition">insert into userinfo (username, password, age,<if test="gender != null">gender,</if>phone)values (#{userName},#{password},#{age},<if test="gender != null">#{gender},</if>#{phone})
</insert>

或者使用注解的方式(不推荐)

把上面的SQL(包括标签),使用<script></script>标签括起来就可以

@Insert("<script>" +"INSERT INTO userinfo (username,`password`,age," +"<if test='gender!=null'>gender,</if>" +"phone)" +"VALUES(#{username},#{age}," +"<if test='gender!=null'>#{gender},</if>" +"#{phone})"+"</script>")
Integer insertUserByCondition(UserInfo userInfo);

注意test中的gender,是传入对象的属性,不是数据库字段 

2. <trim>标签

之前插入的用户功能,只有一个gender字段可能是选填项,如果有多个字段,一般考虑使用标签结合标签,对多个字段都采取动态生成的方式。

标签中有如下属性:

  1. prefix:表示整个语句块,以prefix的值作为前缀
  2. suffix:表示整个语句块,以suffix的值作为后缀
  3. prefixOverrides:表示整个语句块要去除的前缀
  4. suffixOverrides:表示整个语句块要去除的后缀

调整Mapper.xml的插入语句为:

<insert id="insertUserByCondition">insert into mybatis_test.userinfo<trim  prefix="(" suffix=")"  suffixOverrides=","><if test="userName != null">username,</if><if test="password != null">password,</if><if test="age != null">age,</if><if test="gender != null">gender,</if><if test="phone != null">phone,</if></trim>values<trim prefix="(" suffix=")"  suffixOverrides=","><if test="userName != null">#{userName},</if><if test="password != null">#{password},</if><if test="age != null">#{age},</if><if test="gender != null">#{gender},</if><if test="phone != null">#{phone},</if></trim></insert>

或者使用注解(不推荐) 

@Insert("<script>" +"INSERT INTO userinfo " +"<trim prefix='(' suffix=')' suffixOverrides=','>" +"<if test='username!=null'>username,</if>" +"<if test='password!=null'>password,</if>" +"<if test='age!=null'>age,</if>" +"<if test='gender!=null'>gender,</if>" +"<if test='phone!=null'>phone,</if>" +"</trim>" +"VALUES " +"<trim prefix='(' suffix=')' suffixOverrides=','>" +"<if test='username!=null'>#{username},</if>" +"<if test='password!=null'>#{password},</if>" +"<if test='age!=null'>#{age},</if>" +"<if test='gender!=null'>#{gender},</if>" +"<if test='phone!=null'>#{phone}</if>" +"</trim>"+"</script>")
Integer insertUserByCondition(UserInfo userInfo);

在以上sql动态解析时,会将第一个部分做如下处理:

基于prefix配置,开始部分加上(

基于suffix配置,结束部分加上   )

多个组织的语句都以,结尾,在最后拼接好的字符串还会以,结尾,会基于suffixOverrides配置去掉最后一个,

注意<if test = "userName != null" > 中的userName是传入对象的属性

3. <where>标签

看下面这个场景,系统会根据我们的筛选条件,动态组装where条件

这种该如何实现?

接下来我们看代码实现:

需求:传入的用户对象,根据属性作where条件查询,用户中的属性不为null的,都为查询条件。如u为a,则查询条件为where userName =  "a"        

原有SQL

SELECT * FROM userinfo WHERE age = 18 AND gender = 1 AND delete_flag = 0

接口定义 

 List<UserInfo> queryByCondition();

XML实现

<select id="queryByCondition" resultType="com.adviser.springmybaitstest.model.UserInfo">select id, username, password, age, gender, phone, delete_flag, create_time, update_timefrom userinfo<where><if test="age != null">and age = #{age}</if><if test="gender != null">and gender = #{gender}</if><if test="deleteFlag != null">and delete_flag = #{deleteFlag}</if></where>
</select>

 where只会在子元素有内容的情况下才插入where子句,而且会自动去除字句开头的AND或OR

或者使用注解的方式

@Select("<script>select id, username, age, gender, phone, delete_flag, 
create_time, update_time" +" from userinfo" +" <where>" +" <if test='age != null'> and age = #{age} </if>" +" <if test='gender != null'> and gender = #{gender} </if>" +" <if test='deleteFlag != null'> and delete_flag = #
{deleteFlag} </if>" +" </where>" +"</script>")
List<UserInfo> queryByCondition(UserInfo userInfo);

4. <set>标签

需求:根据传入的用户对象属性来更新用户数据,可以使用标签来指定动态内容。

接口定义:根据传入的用户id属性,修改其他不为null的属性

Integer updateUserByCondition(UserInfo userInfo);

XML实现

<update id="updateUserByCondition">update userinfo<set><if test="userName != null">username = #{userName},</if><if test="age != null">age = #{age},</if><if test="deleteFlag != null">delete_flag = #{deleteFlag},</if></set>where id = #{id}
</update>

<set>:动态的时候在SQL语句中插入set关键字,并会删除额外的逗号 

5. <foreach>标签

   对集合进行遍历的时候可以使用该标签。标签有如下属性:

collection:绑定方法参数中的集合,如List,Set,Map或数组对象

item:遍历时的每一个对象

open:语句块开头的字符串

close:语句块结束的字符串

separator:每次遍历之间间隔的字符串

需求:根据多个userid,删除用户数据

接口方法

void deleteByIds(List<Integer> ids);

XML实现

<delete id="deleteByIds">delete from userinfowhere id in <foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach>
</delete>

 或者使用注解

@Delete("<script>" +"delete from userinfo where id in" +"<foreach collection='ids' item='id' separator=',' open='(' 
close=')'>" +"#{id}" +"</foreach>" +"</script>")
Integer deleteUser(Integer id);

6. <include>标签

在XML映射文件中配置的SQL,有时可能会有很多重复的片段,此时就会存在很多冗余的代码

 我们可以对重复的代码片段进行抽取,将其通过<sql>标签封装到一个SQL片段,然后在通过<include>标签进行引用。

<sql>定义可重用的sql片段

<include>:通过属性refid,指定包含的SQL片段

<sql id= "allColumn">id, username, password, age, gender, phone, delete_flag, create_time, update_time
</sql>

通过<include>标签在原来抽取的地方进行引用:

   <select id="queryByCondition" resultType="com.adviser.springmybaitstest.model.UserInfo">select <include refid="allColumn"></include>from userinfo<where><if test="age != null">and age = #{age}</if><if test="gender != null">and gender = #{gender}</if><if test="deleteFlag != null">and delete_flag = #{deleteFlag}</if></where></select><select id="queryAllUser" resultType="com.adviser.springmybaitstest.model.UserInfo">select <include refid="allColumn"></include>from userinfo where id = #{id}</select>

 


http://www.mrgr.cn/news/35993.html

相关文章:

  • Skyeye 云这几年的经历
  • three.js BufferAttribute
  • 计算机网络(九) —— Tcp协议详解
  • python-比较月亮大小/数组下标/人见人爱a+b
  • Webpack 5的新特性:Asset Modules与Dynamic Import
  • Linux快速安装ClickHouse(附官方文档)
  • 【QT 5 调试软件+Linux下调用脚本shell-无法调度+目录拼写+无法找目录+sudo权限(2)+问题解决方式+后续补充】
  • Java中的位图和布隆过滤器(如果想知道Java中有关位图和布隆过滤器的知识点,那么只看这一篇就足够了!)
  • android11 自动授权访问sdcard
  • ChatGPT 向更多用户推出高级语音模式:支持 50 种语言;字节发布两款新视频生成大模型丨 RTE 开发者日报
  • 多城联动、多形式开展网安周公益活动,开源网安传播网络安全知识
  • 解锁视频生成新时代! 探索智谱CogVideoX-2b:轻松生成6秒视频的详细指南
  • 自适应查询优化(Adaptive Query Optimization, AQO)技术简介
  • Circular dependency between the following tasks(gradle循环依赖的问题)
  • 828华为云征文|华为云Flexus云服务器X实例之openEuler系统下部署经典扫雷小游戏
  • easyExcel导出包括相同列id相同合并单元格,明细导出
  • Python项目Flask框架整合Redis
  • python中SortedList类的用法详解
  • VMware提供虚拟硬盘并使得Oracle Linux集群共享块设备并绑定raw设备。
  • Word 制作会议名牌教程