spring的配置文件配置的是扫面生成的东西(配置在web端),generator.xml(配置在core依赖项目里,配合该core的pom.xml使用
这个pom.xml中要配置注入的插件
)是配置控制生成如何生成(生成什么样子(对应Java列名等))
在generator.xml中 后面两个属性设置了可用的通用example操作类型,自动生成bean时生成注入主键方式也是在这里配置
<table tableName="TB_PACT_SED" enableUpdateByExample="true" enableSelectByExample="true">
<generatedKey column="SHIP_KEY" sqlStatement="SEQ_TB_PACT_SED" identity="false" />
</table>
参见通用mapper源码:MapperCommentGenerator
可知identity为false的时候考虑用sequence(默认的isSequenceColumn=ture)生成的效果如下第4
实体id两种生成方式:
1,
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY,generator = "select SEQ_TB_BAS_BED.nextval from dual")//用具体值注入(此值由sequence生成)
@Column(name = "WARE_KEY")
private String ware_key;
2,
@Id
@SequenceGenerator(name="TB_BID_OBJ_ID_GENERATOR", sequenceName="SEQ_TB_BID_OBJ_ID",allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="TB_BID_OBJ_ID_GENERATOR")//用sequence注入(由注入器生成注入值)
private Integer obj_key;
3,
@Id
@GeneratedValue(generator = "UUID")
@Column(name = "PURPOSE_ID")
private String purposeId;
4,
@Id
@Column(name = "SHIP_KEY")
//@SequenceGenerator(name=\"\",sequenceName=\"" + introspectedTable.getTableConfiguration().getGeneratedKey().getRuntimeSqlStatement() + "\");注入方式有好多种源码只用了其中一种
@SequenceGenerator(name="",sequenceName="SEQ_TB_PACT_SED")
private BigDecimal shipKey;
生成时关于表,属性名称:
domainObjectName 数据库表对应的数据对象名称,默认使用表名作为对象名称。
属性名默认是去下划线,java驼峰语法的
之前在集成的时候时用于jar包冲突,web-inf/lib用了一个版本,maven又用了一个版本优先用lib中的导致失败
参考:
http://www.cnblogs.com/GaiDynasty/p/4088531.html
http://generator.sturgeon.mopaas.com/configreference/generatedKey.html
http://jadethao.iteye.com/blog/1725374
生成源码:
public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
if (StringUtility.stringHasValue(introspectedColumn.getRemarks())) {
field.addJavaDocLine("");
}
//娣诲姞娉ㄨВ
if (field.isTransient()) {
//@Column
field.addAnnotation("@Transient");
}
for (IntrospectedColumn column : introspectedTable.getPrimaryKeyColumns()) {
if (introspectedColumn == column) {
field.addAnnotation("@Id");
break;
}
}
String column = introspectedColumn.getActualColumnName();
if (StringUtility.stringContainsSpace(column) || introspectedTable.getTableConfiguration().isAllColumnDelimitingEnabled()) {
column = introspectedColumn.getContext().getBeginningDelimiter()
+ column
+ introspectedColumn.getContext().getEndingDelimiter();
}
if (!column.equals(introspectedColumn.getJavaProperty())) {
//@Column
field.addAnnotation("@Column(name = \"" + column + "\")");
}
if (introspectedColumn.isIdentity()) {
if (introspectedTable.getTableConfiguration().getGeneratedKey().getRuntimeSqlStatement().equals("JDBC")) {
field.addAnnotation("@GeneratedValue(generator = \"JDBC\")");
} else {
field.addAnnotation("@GeneratedValue(strategy = GenerationType.IDENTITY)");
}
} else if (introspectedColumn.isSequenceColumn()) {
field.addAnnotation("@SequenceGenerator(name=\"\",sequenceName=\"" + introspectedTable.getTableConfiguration().getGeneratedKey().getRuntimeSqlStatement() + "\")");
}
}
//这段配置的解读:
关于IDENTITY:
<bean class="com.github.abel533.mapperhelper.MapperInterceptor">
<property name="properties">
<value>
mappers=com.github.abel533.mapper.Mapper//这个都可以省略
IDENTITY=MYSQL/和生成时注入的主键生成方式作用一样,只是为了保险起(实体没有申明注入方式(mysql可以,Oracle用sequence不好用因为sequence不同的
表对应不同))见这里做一个第二方案
notEmpty=true
</value>
</property>
</bean>
Config.class
MapperHelper
EntityHelper initEntityNameMap
MapperTemplate(这个类包含生成sql等是个关键类) newSelectKeyMappedStatement
由这个句话可以看出:
String IDENTITY = (column.getGenerator() == null) || (column.getGenerator().equals("")) ? getIDENTITY() : column.getGenerator();//getIDENTITY()从扫描的配置文件中获取的
在扫描器中配置的IDENTITY,和generator.xml中配置的:<generatedKey column="SHIP_KEY" sqlStatement="SEQ_TB_PACT_SED" identity="false" />即实体中的主键生成那段时同样的效果
在实体列中有用@GeneratedValue或@SequenceGenerator标签指明生成方式的情况下优先使用实体列中的,没有的话就用扫描中配置的
protected void newSelectKeyMappedStatement(MappedStatement ms, EntityColumn column) {
String keyId = ms.getId() + SelectKeyGenerator.SELECT_KEY_SUFFIX;
if (ms.getConfiguration().hasKeyGenerator(keyId)) {
return;
}
Class<?> entityClass = getEntityClass(ms);
//defaults
Configuration configuration = ms.getConfiguration();
KeyGenerator keyGenerator;
Boolean executeBefore = isBEFORE();
String IDENTITY = (column.getGenerator() == null || column.getGenerator().equals("")) ? getIDENTITY() : column.getGenerator();
if (IDENTITY.equalsIgnoreCase("JDBC")) {
keyGenerator = new Jdbc3KeyGenerator();
} else {
SqlSource sqlSource = new RawSqlSource(configuration, IDENTITY, entityClass);
MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, keyId, sqlSource, SqlCommandType.SELECT);
statementBuilder.resource(ms.getResource());
statementBuilder.fetchSize(null);
statementBuilder.statementType(StatementType.STATEMENT);
statementBuilder.keyGenerator(new NoKeyGenerator());
statementBuilder.keyProperty(column.getProperty());
statementBuilder.keyColumn(null);
statementBuilder.databaseId(null);
statementBuilder.lang(configuration.getDefaultScriptingLanuageInstance());
statementBuilder.resultOrdered(false);
statementBuilder.resulSets(null);
statementBuilder.timeout(configuration.getDefaultStatementTimeout());
List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
ParameterMap.Builder inlineParameterMapBuilder = new ParameterMap.Builder(
configuration,
statementBuilder.id() + "-Inline",
entityClass,
parameterMappings);
statementBuilder.parameterMap(inlineParameterMapBuilder.build());
List<ResultMap> resultMaps = new ArrayList<ResultMap>();
ResultMap.Builder inlineResultMapBuilder = new ResultMap.Builder(
configuration,
statementBuilder.id() + "-Inline",
column.getJavaType(),
new ArrayList<ResultMapping>(),
null);
resultMaps.add(inlineResultMapBuilder.build());
statementBuilder.resultMaps(resultMaps);
statementBuilder.resultSetType(null);
statementBuilder.flushCacheRequired(false);
statementBuilder.useCache(false);
statementBuilder.cache(null);
MappedStatement statement = statementBuilder.build();
try {
configuration.addMappedStatement(statement);
} catch (Exception e) {
//ignore
}
MappedStatement keyStatement = configuration.getMappedStatement(keyId, false);
keyGenerator = new SelectKeyGenerator(keyStatement, executeBefore);
try {
configuration.addKeyGenerator(keyId, keyGenerator);
} catch (Exception e) {
//ignore
}
}
//keyGenerator
try {
MetaObject msObject = SystemMetaObject.forObject(ms);
msObject.setValue("keyGenerator", keyGenerator);
msObject.setValue("keyProperties", column.getTable().getKeyProperties());
msObject.setValue("keyColumns", column.getTable().getKeyColumns());
} catch (Exception e) {
//ignore
}
}
关于mappers:
<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.isea533.mybatis.mapper"/>
<property name="properties">
<value>
mappers=tk.mybatis.mapper.common.Mapper//这个都可以省略
IDENTITY=select uuid()//对于使用可变的序列的序列号的值时,这个在配置文件配置不了
ORDER=BEFORE
</value>
</property>
</bean>
MapperScannerConfigurer.class
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
super.postProcessBeanDefinitionRegistry(registry);
//濡傛灉娌℃湁娉ㄥ唽杩囨帴鍙o紝灏辨敞鍐岄粯璁ょ殑Mapper鎺ュ彛
this.mapperHelper.ifEmptyRegisterDefaultInterface();///MapperScannerConfigurer中可以省略 mappers=tk.mybatis.mapper.common.Mapper配置
。。。
}
public void ifEmptyRegisterDefaultInterface() {
if (registerClass.size() == 0) {
registerMapper("tk.mybatis.mapper.common.Mapper");
}
}