
com.pugwoo.dbhelper.utils.DOInfoReader Maven / Gradle / Ivy
package com.pugwoo.dbhelper.utils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.pugwoo.dbhelper.annotation.Column;
import com.pugwoo.dbhelper.annotation.ExcludeInheritedColumn;
import com.pugwoo.dbhelper.annotation.JoinLeftTable;
import com.pugwoo.dbhelper.annotation.JoinRightTable;
import com.pugwoo.dbhelper.annotation.JoinTable;
import com.pugwoo.dbhelper.annotation.RelatedColumn;
import com.pugwoo.dbhelper.annotation.Table;
import com.pugwoo.dbhelper.exception.NoColumnAnnotationException;
import com.pugwoo.dbhelper.exception.NoJoinTableMemberException;
import com.pugwoo.dbhelper.exception.NoKeyColumnAnnotationException;
import com.pugwoo.dbhelper.exception.NoTableAnnotationException;
import com.pugwoo.dbhelper.exception.NotOnlyOneKeyColumnException;
/**
* 2015年1月12日 16:42:26 读取DO的注解信息:
*
* 1. 继承的类的信息读取,父类先读取,请保证@Column注解没有重复的字段。
*/
public class DOInfoReader {
private static final Logger LOGGER = LoggerFactory.getLogger(DOInfoReader.class);
/**
* 获取DO的@Table信息,如果子类没有,会往父类查找
*
* @param clazz
* @throws NoTableAnnotationException 当clazz没有@Table注解时抛出NoTableAnnotationException
* @return
*/
public static Table getTable(Class> clazz)
throws NoTableAnnotationException {
Class> curClass = clazz;
while (curClass != null) {
Table table = curClass.getAnnotation(Table.class);
if(table != null) {
return table;
}
curClass = curClass.getSuperclass();
}
throw new NoTableAnnotationException("class " + clazz.getName()
+ " does not have @Table annotation.");
}
/**
* 获得clazz上注解的JoinTable,如果没有则返回null
* @param clazz
* @return 如果没有则返回null
*/
public static JoinTable getJoinTable(Class> clazz) {
Class> curClass = clazz;
while (curClass != null) {
JoinTable joinTable = curClass.getAnnotation(JoinTable.class);
if(joinTable != null) {
return joinTable;
}
curClass = curClass.getSuperclass();
}
return null;
}
/**
* 从db字段名拿字段对象
* @param clazz
* @param dbFieldName
* @return 如果不存在返回null
*/
public static Field getFieldByDBField(Class> clazz, String dbFieldName) {
List fields = getColumns(clazz);
for(Field field : fields) {
Column column = field.getAnnotation(Column.class);
if(column.value().equals(dbFieldName)) {
return field;
}
}
return null;
}
/**
* 获得泛型的class
* @param field
* @return
*/
public static Class> getGenericFieldType(Field field) {
ParameterizedType stringListType = (ParameterizedType) field.getGenericType();
Class> clazz = (Class>) stringListType.getActualTypeArguments()[0];
return clazz;
}
/**
* 获得所有有@Column注解的列,包括继承的父类中的,顺序父类先
*
* @param clazz
* @throws NoColumnAnnotationException 当没有一个@Column注解时抛出
* @return 不会返回null
*/
public static List getColumns(Class> clazz)
throws NoColumnAnnotationException {
if(clazz == null) {
throw new NoColumnAnnotationException("class is null");
}
List result = _getAnnotationColumns(clazz, Column.class);
if (result.isEmpty()) {
throw new NoColumnAnnotationException("class " + clazz.getName()
+ " does not have any @Column fields");
}
return result;
}
/**
* 获得所有有@Column注解的列,包括继承的父类中的,顺序父类先。
* 该方法只用于select读操作。
* @param clazz
* @throws NoColumnAnnotationException 当没有一个@Column注解时抛出
* @return 不会返回null
*/
public static List getColumnsForSelect(Class> clazz) {
if(clazz == null) {
throw new NoColumnAnnotationException("class is null");
}
List result = _getFieldsForSelect(clazz);
if (result.isEmpty()) {
throw new NoColumnAnnotationException("class " + clazz.getName()
+ " does not have any @Column fields");
}
return result;
}
/**
* 获得注解了@JoinLeftTable的字段,如果没有注解,抛出NoJoinTableMemberException
* @param clazz
* @return
*/
public static Field getJoinLeftTable(Class> clazz) {
if(clazz == null) {
throw new NoJoinTableMemberException("clazz is null");
}
List result = _getAnnotationColumns(clazz, JoinLeftTable.class);
if(result == null || result.isEmpty()) {
throw new NoJoinTableMemberException("class " + clazz.getName()
+ " does not have @JoinLeftTable field");
}
return result.get(0);
}
/**
* 获得注解了@JoinRightTable的字段,如果没有注解,抛出NoJoinTableMemberException
* @param clazz
* @return
*/
public static Field getJoinRightTable(Class> clazz) {
if(clazz == null) {
throw new NoJoinTableMemberException("clazz is null");
}
List result = _getAnnotationColumns(clazz, JoinRightTable.class);
if(result == null || result.isEmpty()) {
throw new NoJoinTableMemberException("class " + clazz.getName()
+ " does not have @JoinRightTable field");
}
return result.get(0);
}
/**
* 获得字段里面的key字段
* @param clazz
* @return
* @throws NoKeyColumnAnnotationException 如果没有key Column,抛出该异常。
*/
public static List getKeyColumns(Class> clazz)
throws NoKeyColumnAnnotationException {
List fields = getColumns(clazz);
List keyFields = new ArrayList();
for(Field field : fields) {
Column column = field.getAnnotation(Column.class);
if(column.isKey()) {
keyFields.add(field);
}
}
if(keyFields.isEmpty()) {
throw new NoKeyColumnAnnotationException();
}
return keyFields;
}
public static Field getOneKeyColumn(Class> clazz) throws NotOnlyOneKeyColumnException {
List keyFields = DOInfoReader.getKeyColumns(clazz);
if (keyFields.size() != 1) {
throw new NotOnlyOneKeyColumnException(
"must have only one key column, actually has "
+ keyFields.size() + " key columns");
}
return keyFields.get(0);
}
public static Field getAutoIncrementField(Class> clazz) {
List fields = getColumns(clazz);
for(Field field : fields) {
Column column = field.getAnnotation(Column.class);
if(column.isAutoIncrement()) {
return field;
}
}
return null;
}
/**
* 获得软删除标记字段,最多只能返回1个。
* @param clazz
* @return 如果没有则返回null
*/
public static Field getSoftDeleteColumn(Class> clazz) {
List fields = getColumns(clazz);
for(Field field : fields) {
Column column = field.getAnnotation(Column.class);
if(column.softDelete() != null && column.softDelete().length == 2
&& !column.softDelete()[0].trim().isEmpty()
&& !column.softDelete()[1].trim().isEmpty()) {
return field;
}
}
return null;
}
/**
* 获得字段里面的非key字段
* @param clazz
* @return
*/
public static List getNotKeyColumns(Class> clazz) {
List fields = getColumns(clazz);
List keyFields = new ArrayList();
for(Field field : fields) {
Column column = field.getAnnotation(Column.class);
if(!column.isKey()) {
keyFields.add(field);
}
}
return keyFields;
}
/**
* 获得所有有@RelatedColumn注解的列,包括继承的父类中的,顺序父类先
*
* @param clazz
* @return 不会返回null
*/
public static List getRelatedColumns(Class> clazz) {
if(clazz == null) {
return new ArrayList();
}
List> classLink = new ArrayList>();
Class> curClass = clazz;
while (curClass != null) {
classLink.add(curClass);
curClass = curClass.getSuperclass();
}
// 父类优先
List result = new ArrayList();
for (int i = classLink.size() - 1; i >= 0; i--) {
Field[] fields = classLink.get(i).getDeclaredFields();
for (Field field : fields) {
if (field.getAnnotation(RelatedColumn.class) != null) {
result.add(field);
}
}
}
return result;
}
/**
* 优先通过getter获得值,如果没有getter,则直接获取
*
* @param field
* @param object
* @return
*/
public static Object getValue(Field field, Object object) {
String fieldName = field.getName();
String setMethodName = "get" + firstLetterUpperCase(fieldName);
Method method = null;
try {
method = object.getClass().getMethod(setMethodName);
} catch (Exception e) {
}
if(method != null) {
try {
return method.invoke(object);
} catch (Exception e) {
LOGGER.error("method invoke", e);
}
}
field.setAccessible(true);
try {
return field.get(object);
} catch (Exception e) {
LOGGER.error("method invoke", e);
return null;
}
}
/**
* 先按照setter的约定寻找setter方法(必须严格匹配参数类型或自动转换)
* 如果有则按setter方法,如果没有则直接写入
*
* @param field
* @param object
* @param value
*/
public static boolean setValue(Field field, Object object, Object value) {
String fieldName = field.getName();
String setMethodName = "set" + firstLetterUpperCase(fieldName);
value = TypeAutoCast.cast(value, field.getType());
Method method = null;
try {
method = object.getClass().getMethod(setMethodName, value.getClass());
} catch (Exception e) {
}
if(method != null) {
try {
method.invoke(object, value);
} catch (Exception e) {
LOGGER.error("method invoke", e);
return false;
}
} else {
field.setAccessible(true);
try {
field.set(object, value);
} catch (Exception e) {
LOGGER.error("method invoke", e);
return false;
}
}
return true;
}
private static List _getFieldsForSelect(Class> clazz) {
if(clazz == null) {
return new ArrayList();
}
List> classLink = new ArrayList>();
Class> curClass = clazz;
while (curClass != null) {
classLink.add(curClass);
ExcludeInheritedColumn eic = curClass.getAnnotation(ExcludeInheritedColumn.class);
if(eic != null) {
break;
}
curClass = curClass.getSuperclass();
}
return _getFields(classLink, Column.class);
}
/**
* 获得clazz类的有annotationClazz注解的字段field(包括clazz类及其父类,父类优先,不处理重名)。
* @param clazz
* @param annoClazz
* @return
*/
private static List _getAnnotationColumns(Class> clazz,
Class extends Annotation> annoClazz) {
if(clazz == null) {
return new ArrayList();
}
List> classLink = new ArrayList>();
Class> curClass = clazz;
while (curClass != null) {
classLink.add(curClass);
curClass = curClass.getSuperclass();
}
return _getFields(classLink, annoClazz);
}
private static List _getFields(List> classLink,
Class extends Annotation> annoClazz) {
List result = new ArrayList();
if(classLink == null || classLink.isEmpty()) {
return result;
}
// 父类先拿,不处理重名情况
for (int i = classLink.size() - 1; i >= 0; i--) {
Field[] fields = classLink.get(i).getDeclaredFields();
for (Field field : fields) {
if (annoClazz != null && field.getAnnotation(annoClazz) != null) {
result.add(field);
}
}
}
return result;
}
private static String firstLetterUpperCase(String str) {
if (str == null || str.length() < 2) {
return str;
}
String firstLetter = str.substring(0, 1).toUpperCase();
return firstLetter + str.substring(1, str.length());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy