当前位置:   article > 正文

jpa中id自增策略_jpa id自增

jpa id自增

一.数据库自带策略

1.@GeneratedValue

@GeneratedValue 用于标注主键的生成策略,通过 strategy 属性指定。

默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略:SqlServer 对应 identity,MySQL 对应 auto increment

① @GeneratedValue(strategy = GenerationType.AUTO) JPA自动选择合适的策略,是默认选项

②@GeneratedValue(strategy = GenerationType.IDENTITY) 采用数据库 ID自增长的方式来自增主 键字段,Oracle 不支持这种方式

③@GeneratedValue(strategy = GenerationType.TABLE) 通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。

④@GeneratedValue(strategy = GenerationType.SEQUENCE)
通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式

二.自定义id自增策略

1.自定义主键生成器AutoGenerator

需要实现IdentifierGenerator并实现 generate()方法。在generate()方法里面去写自定义的主键生成策略

@Component
public class AutoGenerator implements IdentifierGenerator {
    
    protected static final String COL_ALIAS = "maxidval";
 
    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object object)
        throws HibernateException {
        //获取table注解,通过table获取表名
        Table table = object.getClass().getAnnotation(Table.class);
        if (ObjectUtils.isEmpty(table) || ObjectUtils.isEmpty(table.name()))
            return PKGenerator.getPK();   //如果获取不到Table则返回随机ID
        // 获取表名
        String tablename = table.name();
        DynamicTableService dynamicTableService = SpringContextUtils.getBean(DynamicTableService.class);
        // 获取实体中的自增列,这里认为@javax.persistence.Id或@org.springframework.data.annotation.Id修饰的属性就是我们要的
        Field pkCol = getPKCol(object.getClass());
        if (ObjectUtils.isEmpty(pkCol) || ObjectUtils.isEmpty(pkCol.getName()))
            return PKGenerator.getPK();
        String pk = pkCol.getName();
        // 获取自增列最大值, 用mybatis查询最大ID,dynamicTableService.selectByConditions方法可以自定义。参数是传入表名和自增列名
        List<Map<String, Object>> resultList = dynamicTableService.selectByConditions(new DynamicSelectDTO(tablename,
            CollectionUtil.fastList("max(" + pk + ") " + COL_ALIAS), CollectionUtil.fastList()));
        // 下面各种找不到值的情况统一返回1
        if (ObjectUtils.isEmpty(resultList))
            return 1L;
        Map<String, Object> map = resultList.get(0);
        if (ObjectUtils.isEmpty(map))
            return 1L;
        Object maxid = map.get(COL_ALIAS);
        if (ObjectUtil.isEmpty(maxid))
            return 1L;
        // 找到了+1返回
        Long idLong = ObjectUtil.toLong(maxid);
        return ++idLong;
    }
    
    /**
     * @description 获取实体中的自增列,这里认为@javax.persistence.Id或@org.springframework.data.annotation.Id修饰的属性就是我们要的
     * @param clz
     * @return
     */
    protected Field getPKCol(Class<?> clz) {
        //获取实体的所有元素
        Field[] allFields = ReflectUtil.getAllFields(clz);
        for (Field field : allFields) {
            //如果字段有javax.persistence.Id或者org.springframework.data.annotation.Id注解则返回此字段
            if (!ObjectUtils.isEmpty(field.getAnnotation(javax.persistence.Id.class)) || 
                !ObjectUtils.isEmpty(field.getAnnotation(org.springframework.data.annotation.Id.class)))
                return field;
        }
        return null;
    }

}

2.主键上加注解

@GenericGenerator(name="id",strategy="cn.qingsec.test.report.utils.AutoGenerator")
@GeneratedValue(generator = "id")
@Column(name="id",columnDefinition = "varchar(15) comment 'ID'")
private String id;

注意:@GeneratedValue 里面的generator  要和 @GenericGenerator 里面的name 相同,@GenericGenerator里面的strategy  要和自己定义的主键生成器SeqPKGenerator一致,需要包括包名

参考:JPA不依赖数据库用程序实现自增ID,@GeneratedValue,@GenericGenerator,IdentifierGenerator_jpa 自增_maqinghui的博客-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/739628
推荐阅读
相关标签
  

闽ICP备14008679号