欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

通用mapper用oracle序列作为主键

程序员文章站 2022-07-06 09:38:22
通用mapper用oracle序列作为主键最近使用通用mapper开发项目,公司用的oracle数据库,持久层用的是通用mapper,公司要求用数据库的序列,按照官方的配置,可能是自己的原因,总是配置不对,自己看了一下源码,发现用key注解就可以实现,具体配置如下: @Id @Column(name = "id") @KeySql(sql = "select SEQ_ID.nextval from dual", order= ORDER.DEFAULT) private I...

通用mapper用oracle序列作为主键

最近使用通用mapper开发项目,公司用的oracle数据库,持久层用的是通用mapper,公司要求用数据库的序列,按照官方的配置,可能是自己的原因,总是配置不对,自己看了一下源码,发现用key注解就可以实现,具体配置如下:

    @Id
    @Column(name = "id")
    @KeySql(sql = "select SEQ_ID.nextval from dual", order= ORDER.DEFAULT)
    private Integer id;

平常用mybatis的时候,mybatis 有个selectKey标签,那么通用mapper应该是启动的时候把注解的内容封装成selectKey了。于是找到了BaseInsertProvider这个类。

   public String insert(MappedStatement ms) {
        Class<?> entityClass = getEntityClass(ms);
   }

这个insert方法就是保存的方法,getEntityClass就是解析实体。点进去看一下。

public Class<?> getEntityClass(MappedStatement ms) {
       EntityHelper.initEntityNameMap(returnType, mapperHelper.getConfig());
    }

找到了initEntityNameMap 方法,再跟进去。

 public static synchronized void initEntityNameMap(Class<?> entityClass, Config config) {
        if (entityTableMap.get(entityClass) != null) {
            return;
        }
        //创建并缓存EntityTable
        EntityTable entityTable = resolve.resolveEntity(entityClass, config);
        entityTableMap.put(entityClass, entityTable);
    }

终于找到了解析resolve.resolveEntity(entityClass, config),点进去看看。
应为注解是写的在Id字段上的,我们就重点看解析field的方法。

 for (EntityField field : fields) {
         
            if (config.isUseSimpleType()){
            //省略了一些方法
            processField(entityTable, field, config, style);
        }

然后看processField,找到处理主键的方法。

      //处理主键策略
        processKeyGenerator(entityTable, field, entityColumn);
 protected void processKeyGenerator(EntityTable entityTable, EntityField field, EntityColumn entityColumn) {
        //KeySql 优先级最高
        if (field.isAnnotationPresent(KeySql.class)) {
            processKeySql(entityTable, entityColumn, field.getAnnotation(KeySql.class));
        } else if (field.isAnnotationPresent(GeneratedValue.class)) {
            //执行 sql - selectKey
            processGeneratedValue(entityTable, entityColumn, field.getAnnotation(GeneratedValue.class));
        }
    }

看到了keysql 这个注解,于是看下面是怎么处理的。

    protected void processKeySql(EntityTable entityTable, EntityColumn entityColumn, KeySql keySql) {
        if (keySql.useGeneratedKeys()) {
            entityColumn.setIdentity(true);
            entityColumn.setGenerator("JDBC");
            entityTable.setKeyProperties(entityColumn.getProperty());
            entityTable.setKeyColumns(entityColumn.getColumn());
        } else if (keySql.dialect() == IdentityDialect.DEFAULT) {
            entityColumn.setIdentity(true);
            entityColumn.setOrder(ORDER.AFTER);
        }  else if (keySql.dialect() != IdentityDialect.NULL) {
            //自动增长
            entityColumn.setIdentity(true);
            entityColumn.setOrder(ORDER.AFTER);
            entityColumn.setGenerator(keySql.dialect().getIdentityRetrievalStatement());
        } else if (StringUtil.isNotEmpty(keySql.sql())){

            entityColumn.setIdentity(true);
            entityColumn.setOrder(keySql.order());
            entityColumn.setGenerator(keySql.sql());
        } else if (keySql.genSql() != GenSql.NULL.class){
            entityColumn.setIdentity(true);
            entityColumn.setOrder(keySql.order());
            try {
                GenSql genSql = keySql.genSql().newInstance();
                entityColumn.setGenerator(genSql.genSql(entityTable, entityColumn));
            } catch (Exception e) {
                log.error("实例化 GenSql 失败: " + e, e);
                throw new MapperException("实例化 GenSql 失败: " + e, e);
            }
        } else if(keySql.genId() != GenId.NULL.class){
            entityColumn.setIdentity(false);
            entityColumn.setGenIdClass(keySql.genId());
        } else {
            throw new MapperException(entityTable.getEntityClass().getCanonicalName()
                    + " 类中的 @KeySql 注解配置无效!");
        }
    }

}

这里面就是一些判断逻辑。于是我们用注解就可以实现了。

以上文章就是记录一下自己的心得,有不正之处,希望大家多多指点。

本文地址:https://blog.csdn.net/zlystudy/article/details/108974632