Mybatis 动态SQL 2021-9-22

Mybatis 应用

1 Mybatis 入门与编码流程
2 mapper代理开发方式
3 全局配置文件
4 输入映射和输出映射
5 关联查询
6 延迟加载
7 动态SQL
8 Mybatis缓存


一、动态SQL介绍

动态SQL的思想:就是使用不同的动态SQL标签去完成字符串的拼接处理、循环判断。

解决的问题是:
1、 在映射文件中,会编写很多有重叠部分的SQL语句,比如SELECT语句和WHERE语句等这些重叠语句,该如何处理。
2、SQL语句中的where条件有多个,但是页面只传递过来一个条件参数,此时会发生问题。

二、 标签功能说明

2.1 if标签

查询条件是由页面传入,页面中的查询条件可能输入用户名称,也可能不输入用户名称。

    <select id="findUserList" parameterType="queryVo" resultType="user">SELECT * FROM user where 1=1
        <if test="user != null">
            <if test="user.username != null and user.username != ''">AND username like '%${user.username}%'</if>
        </if>
    </select>

2.2 where标签

上边的sql中的1=1,虽然可以保证sql语句的完整性:但是存在性能问题。(索引相关?)Mybatis提供where标签解决该问题。 where 遇到第一个and,会将第一个and 去掉。

    <select id="findUserList" parameterType="queryVo" resultType="user">SELECT * FROM user <!-- where标签会处理它后面的第一个and -->
        <where>
            <if test="user != null">
                <if test="user.username != null and user.username != ''">AND username like '%${user.username}%'</if>
            </if>
        </where>
    </select>

2.3 sql片段

在映射文件中可使用sql标签将重复的sql提取出来,然后使用include标签引用即可,最终达到sql重用的目的,具体实现如下:
1、将where条件抽取出来:

    <sql id="query_user_where">
        <if test="user != null">
            <if test="user.username != null and user.username != ''">AND username like '%${user.username}%'</if>
        </if>
    </sql>

2、使用include引用

    <!-- 使用包装类型查询用户 使用ognl从对象中取属性值,如果是包装对象可以使用.操作符来 取内容部的属性 -->
    <select id="findUserList" parameterType="queryVo" resultType="user">
        SELECT * FROM user
        <!-- where标签会处理它后面的第一个and -->
        <where>
            <include refid="query_user_where"></include>
        </where>
    </select>

注意:
1、如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下:

<include refid="namespace.sql片段”/>

2.4 foreach

综合查询时,传入多个id查询用户信息,用下边两个sql实现:

SELECT * FROM USER WHERE username LIKE '%老郭%' AND (id =1 OR id =10 OR id=16) 
SELECT * FROM USER WHERE username LIKE '%老郭%' AND id IN (1,10,16)

2.4.1 代码实现

在pojo中定义list属性ids存储多个用户id,并添加getter/setter方法。保存查询条件的参数。

public class QueryVo {
    private User user;
    private List<Integer> ids;
}

    <sql id="query_user_where">
        <if test="user != null">
            <if test="user.username != null and user.username != ''">
                AND username like '%${user.username}%'
            </if>
        </if>
        <if test="ids != null and ids.size() > 0">
            <!-- collection:指定输入的集合参数的参数名称 -->
            <!-- item:声明集合参数中的元素变量名,与#{item}对应 -->
            <!-- open:集合遍历时,需要拼接到遍历sql语句的前面 -->
            <!-- close:集合遍历时,需要拼接到遍历sql语句的后面 -->
            <!-- separator:集合遍历时,需要拼接到遍历sql语句之间的分隔符号 -->
            <foreach collection="ids" item="id" open=" AND id IN ( " close=" ) " separator=",">#{id}</foreach>
        </if>
    </sql>

注意事项
如果parameterType不是POJO类型,而是List或者Array的话,那么foreach语句中,collection属性值需要固定写死为list或者array。

2.5 存在唯一约束时,不存在时插入,存在时更新批量更新

INSERT 语句的一部分,如果指定 ON DUPLICATE KEY UPDATE ,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则在出现重复值的行执行UPDATE,如果不会导致唯一值列重复的问题,则插入新行。

sql 语句原型:

insert into table (player_id,award_type,num) values(20001,0,1) on DUPLICATE key update num=num+values(num)

批量执行时,执行效率大幅度提高。

 <insert id="batchUpdate" parameterType="java.util.List">
        insert into t_a
        (id,a1,a2,a3)
        values
        <foreach collection="list" item="item" index="index" separator=",">
            (#{item.id},
            #{item.a1},
            #{item.a2},
            #{item.a3})
        </foreach>
        ON DUPLICATE KEY UPDATE
        a1 = VALUES(a1),
        a2 = VALUES(a2)
    </insert>

columnList:需要更新的字段(检查对象中不为null的字段集合,例如:id,a1,a2,a3)

  • 在对象中取值的字符串,与collection对应,例如:#{item.id}, #{item.a1}, #{item.a2}, #{item.a3}
  • 修改更新的字段集合,例如:a1 =a1 + VALUES(a1), a2 = VALUES(a2), VALUES() 表示更新的字段
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值