Skip to content

Commit e76e254

Browse files
committed
修改处理Field的逻辑,解决实体类继承时的泛型类型。
1 parent 5b5876c commit e76e254

File tree

1 file changed

+152
-117
lines changed

1 file changed

+152
-117
lines changed

src/main/java/tk/mybatis/mapper/mapperhelper/EntityHelper.java

Lines changed: 152 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@
3636
import tk.mybatis.mapper.util.StringUtil;
3737

3838
import javax.persistence.*;
39-
import java.lang.reflect.Field;
40-
import java.lang.reflect.Modifier;
39+
import java.lang.reflect.*;
4140
import java.util.*;
4241

4342
/**
@@ -189,6 +188,18 @@ public static synchronized void initEntityNameMap(Class<?> entityClass, Config c
189188
NameStyle nameStyle = entityClass.getAnnotation(NameStyle.class);
190189
style = nameStyle.value();
191190
}
191+
//创建并缓存EntityTable
192+
entityTableMap.put(entityClass, newEntityTable(entityClass, style));
193+
}
194+
195+
/**
196+
* 新建EntityTable
197+
*
198+
* @param entityClass
199+
* @param style
200+
* @return
201+
*/
202+
private static EntityTable newEntityTable(Class<?> entityClass, Style style) {
192203
//表名
193204
EntityTable entityTable = null;
194205
if (entityClass.isAnnotationPresent(Table.class)) {
@@ -203,133 +214,38 @@ public static synchronized void initEntityNameMap(Class<?> entityClass, Config c
203214
//可以通过stye控制
204215
entityTable.setName(StringUtil.convertByStyle(entityClass.getSimpleName(), style));
205216
}
206-
207-
//列
208-
List<Field> fieldList = getAllField(entityClass, null);
209-
Set<EntityColumn> columnSet = new LinkedHashSet<EntityColumn>();
210-
Set<EntityColumn> pkColumnSet = new LinkedHashSet<EntityColumn>();
211-
for (Field field : fieldList) {
212-
//排除字段
213-
if (field.isAnnotationPresent(Transient.class)) {
214-
continue;
215-
}
216-
//Id
217-
EntityColumn entityColumn = new EntityColumn(entityTable);
218-
if (field.isAnnotationPresent(Id.class)) {
219-
entityColumn.setId(true);
220-
}
221-
//Column
222-
String columnName = null;
223-
if (field.isAnnotationPresent(Column.class)) {
224-
Column column = field.getAnnotation(Column.class);
225-
columnName = column.name();
226-
}
227-
//ColumnType
228-
if (field.isAnnotationPresent(ColumnType.class)) {
229-
ColumnType columnType = field.getAnnotation(ColumnType.class);
230-
//column可以起到别名的作用
231-
if(StringUtil.isEmpty(columnName) && StringUtil.isNotEmpty(columnType.column())){
232-
columnName = columnType.column();
233-
}
234-
if(columnType.jdbcType() != JdbcType.UNDEFINED){
235-
entityColumn.setJdbcType(columnType.jdbcType());
236-
}
237-
if(columnType.typeHandler() != UnknownTypeHandler.class){
238-
entityColumn.setTypeHandler(columnType.typeHandler());
239-
}
240-
}
241-
//表名
242-
if (StringUtil.isEmpty(columnName)) {
243-
columnName = StringUtil.convertByStyle(field.getName(), style);
244-
}
245-
entityColumn.setProperty(field.getName());
246-
entityColumn.setColumn(columnName);
247-
entityColumn.setJavaType(field.getType());
248-
//OrderBy
249-
if (field.isAnnotationPresent(OrderBy.class)) {
250-
OrderBy orderBy = field.getAnnotation(OrderBy.class);
251-
if (orderBy.value().equals("")) {
252-
entityColumn.setOrderBy("ASC");
253-
} else {
254-
entityColumn.setOrderBy(orderBy.value());
255-
}
256-
}
257-
//主键策略 - Oracle序列,MySql自动增长,UUID
258-
if (field.isAnnotationPresent(SequenceGenerator.class)) {
259-
SequenceGenerator sequenceGenerator = field.getAnnotation(SequenceGenerator.class);
260-
if (sequenceGenerator.sequenceName().equals("")) {
261-
throw new RuntimeException(entityClass + "字段" + field.getName() + "的注解@SequenceGenerator未指定sequenceName!");
262-
}
263-
entityColumn.setSequenceName(sequenceGenerator.sequenceName());
264-
} else if (field.isAnnotationPresent(GeneratedValue.class)) {
265-
GeneratedValue generatedValue = field.getAnnotation(GeneratedValue.class);
266-
if (generatedValue.generator().equals("UUID")) {
267-
entityColumn.setUuid(true);
268-
} else if (generatedValue.generator().equals("JDBC")) {
269-
entityColumn.setIdentity(true);
270-
entityColumn.setGenerator("JDBC");
271-
entityTable.setKeyProperties(entityColumn.getProperty());
272-
entityTable.setKeyColumns(entityColumn.getColumn());
273-
} else {
274-
//允许通过generator来设置获取id的sql,例如mysql=CALL IDENTITY(),hsqldb=SELECT SCOPE_IDENTITY()
275-
//允许通过拦截器参数设置公共的generator
276-
if (generatedValue.strategy() == GenerationType.IDENTITY) {
277-
//mysql的自动增长
278-
entityColumn.setIdentity(true);
279-
if (!generatedValue.generator().equals("")) {
280-
String generator = null;
281-
IdentityDialect identityDialect = IdentityDialect.getDatabaseDialect(generatedValue.generator());
282-
if (identityDialect != null) {
283-
generator = identityDialect.getIdentityRetrievalStatement();
284-
} else {
285-
generator = generatedValue.generator();
286-
}
287-
entityColumn.setGenerator(generator);
288-
}
289-
} else {
290-
throw new RuntimeException(field.getName()
291-
+ " - 该字段@GeneratedValue配置只允许以下几种形式:" +
292-
"\n1.全部数据库通用的@GeneratedValue(generator=\"UUID\")" +
293-
"\n2.useGeneratedKeys的@GeneratedValue(generator=\\\"JDBC\\\") " +
294-
"\n3.类似mysql数据库的@GeneratedValue(strategy=GenerationType.IDENTITY[,generator=\"Mysql\"])");
295-
}
296-
}
297-
}
298-
columnSet.add(entityColumn);
299-
if (entityColumn.isId()) {
300-
pkColumnSet.add(entityColumn);
301-
}
302-
}
303-
entityTable.setEntityClassColumns(columnSet);
304-
if (pkColumnSet.size() == 0) {
305-
entityTable.setEntityClassPKColumns(columnSet);
306-
} else {
307-
entityTable.setEntityClassPKColumns(pkColumnSet);
217+
entityTable.setEntityClassColumns(new LinkedHashSet<EntityColumn>());
218+
entityTable.setEntityClassPKColumns(new LinkedHashSet<EntityColumn>());
219+
//处理所有列
220+
processAllColumns(entityTable, style, null, null);
221+
//当pk.size=0的时候使用所有列作为主键
222+
if (entityTable.getEntityClassPKColumns().size() == 0) {
223+
entityTable.setEntityClassPKColumns(entityTable.getEntityClassColumns());
308224
}
309-
//缓存
310-
entityTableMap.put(entityClass, entityTable);
225+
return entityTable;
311226
}
312227

313-
314228
/**
315-
* 获取全部的Field
229+
* 处理所有列
316230
*
231+
* @param entityTable
232+
* @param style
317233
* @param entityClass
318-
* @param fieldList
319-
* @return
234+
* @param genericMap 处理泛型字段
320235
*/
321-
private static List<Field> getAllField(Class<?> entityClass, List<Field> fieldList) {
322-
if (fieldList == null) {
323-
fieldList = new ArrayList<Field>();
236+
private static void processAllColumns(EntityTable entityTable, Style style, Class<?> entityClass, Map<String, Class<?>> genericMap) {
237+
if (entityClass == null) {
238+
entityClass = entityTable.getEntityClass();
324239
}
325240
if (entityClass.equals(Object.class)) {
326-
return fieldList;
241+
return;
327242
}
328243
Field[] fields = entityClass.getDeclaredFields();
329244
for (Field field : fields) {
330245
//排除静态字段,解决bug#2
331246
if (!Modifier.isStatic(field.getModifiers())) {
332-
fieldList.add(field);
247+
//处理field
248+
processField(entityTable, style, field, genericMap);
333249
}
334250
}
335251
Class<?> superClass = entityClass.getSuperclass();
@@ -338,8 +254,127 @@ private static List<Field> getAllField(Class<?> entityClass, List<Field> fieldLi
338254
&& (superClass.isAnnotationPresent(Entity.class)
339255
|| (!Map.class.isAssignableFrom(superClass)
340256
&& !Collection.class.isAssignableFrom(superClass)))) {
341-
return getAllField(entityClass.getSuperclass(), fieldList);
257+
Map<String, Class<?>> _genericMap = null;
258+
if (entityClass.getGenericSuperclass() instanceof ParameterizedType) {
259+
Type[] types = ((ParameterizedType) entityClass.getGenericSuperclass()).getActualTypeArguments();
260+
TypeVariable[] typeVariables = superClass.getTypeParameters();
261+
if (typeVariables.length > 0) {
262+
_genericMap = new HashMap<String, Class<?>>();
263+
for (int i = 0; i < typeVariables.length; i++) {
264+
_genericMap.put(typeVariables[i].getName(), (Class<?>) types[i]);
265+
}
266+
}
267+
}
268+
processAllColumns(entityTable, style, superClass, _genericMap);
269+
}
270+
}
271+
272+
/**
273+
* 处理一列
274+
*
275+
* @param entityTable
276+
* @param style
277+
* @param field
278+
* @param genericMap
279+
*/
280+
private static void processField(EntityTable entityTable, Style style, Field field, Map<String, Class<?>> genericMap) {
281+
//排除字段
282+
if (field.isAnnotationPresent(Transient.class)) {
283+
return;
284+
}
285+
//Id
286+
EntityColumn entityColumn = new EntityColumn(entityTable);
287+
if (field.isAnnotationPresent(Id.class)) {
288+
entityColumn.setId(true);
289+
}
290+
//Column
291+
String columnName = null;
292+
if (field.isAnnotationPresent(Column.class)) {
293+
Column column = field.getAnnotation(Column.class);
294+
columnName = column.name();
295+
}
296+
//ColumnType
297+
if (field.isAnnotationPresent(ColumnType.class)) {
298+
ColumnType columnType = field.getAnnotation(ColumnType.class);
299+
//column可以起到别名的作用
300+
if (StringUtil.isEmpty(columnName) && StringUtil.isNotEmpty(columnType.column())) {
301+
columnName = columnType.column();
302+
}
303+
if (columnType.jdbcType() != JdbcType.UNDEFINED) {
304+
entityColumn.setJdbcType(columnType.jdbcType());
305+
}
306+
if (columnType.typeHandler() != UnknownTypeHandler.class) {
307+
entityColumn.setTypeHandler(columnType.typeHandler());
308+
}
309+
}
310+
//表名
311+
if (StringUtil.isEmpty(columnName)) {
312+
columnName = StringUtil.convertByStyle(field.getName(), style);
313+
}
314+
entityColumn.setProperty(field.getName());
315+
entityColumn.setColumn(columnName);
316+
if (field.getGenericType() != null && field.getGenericType() instanceof TypeVariable) {
317+
if (genericMap == null || !genericMap.containsKey(((TypeVariable) field.getGenericType()).getName())) {
318+
throw new RuntimeException(entityTable.getEntityClass() + "字段" + field.getName() + "的泛型类型无法获取!");
319+
} else {
320+
entityColumn.setJavaType(genericMap.get(((TypeVariable) field.getGenericType()).getName()));
321+
}
322+
} else {
323+
entityColumn.setJavaType(field.getType());
324+
}
325+
//OrderBy
326+
if (field.isAnnotationPresent(OrderBy.class)) {
327+
OrderBy orderBy = field.getAnnotation(OrderBy.class);
328+
if (orderBy.value().equals("")) {
329+
entityColumn.setOrderBy("ASC");
330+
} else {
331+
entityColumn.setOrderBy(orderBy.value());
332+
}
333+
}
334+
//主键策略 - Oracle序列,MySql自动增长,UUID
335+
if (field.isAnnotationPresent(SequenceGenerator.class)) {
336+
SequenceGenerator sequenceGenerator = field.getAnnotation(SequenceGenerator.class);
337+
if (sequenceGenerator.sequenceName().equals("")) {
338+
throw new RuntimeException(entityTable.getEntityClass() + "字段" + field.getName() + "的注解@SequenceGenerator未指定sequenceName!");
339+
}
340+
entityColumn.setSequenceName(sequenceGenerator.sequenceName());
341+
} else if (field.isAnnotationPresent(GeneratedValue.class)) {
342+
GeneratedValue generatedValue = field.getAnnotation(GeneratedValue.class);
343+
if (generatedValue.generator().equals("UUID")) {
344+
entityColumn.setUuid(true);
345+
} else if (generatedValue.generator().equals("JDBC")) {
346+
entityColumn.setIdentity(true);
347+
entityColumn.setGenerator("JDBC");
348+
entityTable.setKeyProperties(entityColumn.getProperty());
349+
entityTable.setKeyColumns(entityColumn.getColumn());
350+
} else {
351+
//允许通过generator来设置获取id的sql,例如mysql=CALL IDENTITY(),hsqldb=SELECT SCOPE_IDENTITY()
352+
//允许通过拦截器参数设置公共的generator
353+
if (generatedValue.strategy() == GenerationType.IDENTITY) {
354+
//mysql的自动增长
355+
entityColumn.setIdentity(true);
356+
if (!generatedValue.generator().equals("")) {
357+
String generator = null;
358+
IdentityDialect identityDialect = IdentityDialect.getDatabaseDialect(generatedValue.generator());
359+
if (identityDialect != null) {
360+
generator = identityDialect.getIdentityRetrievalStatement();
361+
} else {
362+
generator = generatedValue.generator();
363+
}
364+
entityColumn.setGenerator(generator);
365+
}
366+
} else {
367+
throw new RuntimeException(field.getName()
368+
+ " - 该字段@GeneratedValue配置只允许以下几种形式:" +
369+
"\n1.全部数据库通用的@GeneratedValue(generator=\"UUID\")" +
370+
"\n2.useGeneratedKeys的@GeneratedValue(generator=\\\"JDBC\\\") " +
371+
"\n3.类似mysql数据库的@GeneratedValue(strategy=GenerationType.IDENTITY[,generator=\"Mysql\"])");
372+
}
373+
}
374+
}
375+
entityTable.getEntityClassColumns().add(entityColumn);
376+
if (entityColumn.isId()) {
377+
entityTable.getEntityClassPKColumns().add(entityColumn);
342378
}
343-
return fieldList;
344379
}
345380
}

0 commit comments

Comments
 (0)