簡體   English   中英

@TableGenerator for mybatis

[英]@TableGenerator for mybatis

我在EclipseLink上成功使用了@TableGenerator:

@Id
@TableGenerator(name = "ID_GEN",
        table = "seq",
        pkColumnName = "seqName",
        valueColumnName = "`id`",
        pkColumnValue = "SEQUENCE")
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ID_GEN")
private Long id;

我正在搜索Mybatis是否有相同的可能性來完成相同的結果,但是我唯一看到的是對generateKey的一些引用:

http://www.mybatis.org/generator/configreference/generatedKey.html#

下面的語句(來自上面的鏈接)是指一些可能的“序列”,這使我認為可能存在一種使用相同類型的序列表來完成此操作的方法。

“該元素用於指定自動生成的鍵的屬性(來自標識字段或序列)。”

有什么方法可以在Mybatis中使用此@ GeneratedValue / @ TableGenerator機制嗎?

任何幫助將不勝感激。

@TableGenerator是JPA的功能。 在后台,JPA實現發出多個查詢以生成值。 mybatis不會執行此操作,也就是說,它不會執行您未明確指定的任何查詢,因此沒有簡單和聲明性的方法來實現與@TableGenerator提供的功能相同的功能。 您將需要模擬休眠對序列表的查詢。

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

這是模仿GenerationType.SEQUENCE策略的文檔中經過稍微修改的示例:

<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結果分配給keyProperty中指定的屬性,該id是所傳遞對象的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

最后,我實現了一個自定義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;
    }
}

謝謝大家的幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM