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

MyBatis 操作数据库(进阶)

动态SQL

<if>标签

在注册⽤⼾的时候,可能会有这样⼀个问题,如下图所⽰:
注册分为两种字段:必填字段和⾮必填字段,那如果在添加⽤⼾的时候有不确定的字段传⼊,程序应
该如何实现呢?
这个时候就需要使⽤动态标签 来判断了,⽐如添加的时候性别 gender 为⾮必填字段,具体实现如
下:
接⼝定义:
Integer insertUserByCondition(UserInfo userInfo);
Mapper.xml实现:
<insert id="insertUserByCondition">
 INSERT INTO userinfo (
 username,
 `password`,
 age,
 <if test="gender != null">
 gender,
 </if>
 phone)
 VALUES (
 #{username},
 #{age},
 <if test="gender != null">
 #{gender},
 </if>
 #{phone})
</insert>

或者使⽤注解⽅式(不推荐)

@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);

<trim>标签

之前的插⼊⽤⼾功能,只是有⼀个 gender 字段可能是选填项,如果有多个字段,⼀般考虑使⽤标签结合标签,对多个字段都采取动态⽣成的⽅式。

标签中有如下属性:

prefix:表⽰整个语句块,以prefix的值作为前缀

suffix:表⽰整个语句块,以suffix的值作为后缀

prefixOverrides:表⽰整个语句块要去除掉的前缀

suffixOverrides:表⽰整个语句块要去除掉的后缀

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

<insert id="insertUserByCondition">
 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>
</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 是传⼊对象的属性

<where>标签

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

接⼝定义:
List<UserInfo> queryByCondition();
Mapper.xml实现
<select id="queryByCondition" resultType="com.example.demo.model.UserInfo">
 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>
</select>
<where> 只会在⼦元素有内容的情况下才插⼊where⼦句,⽽且会⾃动去除⼦句的开头的AND或
OR
以上标签也可以使⽤ <trim prefix="where" prefixOverrides="and"> 替换, 但是此种
情况下, 当⼦元素都没有内容时, where关键字也会保留
或者使⽤注解⽅式
@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);

<set>标签

需求: 根据传⼊的⽤⼾对象属性来更新⽤⼾数据,可以使⽤标签来指定动态内容.
接⼝定义: 根据传⼊的⽤⼾ id 属性,修改其他不为 null 的属性
Integer updateUserByCondition(UserInfo userInfo);
Mapper.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关键字,并会删掉额外的逗号. (⽤于update语句中)
以上标签也可以使⽤ <trim prefix="set" suffixOverrides=","> 替换。
或者使⽤注解⽅式
@Update("<script>" +
 "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}" +
 "</script>")
Integer updateUserByCondition(UserInfo userInfo);

<foreach>标签

对集合进⾏遍历时可以使⽤该标签。标签有如下属性:

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

item:遍历时的每⼀个对象

open:语句块开头的字符串

close:语句块结束的字符串

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

需求: 根据多个userid, 删除⽤⼾数据

接⼝⽅法:

void deleteByIds(List<Integer> ids);
ArticleMapper.xml 中新增删除 sql:
<delete id="deleteByIds">
 delete from userinfo
 where 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);

<include>标签

问题分析:
在xml映射⽂件中配置的SQL,有时可能会存在很多重复的⽚段,此时就会存在很多冗余的代码
我们可以对重复的代码⽚段进⾏抽取,将其通过 <sql> 标签封装到⼀个SQL⽚段,然后再通过
<include> 标签进⾏引⽤。
<sql> :定义可重⽤的SQL⽚段
<include> :通过属性refid,指定包含的SQL⽚段
<sql id="allColumn">
 id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>
通过 <include> 标签在原来抽取的地⽅进⾏引⽤。操作如下:
<select id="queryAllUser" resultMap="BaseMap">
 select
 <include refid="allColumn"></include>
 from userinfo
 </select>

<select id="queryById" resultType="com.example.demo.model.UserInfo">
 select
 <include refid="allColumn"></include>
 from userinfo where id= #{id}
</select>


http://www.kler.cn/a/408358.html

相关文章:

  • 【SQL】【数据库】语句翻译例题
  • 虚幻引擎---术语篇
  • linux入门——“僵尸进程、孤儿进程”
  • oracle查看锁阻塞-谁阻塞了谁
  • 《FreeRTOS任务删除篇》
  • 1123--日期类
  • C++详细笔记(七)(string底层初步实现)
  • 曲谱转换成音频
  • 【免费】高比例风电电力系统储能运行及配置分析【火电机组、风能、储能】
  • 企业数智化新纪元,安全体系保驾护航
  • 蓝桥杯嵌入式再学习(4)led的点亮
  • 淘宝接口高并发采集优化之道:提升数据获取速度与质量
  • RTOS学习笔记---任务的管理
  • jsencrypt 库作用
  • 【设计模式系列】责任链模式(十六)
  • Jedis存储一个以byte[]的形式的对象到Redis
  • 模型压缩——如何进行知识蒸馏?
  • kotlin 的循环
  • 【MySQL】开发技术深度探索:mysql数据库复合查询全面详解
  • Group Convolution(分组卷积)
  • 1123--collection接口,list接口,set接口
  • scau编译原理综合性实验
  • 【数据结构】链表重难点突破
  • CTF之密码学(键盘加密)
  • Linux(2)
  • 16.C++STL 3(string类的模拟,深浅拷贝问题)