本文正在参加「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>
复制代码
返回数据对比的结果
通过设置resultType
为Boolean
类型来实现某些简单的逻辑校验
<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