我们目前在数据库中有触发器,为我插入的每条记录分发uid。当我用mybatis插入记录时,我想要获得该uid,而不是已插入的行数。
从之前的帖子中我读到我可以用
useGeneratedKeys="true" keyProperty="id"
但是我们将uuid存储为二进制,所以我想从插入操作中获得非二进制的uuid。当我们插入东西时,我们使用像'uuid2bin'和'bin2uuid'这样的函数,所以我希望使用这样的函数从数据库(MySQL)检索新生成的uuid。
关于如何获得新生成的uuid有什么建议吗??
我可以想到两个选项:1)使用MyBatis TypeHandler
在Java中进行转换,或2)使用返回格式化UUID的存储过程包装插入。
第1条的问题是,如果MySql是远程的,那么您将把负载从DB转移到应用程序,这可能会对性能产生影响。
使用#2,您需要在MyBatis中使用<select>
。但是,你需要确保它确实提交了。此外,如果您正在使用MyBatis缓存,您还需要在<select>
中设置flushCache=true
。
我会在<insert>
标签内使用<selectKey>
标签
<insert>
<selectKey keyProperty="pk" resultType="Type" order="AFTER">
select myDBFunction( (select triggerGeneratedColumnInBinary from myTable where pk = triggerLogicToRetrieveLastGenerated(...) ) );
</selectKey>
...procedure call or insert...
</insert>
如果你发送的是对象而不是Hashmap,这段代码将在插入后用触发器生成的列设置解释器函数的结果。该方法仍将返回行数,但您的对象将保留其键。
System.out.println(myObject.getPk()); //0
int rows = myMapper.insertMyClass(myObject); // sets the pk
System.out.println(myObject.getPK()); //324
useGeneratedKeys将不会帮助你,因为它告诉MyBatis使用JDBC getGeneratedKeys方法来检索数据库内部生成的键(例如,RDBMS中的自动增量字段,如MySQL或SQL Server)。
方法返回的值是更新的行数。传入参数的id是插入行的id。如下:
<insert id="insertSelectiveReturnKey" parameterType="com.test.dal.model.CostDO" useGeneratedKeys="true" keyProperty="id">
insert into cost
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="name != null">
name,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="name != null">
#{name,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
CostDO costDO = new CostDO();
costDO.setName("test");
int updateNum = productMapper.insertSelectiveReturnKey(costDO);
// updateNum is the number of updated rows.
productMapper.insertSelectiveReturnKey(costDO);
int id = costDO.getId();
// id is the id of insertd row