Mybatis 标签的骚操作用法,你都知道哪些?|Java 开发实战

本文正在参加「Java主题月 – Java 开发实战」,详情查看 活动链接

开篇

这是我参与更文挑战的第6天,活动详情查看: 更文挑战

有时候新增一条数据,需要这条新增数据的主键,以便使用,如果采用先插入再查询的方式明显不符合要求,效率也变低了。

这时候,可以使用<selectKey>标签,将insert的数据的主键返回,直接拿到新增数据的主键,以便后续使用。

插入时返回数据主键

表的主键有两种,一种自增主键,一般为int/long类型,一种为非自增的主键,例如用uuid等。

  • 自增类型的主键。
<!--selectKey  会将 SELECT LAST_INSERT_ID()的结果放入到传入的model的主键里面,  
        keyProperty 对应的model中的主键的属性名,这里是 AccountModifyLogDo 中的id,因为它跟数据库的主键对应, 
        order: AFTER 表示 SELECT LAST_INSERT_ID() 在insert执行之后执行,多用与自增主键,  
              BEFORE 表示 SELECT LAST_INSERT_ID() 在insert执行之前执行,这样的话就拿不到主键了,这种适合那种主键不是自增的类型  
        resultType 主键类型 -->  
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
  LAST_INSERT_ID()
</selectKey>
复制代码
  • 非自增的主键
<!-- 跟自增主键方式相比,这里的不同之处只有两点  
    1  insert语句需要写id字段了,并且 values里面也不能省略  
    2 selectKey 的order属性需要写成BEFORE 因为这样才能将生成的uuid主键放入到model中,  
    这样后面的insert的values语句里面的id才不会获取为空  
跟自增主键相比就这点区别,当然了这里的获取主键id的方式为 select uuid()  也可以另外生成函数。-->
<selectKey keyProperty="id" order="BEFORE" resultType="String">  
    select uuid()  
</selectKey>
复制代码

示例

  <insert id="insertSelective" parameterType="com.account.dao.model.account.AccountModifyLogDo">
  
    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
      SELECT 0
    </selectKey>
    insert into t_account_modify_log
    <!-- <trim>标签
    prefix:在trim标签内sql语句加上前缀。
    suffix:在trim标签内sql语句加上后缀。
    prefixOverrides:指定去除多余的前缀内容
    suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。
    -->
    <trim prefix="(" suffix=")" prefixOverrides="" suffixOverrides=",">
      <if test="customerId != null">
        customer_id,
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="customerId != null">
        #{customerId,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
    </trim>
  </insert>
</mapper>
复制代码

返回数据对比的结果

通过设置resultTypeBoolean类型来实现某些简单的逻辑校验

 <select id="existPhone" resultType="java.lang.Boolean">
        SELECT COUNT(*) > 0 FROM t_customer
        WHERE phone = #{phone} AND is_del = 0
    </select>
复制代码

注解中使用动态sql

要在带注解的映射器Mapper接口类中使用动态 SQL,可以使用

@Update({"<script>",
"update Author",
"  <set>",
"    <if test='username != null'>username=#{username},</if>",
"    <if test='password != null'>password=#{password},</if>",
"    <if test='email != null'>email=#{email},</if>",
"    <if test='bio != null'>bio=#{bio}</if>",
"  </set>",
"where id=#{id}",
"</script>"})
void updateAuthorValues(Author author);
复制代码

动态sql中使用变量赋值替换

元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:

<select id="selectArticleLike" resultType="ArticleDO">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM Article
  WHERE title LIKE #{pattern}
</select>
复制代码

多数据库动态sql支持

如果配置了databaseIdProvider,就可以在动态代码中使用名为 _databaseId 的变量来为不同的数据库源构建特定的语句。比如下面的例子:

<insert id="insert">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    <if test="_databaseId == 'oracle'">
      insert into users values (#{name})
    </if>
    <if test="_databaseId == 'sqlserver'">
      select id from user order by id desc limit 1;
    </if>
  </selectKey>
  insert into users values (#{id}, #{name})
</insert>
复制代码

关注+点赞?收藏❤️不迷路

文章每周持续更新,可以微信搜索「 十分钟学编程 」第一时间阅读和催更,如果这个文章写得还不错,觉得有点东西的话
各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享