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