简述MyBatis的动态SQL(xml实现)

数据库表的创建

-- 创建数据库
DROP DATABASE IF EXISTS mybatis_test;
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
USE mybatis_test;
-- 创建表[⽤⼾表]
DROP TABLE IF EXISTS userinfo;
CREATE TABLE `userinfo` (
 `id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
 `username` VARCHAR ( 127 ) NOT NULL,
 `password` VARCHAR ( 127 ) NOT NULL,
 `age` TINYINT ( 4 ) NOT NULL,
 `gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-⼥ 0-默认',
 `phone` VARCHAR ( 15 ) DEFAULT NULL,
 `delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',
 `create_time` DATETIME DEFAULT now(),
 `update_time` DATETIME DEFAULT now(),
 PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;

Java中创建相应的实体类

public class UserInfo {
 private Integer id;
 private String username;
 private String password;
 private Integer age;
 private Integer gender;
 private String phone;
 private Integer deleteFlag;
 private Date createTime;
 private Date updateTime;
}

1.if标签

当用户注册用户信息时,会有必填项和非必填项,这时候就可以用if标签判断,通过条件判断来排除特定的SQL片段,从而生成不同的SQL语句
if标签中, 使⽤的是Java对象的属性, ⽽⾮数据库字段
例如 增加用户gender是非必填项

接口定义

Integer insert(UserInfo userInfo)

接口实现

<insert id="insert">
 INSERT INTO userinfo (
 username,`password`,age,
 <if test="gender != null">
 gender,
 </if>
 phone)
 VALUES (
 #{username},
 #{age},
 <if test="gender != null">
 #{gender},
 </if>
 #{phone})
</insert>

2.trim标签

之前插入对象只有gender是非必填项,如果有多个非必填项时,一般使用使⽤标签结合标签,使用trim标签可以在条件为空或者不满足时,避免拼接不正确的sql语句。
trim标签有以下几个属性:
1.prefix:指定在拼接条件之前添加的字符串。
2.prefixOverrides:指定要去除的前缀字符串。
3.suffix:指定在拼接条件之后添加的字符串。
4.suffixOverrides:指定要去除的后缀字符串。

例如:增加用户有多个非必填项

接口定义

Integer insert(UserInfo userInfo)

接口实现

<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>

sql动态解析上面语句

  • 基于 prefix 配置,开始部分加上 (
  • 基于 suffix 配置,结束部分加上 )
  • 多个 组织的语句都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于suffixOverrides 配置去掉最后⼀个 ,

3.where标签

where标签会自动去掉开头的AND或OR关键字。这样即使第一个条件没有使用AND或OR连接符,最终生成的SQL语句也是正确的,如果where标签部分没有传递参数,则不会生成对应的where条件
例如:根据属性做where条件查询

接口定义

List<UserInfo> queryByCondition();

接口实现

<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>

4.set标签

set标签是一种用于更新用户数据的标签,它可以根据传入的用户对象属性来更新用户数据。通过使用set标签,可以动态指定要更新的内容
动态的在SQL语句中插⼊set关键字,并会删掉额外的逗号
例如:根据传入的用户对象属性来动态更新用户数据

接口定义

Integer updateUser(UserInfo userInfo);

接口实现

<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>

5.foreach标签

foreach标签它可以将集合或数组中的每个元素作为参数传递给SQL语句中的占位符,从而动态生成多个SQL语句
foreach标签有以下几个重要的属性:
1.collection:指定要遍历的集合或数组。
2. item:指定每个元素在遍历过程中的引用名称。
3.open:指定每个生成的SQL语句的起始字符。
4. separator:指定每个生成的SQL语句之间的分隔符。
5. close:指定每个生成的SQL语句的结束字符

例如:根据多个userid, 删除⽤⼾数据

接口定义

void deleteByIds(List<Integer> ids);

接口实现

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

6.include标签

xml⽂件中配置的SQL,有时可能会存在很多重复的⽚段,此时就会存在很多冗余的代码我们可以对重复的代码⽚段进⾏抽取,将其通过 sql 标签封装到⼀个SQL⽚段,然后再通过include>标签进⾏引⽤

例子分析

sql 标签封装到⼀个SQL⽚段

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

通过 标签在原来抽取的地⽅进⾏引⽤

<select id="queryAllUser" resultMap="BaseMap">
 select
 <include refid="allColumn"></include>
 from userinfo
</select>

解析上面sql语句为

select id, username, age, gender, phone, delete_flag, create_time, update_time from userinfo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值