Skip to content

Commit 1269dc8

Browse files
committed
3.3.1更新
1 parent e12be21 commit 1269dc8

File tree

11 files changed

+380
-76
lines changed

11 files changed

+380
-76
lines changed

README.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,42 @@ http://repo1.maven.org/maven2/javax/persistence/persistence-api/1.0/
110110

111111
##Maven坐标以及下载地址
112112

113-
###最新版本3.3.0 - 2015-11-01
113+
###最新版本3.3.1 - 2015-12-06
114+
115+
- 增加`enableMethodAnnotation`参数,可以控制是否支持方法上的JPA注解,默认`false`
116+
设置`enableMethodAnnotation = true`的时候注意,如`getRealName``setYourName`都会产生`realName`属性或`yourName`属性,如果该方法对应的属性不是表中的字段,就需要给方法增加`@Transient`注解。
117+
同样如果你的实体是继承`Map`类型的,你不需要在实体中写`private String userName`这样的属性,你只需要写`setUserName``getUserName`这样的方法就可以。
118+
- 在处理的注解的时候,优先从`Field`获取,然后是`setter`方法,最后是`getter`方法,注解重复的情况下,只获取按顺序得到的第一个
119+
- 为了支持如`public class Country extends Entity<Integer, String>`这样的泛型类型,在生成`#{propertyName}`的时候都带上了`javaType`属性。
120+
产生的结果就是`#{propertyName, javaType=java.lang.Integer}`这样子的,这会导致当你调用方法时,必须保证类型一致。
121+
也就是假设主键是`Integer id`,调用`selectByPrimaryKey(Object id)`的时候,参数`id`必须使用`100`这样的数字,不能使用`"100"`字符串(以前版本可以)。
122+
如果不带`javaType`,那么如果`id`是个泛型,MyBatis查找的时候就会因为找不到正确的类型而抛出异常。
123+
- 为了让扩展更方便,将`tk.mybatis.mapper.provider`包下所有的通用接口的实现方法改为了`String`形式。
124+
例如`selectByPrimaryKey`方法:
125+
```java
126+
/**
127+
* 根据主键进行查询
128+
*
129+
* @param ms
130+
*/
131+
public String selectByPrimaryKey(MappedStatement ms) {
132+
final Class<?> entityClass = getEntityClass(ms);
133+
//将返回值修改为实体类型,只有select返回实体类型的需要修改返回值,其他如insert,update,delete都是返回int,不需要修改
134+
setResultType(ms, entityClass);
135+
StringBuilder sql = new StringBuilder();
136+
sql.append("select ");
137+
sql.append(EntityHelper.getSelectColumns(entityClass));
138+
sql.append(" from ");
139+
sql.append(SqlHelper.getDynamicTableName(entityClass, tableName(entityClass)));
140+
sql.append(" where ");
141+
sql.append(EntityHelper.getPrimaryKeyWhere(entityClass));
142+
return sql.toString();
143+
}
144+
```
145+
自己扩展单表操作的方法是非常容易的事情,建议有一定通用Mapper使用基础的自行扩展,扩展可以参考[如何扩展通用接口](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/6.MyMapper.md)
146+
147+
148+
###3.3.0 - 2015-11-01
114149

115150
- 增加对动态表名的支持,需要实体类继承`IDynamicTableName`接口,用法见[详细说明](http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/3.2.Use330.md)
116151

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>tk.mybatis</groupId>
66
<artifactId>mapper</artifactId>
7-
<version>3.3.0</version>
7+
<version>3.3.1-SNAPSHOT</version>
88
<packaging>jar</packaging>
99

1010
<name>mapper</name>

