我已经成功地将@TableGenerator与EclipseLink一起使用:
@Id
@TableGenerator(name = "ID_GEN",
table = "seq",
pkColumnName = "seqName",
valueColumnName = "`id`",
pkColumnValue = "SEQUENCE")
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ID_GEN")
private Long id;我在搜索Mybatis是否有同样的可能性来实现同样的结果,但我看到的唯一一件事是对generatedKey的一些引用:
http://www.mybatis.org/generator/configreference/generatedKey.html#)
下面的语句(来自上面的链接)引用了一些可能的“序列”,这让我认为可能有一种方法可以使用相同类型的顺序表来实现这一点。
“元素用于指定自动生成的键的属性(从标识字段或序列)。”
有没有办法在Mybatis中使用这个@GeneratedValue/@TableGenerator机制?
任何帮助都将不胜感激。
发布于 2019-07-17 00:07:54
@TableGenerator是JPA的特性。在幕后,JPA实现发出多个查询来生成值。mybatis不会这样做,也就是说,它不会执行您没有显式指定的任何查询,因此没有简单且声明性的方法来实现与@TableGenerator提供的相同功能。您需要模拟hibernate对序列表执行的查询。
在mybatis中,您可以使用selectKey生成值。
以下是来自模拟GenerationType.SEQUENCE策略的documentation的略微修改的示例:
<insert id="insertAuthor">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
select nextval('author_id_seq')
</selectKey>
insert into Author
(id, username, password, email,bio, favourite_section)
values
(#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
</insert>在selectKey部分,可以指定任意查询。它的结果将被赋值给在keyProperty中指定的属性,在本例中是传递的对象的id。
模拟@TableGenerator策略GenerationType.TABLE的实际查询取决于数据库。对于postgresql,selectKey中的查询类似于:
INSERT INTO seq (seqName, id) values ('SEQUENCE', 1)
ON CONFLICT
DO UPDATE id = id + 1
WHERE seqName = 'SEQUENCE'
RETURNING id发布于 2019-07-17 22:13:45
最后,我实现了一个自定义id生成器序列管理器来实现mybatis中的GenerationType.TABLE行为:
@Mapper
public interface ReadOnly {
@Select("SELECT `index` from sequence WHERE sequenceName = #{sequenceName}")
Long getNextIndex(@Param("sequenceName") String sequenceName);
}
@Mapper
public interface ReadWrite {
@Update("UPDATE sequence SET `index` = #{index} WHERE (sequenceName = #{sequenceName})")
void updateIndex(@Param("index") long index, @Param("sequenceName") String sequenceName);
@Component
public class SequenceManager {
@Autowired
ReadOnly readonly;
@Autowired
ReadWrite readwrite;
private long index = 0;
private static long blockSize = 10;
public SequenceManager() {
}
public long getNextIndex(String sequenceName) {
if (index % blockSize == 0) {
index = getAfterIncrement(sequenceName);
}
return index++;
}
@Transactional
public long getAfterIncrement(String sequenceName) {
index = readonly.getNextIndex(sequenceName);
readwrite.updateIndex(index + blockSize, sequenceName);
return index + blockSize;
}
}感谢大家在这个问题上的帮助。
https://stackoverflow.com/questions/57047014
复制相似问题