通用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 注解配置无效!"); } } }
这里面就是一些判断逻辑。于是我们用注解就可以实现了。
以上文章就是记录一下自己的心得,有不正之处,希望大家多多指点。
数据库技术:通用mapper用oracle序列作为主键地址:https://blog.csdn.net/zlystudy/article/details/108974632
需要了解更多数据库技术:通用mapper用oracle序列作为主键,都可以关注数据库技术分享栏目—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/dtteaching/639503.html