src/main/java/tk/mybatis/mapper/entity/Config.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public class Config {
1818
private String seqFormat;
1919
private String catalog;
2020
private String schema;
21+
/**
22+
* 是否支持方法上的注解,默认false
23+
*/
24+
private boolean enableMethodAnnotation;
2125
/**
2226
* 对于一般的getAllIfColumnNode,是否判断!='',默认不判断
2327
*/
@@ -165,6 +169,14 @@ public void setStyle(Style style) {
165169
this.style = style;
166170
}
167171

172+
public boolean isEnableMethodAnnotation() {
173+
return enableMethodAnnotation;
174+
}
175+
176+
public void setEnableMethodAnnotation(boolean enableMethodAnnotation) {
177+
this.enableMethodAnnotation = enableMethodAnnotation;
178+
}
179+
168180
/**
169181
* 获取表前缀,带catalog或schema
170182
*
@@ -219,6 +231,10 @@ public void setProperties(Properties properties) {
219231
if (StringUtil.isNotEmpty(notEmpty)) {
220232
this.notEmpty = notEmpty.equalsIgnoreCase("TRUE");
221233
}
234+
String enableMethodAnnotation = properties.getProperty("enableMethodAnnotation");
235+
if (StringUtil.isNotEmpty(enableMethodAnnotation)) {
236+
this.enableMethodAnnotation = enableMethodAnnotation.equalsIgnoreCase("TRUE");
237+
}
222238
String styleStr = properties.getProperty("style");
223239
if (StringUtil.isNotEmpty(styleStr)) {
224240
try {
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
package tk.mybatis.mapper.entity;
2+
3+
import java.beans.PropertyDescriptor;
4+
import java.lang.annotation.Annotation;
5+
import java.lang.reflect.Field;
6+
import java.lang.reflect.Method;
7+
8+
/**
9+
* 封装字段和方法,统一调用某些方法
10+
*
11+
* @author liuzh
12+
*/
13+
public class EntityField {
14+
private String name;
15+
private Field field;
16+
private Class<?> javaType;
17+
private Method setter;
18+
private Method getter;
19+
20+
/**
21+
* 构造方法
22+
*
23+
* @param field 字段
24+
* @param propertyDescriptor 字段name对应的property
25+
*/
26+
public EntityField(Field field, PropertyDescriptor propertyDescriptor) {
27+
if (field != null) {
28+
this.field = field;
29+
this.name = field.getName();
30+
this.javaType = field.getType();
31+
}
32+
if (propertyDescriptor != null) {
33+
this.name = propertyDescriptor.getName();
34+
this.setter = propertyDescriptor.getWriteMethod();
35+
this.getter = propertyDescriptor.getReadMethod();
36+
this.javaType = propertyDescriptor.getPropertyType();
37+
}
38+
}
39+
40+
/**
41+
* 先创建field,然后可以通过该方法获取property等属性
42+
*
43+
* @param other
44+
*/
45+
public void copyFromPropertyDescriptor(EntityField other) {
46+
this.setter = other.setter;
47+
this.getter = other.getter;
48+
this.javaType = other.javaType;
49+
this.name = other.name;
50+
}
51+
52+
/**
53+
* 是否有该注解
54+
*
55+
* @param annotationClass
56+
* @return
57+
*/
58+
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
59+
boolean result = false;
60+
if (field != null) {
61+
result = field.isAnnotationPresent(annotationClass);
62+
}
63+
if (!result && setter != null) {
64+
result = setter.isAnnotationPresent(annotationClass);
65+
}
66+
if (!result && getter != null) {
67+
result = getter.isAnnotationPresent(annotationClass);
68+
}
69+
return result;
70+
}
71+
72+
/**
73+
* 获取指定的注解
74+
*
75+
* @param annotationClass
76+
* @param <T>
77+
* @return
78+
*/
79+
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
80+
T result = null;
81+
if (field != null) {
82+
result = field.getAnnotation(annotationClass);
83+
}
84+
if (result == null && setter != null) {
85+
result = setter.getAnnotation(annotationClass);
86+
}
87+
if (result == null && getter != null) {
88+
result = getter.getAnnotation(annotationClass);
89+
}
90+
return result;
91+
}
92+
93+
/**
94+
* 字段属性名
95+
*
96+
* @return
97+
*/
98+
public String getName() {
99+
return name;
100+
}
101+
102+
/**
103+
* 获取javaType
104+
*
105+
* @return
106+
*/
107+
public Class<?> getJavaType() {
108+
return javaType;
109+
}
110+
111+
/**
112+
* 设置javaType
113+
*
114+
* @param javaType
115+
*/
116+
public void setJavaType(Class<?> javaType) {
117+
this.javaType = javaType;
118+
}
119+
120+
@Override
121+
public boolean equals(Object o) {
122+
if (this == o) return true;
123+
if (o == null || getClass() != o.getClass()) return false;
124+
125+
EntityField that = (EntityField) o;
126+
127+
return !(name != null ? !name.equals(that.name) : that.name != null);
128+
129+
}
130+
131+
@Override
132+
public int hashCode() {
133+
return name != null ? name.hashCode() : 0;
134+
}
135+
}

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

Lines changed: 15 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@
3232
import tk.mybatis.mapper.code.Style;
3333
import tk.mybatis.mapper.entity.Config;
3434
import tk.mybatis.mapper.entity.EntityColumn;
35+
import tk.mybatis.mapper.entity.EntityField;
3536
import tk.mybatis.mapper.entity.EntityTable;
3637
import tk.mybatis.mapper.util.StringUtil;
3738

