首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@TableGenerator for mybatis

@TableGenerator for mybatis
EN

Stack Overflow用户
提问于 2019-07-16 04:49:40
回答 2查看 298关注 0票数 0

我已经成功地将@TableGenerator与EclipseLink一起使用:

代码语言:javascript
复制
@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机制?

任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

发布于 2019-07-17 00:07:54

@TableGenerator是JPA的特性。在幕后,JPA实现发出多个查询来生成值。mybatis不会这样做,也就是说,它不会执行您没有显式指定的任何查询,因此没有简单且声明性的方法来实现与@TableGenerator提供的相同功能。您需要模拟hibernate对序列表执行的查询。

在mybatis中,您可以使用selectKey生成值。

以下是来自模拟GenerationType.SEQUENCE策略的documentation的略微修改的示例:

代码语言:javascript
复制
<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中的查询类似于:

代码语言:javascript
复制
INSERT INTO seq (seqName, id) values ('SEQUENCE', 1)
ON CONFLICT
 DO UPDATE id = id + 1
 WHERE seqName = 'SEQUENCE'
RETURNING id
票数 0
EN

Stack Overflow用户

发布于 2019-07-17 22:13:45

最后,我实现了一个自定义id生成器序列管理器来实现mybatis中的GenerationType.TABLE行为:

代码语言:javascript
复制
@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;
    }
}

感谢大家在这个问题上的帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57047014

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档