3839
import javax.persistence.*;
39-
import java.lang.reflect.*;
4040
import java.util.*;
4141

4242
/**
@@ -184,23 +184,12 @@ public static synchronized void initEntityNameMap(Class<?> entityClass, Config c
184184
}
185185
Style style = config.getStyle();
186186
//style,该注解优先于全局配置
187-
if(entityClass.isAnnotationPresent(NameStyle.class)){
187+
if (entityClass.isAnnotationPresent(NameStyle.class)) {
188188
NameStyle nameStyle = entityClass.getAnnotation(NameStyle.class);
189189
style = nameStyle.value();
190190
}
191-
//创建并缓存EntityTable
192-
entityTableMap.put(entityClass, newEntityTable(entityClass, style));
193-
}
194191

195-
/**
196-
* 新建EntityTable
197-
*
198-
* @param entityClass
199-
* @param style
200-
* @return
201-
*/
202-
private static EntityTable newEntityTable(Class<?> entityClass, Style style) {
203-
//表名
192+
//创建并缓存EntityTable
204193
EntityTable entityTable = null;
205194
if (entityClass.isAnnotationPresent(Table.class)) {
206195
Table table = entityClass.getAnnotation(Table.class);
@@ -217,56 +206,20 @@ private static EntityTable newEntityTable(Class<?> entityClass, Style style) {
217206
entityTable.setEntityClassColumns(new LinkedHashSet<EntityColumn>());
218207
entityTable.setEntityClassPKColumns(new LinkedHashSet<EntityColumn>());
219208
//处理所有列
220-
processAllColumns(entityTable, style, null, null);
209+
List<EntityField> fields = null;
210+
if (config.isEnableMethodAnnotation()) {
211+
fields = FieldHelper.getAll(entityClass);
212+
} else {
213+
fields = FieldHelper.getFields(entityClass);
214+
}
215+
for (EntityField field : fields) {
216+
processField(entityTable, style, field);
217+
}
221218
//当pk.size=0的时候使用所有列作为主键
222219
if (entityTable.getEntityClassPKColumns().size() == 0) {
223220
entityTable.setEntityClassPKColumns(entityTable.getEntityClassColumns());
224221
}
225-
return entityTable;
226-
}
227-
228-
/**
229-
* 处理所有列
230-
*
231-
* @param entityTable
232-
* @param style
233-
* @param entityClass
234-
* @param genericMap 处理泛型字段
235-
*/
236-
private static void processAllColumns(EntityTable entityTable, Style style, Class<?> entityClass, Map<String, Class<?>> genericMap) {
237-
if (entityClass == null) {
238-
entityClass = entityTable.getEntityClass();
239-
}
240-
if (entityClass.equals(Object.class)) {
241-
return;
242-
}
243-
Field[] fields = entityClass.getDeclaredFields();
244-
for (Field field : fields) {
245-
//排除静态字段,解决bug#2
246-
if (!Modifier.isStatic(field.getModifiers())) {
247-
//处理field
248-
processField(entityTable, style, field, genericMap);
249-
}
250-
}
251-
Class<?> superClass = entityClass.getSuperclass();
252-
if (superClass != null
253-
&& !superClass.equals(Object.class)
254-
&& (superClass.isAnnotationPresent(Entity.class)
255-
|| (!Map.class.isAssignableFrom(superClass)
256-
&& !Collection.class.isAssignableFrom(superClass)))) {
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-
}
222+
entityTableMap.put(entityClass, entityTable);
270223
}
271224

272225
/**
@@ -275,9 +228,8 @@ private static void processAllColumns(EntityTable entityTable, Style style, Clas
275228
* @param entityTable
276229
* @param style
277230
* @param field
278-
* @param genericMap
279231
*/
280-
private static void processField(EntityTable entityTable, Style style, Field field, Map<String, Class<?>> genericMap) {
232+
private static void processField(EntityTable entityTable, Style style, EntityField field) {
281233
//排除字段
282234
if (field.isAnnotationPresent(Transient.class)) {
283235
return;
@@ -313,15 +265,7 @@ private static void processField(EntityTable entityTable, Style style, Field fie
313265
}
314266
entityColumn.setProperty(field.getName());
315267
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-
}
268+
entityColumn.setJavaType(field.getJavaType());
325269
//OrderBy
326270
if (field.isAnnotationPresent(OrderBy.class)) {
327271
OrderBy orderBy = field.getAnnotation(OrderBy.class);

0 commit comments

Comments
 (0)