MyBatis封装简单的CRUD

jopen 6年前

MyBatis封装简单的CRUD

1)公共的Dao接口

import java.io.Serializable;  import java.util.List;    public interface IBaseDao<T extends BaseDO<T>, PK extends Serializable> {            /**       * 新增(不会将序列生成的ID,注入)       * 效率较save(T t)高       * @param t       */      void create(T t);            /**       * 批量新增(不会将序列生成的ID,注入)       * 效率较saveOfBatch(List<T> tList)高       * @param tList       */      void createOfBatch(List<T> tList);            /**       * 新增(会将序列生成的ID,注入)       * @param t       */      void save(T t);            /**       * 批量新增(会将序列生成的ID,注入)       * @param tList       */      void saveOfBatch(List<T> tList);            /**       * 根据ID进行删除       * @param id       */      void removeById(PK id);            /**       * 根据ids进行批量删除       * @param ids       */      void removeOfBatch(List<PK> ids);                  void removeAll();            /**       * 更新,字段为空,则不进行更新       * @param t       */      void modify(T t);            /**       * 批量更新       * @param tList       */      void modifyOfBatch(List<T> tList);            /**       * 根据ID获取对象       * @param id       * @return       */      T findOneById(PK id);            /**       * 获取所有的对象       * @return       */      List<T> findAll();            /**       * 获取记录数       * @return       */      Long findAllCount();        }

2)公共的Dao接口实现类

import java.io.Serializable;  import java.lang.reflect.Field;  import java.util.ArrayList;  import java.util.HashMap;  import java.util.LinkedHashMap;  import java.util.List;  import java.util.Map;    import javax.annotation.Resource;    import org.apache.commons.lang.StringUtils;  import org.mybatis.spring.SqlSessionTemplate;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import org.springframework.stereotype.Repository;    import com.msd.ass.commons.util.GenericsUtils;  import com.msd.ass.commons.util.ReflectionUtils;  import com.msd.ass.core.anno.base.Ignore;  import com.msd.ass.core.anno.base.PrimaryKey;  import com.msd.ass.core.anno.base.Table;  import com.msd.ass.core.anno.base.TableColumn;  import com.msd.ass.core.constant.AssConstant;    @Repository("BaseDao")  public abstract class BaseDao<T extends BaseDO<T>, PK extends Serializable>          implements IBaseDao<T, PK> {            protected Logger                                        logger            = LoggerFactory                                                                                      .getLogger(this                                                                                              .getClass());            @Resource(name = "sqlSessionTemplateASS")      public SqlSessionTemplate                                sqlSessionTemplateASS;            private Class<T>                                        entityClass;      //实体类主键名称      private String                                            pkName;      //实体类ID字段名称      private String                                             idName;      //主键的序列      private String                                             seq;      private String                                            tableName;      /**       * 作cache 结构{T类的镜像,{数据库列名,实体字段名}}       */      private static final Map<Class<?>, Map<String, String>>    classFieldMap    = new HashMap<Class<?>, Map<String, String>>();      private Map<String, String>                                currentColumnFieldNames;            private SQLGenerator<T>                                    sqlGenerator;            /**       *        */      @SuppressWarnings("unchecked")      public BaseDao() {          super();          this.entityClass = (Class<T>) GenericsUtils                  .getSuperClassGenricType(this.getClass());                    currentColumnFieldNames = classFieldMap.get(entityClass);          if (null == currentColumnFieldNames) {              currentColumnFieldNames = new LinkedHashMap<String, String>();              classFieldMap.put(entityClass, currentColumnFieldNames);          }                    // 作cache          Field[] fields = this.entityClass.getDeclaredFields();                    String fieldName = null;          String columnName = null;          for (Field field : fields) {              if (field.isAnnotationPresent(Ignore.class)) {                  continue;              }              fieldName = field.getName();              TableColumn tableColumn = field.getAnnotation(TableColumn.class);              if (null != tableColumn) {                  columnName = tableColumn.value();              } else {                  columnName = null;              }              // 如果未标识特殊的列名,默认取字段名              columnName = (StringUtils.isEmpty(columnName) ? StringUtils                      .upperCase(fieldName) : columnName);              currentColumnFieldNames.put(columnName, fieldName);              if (field.isAnnotationPresent(PrimaryKey.class)) {                  // 取得ID的列名                  idName = fieldName;                  pkName = columnName;                  PrimaryKey primaryKey = field.getAnnotation(PrimaryKey.class);                  seq = primaryKey.seq();              }          }                    Table table = this.entityClass.getAnnotation(Table.class);          if (null == table) { throw new RuntimeException("类-"                  + this.entityClass + ",未用@Table注解标识!!"); }          tableName = table.value();                    sqlGenerator = new SQLGenerator<T>(currentColumnFieldNames.keySet(),                  tableName,pkName,seq);      }            @Override      public void create(T t) {          sqlSessionTemplateASS.insert("create",                  sqlGenerator.sql_create(t, currentColumnFieldNames));      }            @Override      public void createOfBatch(List<T> tList) {          if(null == tList || tList.isEmpty()){              return;          }          int len = tList.size(), i = 0;          List<T> temp = new ArrayList<T>();          //获取列表的第一个对象的pk的value          Object pkVal = null;          for (; i < len; i++) {              T t = tList.get(i);              if(i==0){                  pkVal = ReflectionUtils.invokeGetterMethod(t, idName);              }                            temp.add(t);              if (i > 0 && i % AssConstant.FLUSH_CRITICAL_VAL == 0) {                  sqlSessionTemplateASS.insert("createOfBatch", sqlGenerator                          .sql_createOfBatch(temp, currentColumnFieldNames,pkVal));                  sqlSessionTemplateASS.flushStatements();                  temp = new ArrayList<T>();              }          }          sqlSessionTemplateASS.insert("createOfBatch", sqlGenerator                  .sql_createOfBatch(temp, currentColumnFieldNames,pkVal));      }                  @Override      public void save(T t) {          if(StringUtils.isEmpty(seq)){              this.create(t);          }          logger.info("生成序列开始:----------start----------");          Long nextval = sqlSessionTemplateASS.selectOne("fetchSeqNextval","SELECT ".concat(seq).concat(" FROM DUAL"));          ReflectionUtils.invokeSetterMethod(t, idName, nextval);          logger.info("生成序列结束:---------- end ----------");                    this.create(t);      }        @Override      public void saveOfBatch(List<T> tList) {          if(null == tList || tList.isEmpty()){              return;          }          if(StringUtils.isEmpty(seq)){              this.createOfBatch(tList);          }          logger.info("生成序列开始:----------start----------");          for(T t : tList){              Long nextval = sqlSessionTemplateASS.selectOne("fetchSeqNextval","SELECT ".concat(seq).concat(" FROM DUAL"));              ReflectionUtils.invokeSetterMethod(t, idName, nextval);          }          logger.info("生成序列结束:---------- end ----------");                    this.createOfBatch(tList);      }        @Override      public void removeById(PK id) {          sqlSessionTemplateASS.delete("removeById",                  sqlGenerator.sql_removeById(id));      }            @Override      public void removeOfBatch(List<PK> ids) {          if(null == ids || ids.isEmpty()){              return;          }          int len = ids.size(), i = 0;          List<PK> temp = new ArrayList<PK>();          for (; i < len; i++) {              temp.add(ids.get(i));              if (i > 0 && i % AssConstant.FLUSH_CRITICAL_VAL == 0) {                  sqlSessionTemplateASS.delete("removeOfBatch",                          sqlGenerator.sql_removeOfBatch(temp));                  sqlSessionTemplateASS.flushStatements();                  temp = new ArrayList<PK>();              }          }          sqlSessionTemplateASS.delete("removeOfBatch",                  sqlGenerator.sql_removeOfBatch(temp));      }            @Override      public void removeAll(){          sqlSessionTemplateASS.delete("removeAll",                  sqlGenerator.sql_removeAll());      }                  @Override      public void modify(T t) {          sqlSessionTemplateASS.update("modify",                  sqlGenerator.sql_modify(t, currentColumnFieldNames));                }            @Override      public void modifyOfBatch(List<T> tList) {          if(null == tList || tList.isEmpty()){              return;          }          int len = tList.size(),i=0;          for(;i<len;i++){              this.modify(tList.get(i));              if (i > 0 && i % AssConstant.FLUSH_CRITICAL_VAL == 0) {                  sqlSessionTemplateASS.flushStatements();              }          }      }            @Override      public T findOneById(PK id) {          Map<String, Object> resultMap = sqlSessionTemplateASS.selectOne(                  "findOneById", sqlGenerator.sql_findOneById(id));                    return handleResult(resultMap, this.entityClass);      }            @Override      public List<T> findAll() {          List<Map<String, Object>> resultMapList = sqlSessionTemplateASS                  .selectList("findAll", sqlGenerator.sql_findAll());          List<T> tList = new ArrayList<T>(resultMapList.size());          for (Map<String, Object> resultMap : resultMapList) {              T t = handleResult(resultMap, this.entityClass);              tList.add(t);          }          return tList;      }            @Override      public Long findAllCount() {          Long count = sqlSessionTemplateASS                  .selectOne("findAllCount", sqlGenerator.sql_findAllCount());          return count;      }            private T handleResult(Map<String, Object> resultMap, Class<T> tClazz) {          T t = null;          try {              t = tClazz.newInstance();          } catch (InstantiationException e) {              logger.error("/********************************");              logger.error("封装查询结果时,实例化对象(" + this.entityClass + ")时,出现异常!"                      + e.getMessage());              logger.error("/********************************");          } catch (IllegalAccessException e) {              logger.error("/********************************");              logger.error("封装查询结果时,实例化对象(" + this.entityClass + ")时,出现异常!"                      + e.getMessage());              logger.error("/********************************");          }          for (Map.Entry<String, Object> entry : resultMap.entrySet()) {              String key = entry.getKey();              key = currentColumnFieldNames.get(key);              Object val = entry.getValue();              ReflectionUtils.invokeSetterMethod(t, key, val);          }          return t;      }        }

3)xml配置

<?xml version="1.0" encoding="UTF-8"?>  <!DOCTYPE mapper         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">    <mapper namespace="com.szy.ass.core.base.BaseDao">      <!-- 新增 -->      <insert id="create">          ${value}      </insert>        <!-- 批量新增 -->      <insert id="createOfBatch">          ${value}      </insert>        <!-- 根据ID删除 -->      <delete id="removeById">          ${value}      </delete>        <!-- 批量删除 -->      <delete id="removeOfBatch">          ${value}      </delete>        <!-- 批量删除 -->      <delete id="removeAll">          ${value}      </delete>        <!-- 更新 -->      <update id="modify">${value}</update>            <!-- 根据ID查询单个 -->      <select id="findOneById" resultType="hashmap">          ${value}      </select>        <!-- 查询所有 -->      <select id="findAll" resultType="hashmap">          ${value}      </select>        <!-- 查询总数量 -->      <select id="findAllCount" resultType="Long">          ${value}      </select>            <!-- 获取下一个序列的值 -->      <select id="fetchSeqNextval" resultType="Long" flushCache="true">          ${value}      </select>  </mapper>

4)两个工具类

4.1)生成SQL的工具类

import java.util.Date;  import java.util.LinkedList;  import java.util.List;  import java.util.Map;  import java.util.Set;    import org.apache.commons.lang.StringUtils;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;    import com.msd.ass.commons.util.DateUtil;  import com.msd.ass.commons.util.ReflectionUtils;  import com.msd.ass.core.constant.AssConstant;    /**   * Description: 生成查询数量的SQL   */  public class SQLGenerator<T> {            protected Logger    logger    = LoggerFactory.getLogger(this.getClass());      private Set<String>    columns;      private String        tableName;      private String        columnsStr;      private String        pkName;      private String        seq;            public SQLGenerator(Set<String> columns, String tableName, String pkName,              String seq) {          super();          this.columns = columns;          this.tableName = tableName;          this.pkName = pkName;          this.seq = seq;          this.columnsStr = StringUtils.join(this.columns, ",");      }            /**       * 生成新增的SQL       *        * @param t       * @param currentColumnFieldNames       * @return       */      public String sql_create(T t, Map<String, String> currentColumnFieldNames) {          List<Object> values = obtainFieldValues(t, currentColumnFieldNames);                    StringBuilder sql_build = new StringBuilder();          sql_build.append("INSERT INTO ").append(tableName).append("(")                  .append(columnsStr).append(")values(")                  .append(StringUtils.join(values, ",")).append(")");          String sql = sql_build.toString();                    logger.debug("生成的SQL为: " + sql);                    return sql;      }            /**       * 生成批量新增的SQL       *        * @param tList       * @param currentColumnFieldNames       * @return       */      public String sql_createOfBatch(List<T> tList,              Map<String, String> currentColumnFieldNames,Object pkVal) {          StringBuilder sql_build = new StringBuilder();          int len = tList.size(),i=0;                    if(StringUtils.isNotEmpty(seq) && null == pkVal){              // ID使用序列              sql_build.append("INSERT INTO ").append(tableName).append("(")                      .append(columnsStr).append(")");              sql_build.append(" SELECT ").append(seq).append(" , a.* FROM ( ");              for (; i < len; i++) {                  T t = tList.get(i);                  List<Object> values = obtainFieldValues(t,                          currentColumnFieldNames);                  values.remove(seq);                                    if (i == 0) {                      sql_build.append(" SELECT ");                  } else {                      sql_build.append(" UNION ALL SELECT ");                  }                  int j = 0, vlen = values.size();                  for (; j < vlen; j++) {                      sql_build.append(values.get(j)).append(" AS T").append(j);                      if (j != (vlen - 1)) {                          sql_build.append(",");                      }                  }                  sql_build.append(" FROM DUAL ");              }              sql_build.append(" ) a ");          } else {              //ID没有使用序列              sql_build.append("INSERT INTO ").append(tableName).append("(")                      .append(columnsStr).append(")");              for (; i < len; i++) {                  T t = tList.get(i);                  List<Object> values = obtainFieldValues(t, currentColumnFieldNames);                                    if (i == 0) {                      sql_build.append(" SELECT ");                  } else {                      sql_build.append(" UNION ALL SELECT ");                  }                  sql_build.append(StringUtils.join(values, ",")).append(                          " FROM DUAL ");              }          }                    String sql = sql_build.toString();                    logger.debug("生成的SQL为: " + sql);                    return sql;      }            /**       * 提供给生成新增SQL 使用       *        * @param t       * @param currentColumnFieldNames       * @return       */      private List<Object> obtainFieldValues(T t,              Map<String, String> currentColumnFieldNames) {          List<Object> values = new LinkedList<Object>();          for (String column : columns) {              Object value = ReflectionUtils.obtainFieldValue(t,                      currentColumnFieldNames.get(column));              if(StringUtils.equalsIgnoreCase(column, pkName) &&  null == value){                  value = seq;              }else{                  value = handleValue(value);              }              values.add(value);          }          return values;      }            /**       * 处理value       *        * @param value       * @return       */      private Object handleValue(Object value) {          if (value instanceof String) {              value = "\'" + value + "\'";          } else if (value instanceof Date) {              Date date = (Date) value;              String dateStr = DateUtil.convertDateToString(date,                      DateUtil.FULL_TIME_FORMAT);              value = "TO_TIMESTAMP('" + dateStr                      + "','YYYY-MM-DD HH24:MI:SS.FF3')";          } else if (value instanceof Boolean) {              Boolean v = (Boolean) value;              value = v ? 1 : 0;          }else if(null == value || StringUtils.isBlank(value.toString())){              value = "''";          }          return value;      }            /**       * 生成根据ID删除的SQL       *        * @param id       * @return       */      public <PK> String sql_removeById(PK id) {          StringBuilder sql_build = new StringBuilder();          sql_build.append("DELETE FROM ").append(this.tableName)                  .append(" WHERE ").append(pkName).append(" = ").append(id);                    String sql = sql_build.toString();                    logger.debug("生成的SQL为: " + sql);                    return sql;      }            /**       * 生成根据IDs批量删除的SQL       *        * @param ids       * @return       */      public <PK> String sql_removeOfBatch(List<PK> ids) {          StringBuilder sql_build = new StringBuilder();          sql_build.append("DELETE FROM ").append(this.tableName)                  .append(" WHERE ").append(pkName).append(" IN ( 0 ");          int len = ids.size(), i = 0;          for (; i < len; i++) {              PK id = ids.get(i);              sql_build.append(",").append(id);              if (i > 0 && i % (AssConstant.DELETE_CRITICAL_VAL - 1) == 0) {                  sql_build.append(")").append(" OR ").append(pkName)                          .append(" IN ( 0 ");              }          }          sql_build.append(")");                    String sql = sql_build.toString();                    logger.debug("生成的SQL为: " + sql);                    return sql;      }                  public String sql_removeAll() {          StringBuilder sql_build = new StringBuilder();          sql_build.append("DELETE FROM ").append(this.tableName);          String sql = sql_build.toString();          logger.debug("生成的SQL为: " + sql);          return sql;      }            /**       * 生成更新的SQL       *        * @param t       * @param currentColumnFieldNames       * @return       */      public String sql_modify(T t, Map<String, String> currentColumnFieldNames) {          List<String> values = obtainColumnVals(t, currentColumnFieldNames);          Object id = ReflectionUtils.obtainFieldValue(t,                  currentColumnFieldNames.get(pkName));          id = handleValue(id);                    StringBuilder sql_build = new StringBuilder();          sql_build.append("UPDATE ").append(tableName).append(" SET ")                  .append(StringUtils.join(values, ",")).append(" WHERE ")                  .append(pkName).append(" = ").append(id);                    String sql = sql_build.toString();                    logger.debug("生成的SQL为: " + sql);                    return sql;      }            /**       * 提供给生成更新SQL使用       *        * @param t       * @param currentColumnFieldNames       * @return       */      private List<String> obtainColumnVals(T t,              Map<String, String> currentColumnFieldNames) {          List<String> colVals = new LinkedList<String>();          for (String column : columns) {              Object value = ReflectionUtils.obtainFieldValue(t,                      currentColumnFieldNames.get(column));              if (value != null && !StringUtils.equalsIgnoreCase(column, pkName)) {                  colVals.add(column + "=" + handleValue(value));              }          }          return colVals;      }            /**       * 生成根据ID查询的SQL       *        * @param id       * @return       */      public <PK> String sql_findOneById(PK id) {          StringBuilder sql_build = new StringBuilder();          sql_build.append("SELECT ").append(columnsStr).append(" FROM ")                  .append(this.tableName)                  .append(" WHERE ROWNUM = 1 AND " + pkName + " = " + id);                    String sql = sql_build.toString();                    logger.debug("生成的SQL为: " + sql);                    return sql;                }            /**       * 生成查询所有的SQL       *        * @return       */      public String sql_findAll() {          StringBuilder sql_build = new StringBuilder();          sql_build.append("SELECT ").append(columnsStr).append(" FROM ")                  .append(this.tableName);          String sql = sql_build.toString();                    logger.debug("生成的SQL为: " + sql);                    return sql;      }            /**       * 生成查询数量的SQL       *        * @return       */      public String sql_findAllCount() {          StringBuilder sql_build = new StringBuilder();          sql_build.append("SELECT COUNT(1) ").append(" FROM ")                  .append(this.tableName);          String sql = sql_build.toString();                    logger.debug("生成的SQL为: " + sql);                    return sql;      }        }

4.1)反射的工具类

import java.lang.reflect.Field;  import java.lang.reflect.InvocationTargetException;  import java.lang.reflect.Method;  import java.math.BigDecimal;  import java.math.BigInteger;  import java.sql.Timestamp;  import java.text.ParseException;  import java.util.Date;  import java.util.HashMap;  import java.util.Map;    import org.apache.commons.lang.StringUtils;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;    /**   * Description:反射工具类   */  public abstract class ReflectionUtils {            private static final Logger    logger    = LoggerFactory              .getLogger(ReflectionUtils.class);      /**       * 缓存方法       */      private static final Map<Class<?>, Method[]>    METHODS_CACHEMAP    = new HashMap<Class<?>, Method[]>();            /**       * 反射 取值、设值,合并两个对象(Field same only )       *        * @param from       * @param to       */      public static <T> void copyProperties(T fromobj, T toobj,              String... fieldspec) {          for (String filename : fieldspec) {              Object val = ReflectionUtils.invokeGetterMethod(fromobj, filename);              ReflectionUtils.invokeSetterMethod(toobj, filename, val);          }                }            /**       * 调用Getter方法       *        * @param obj       *            对象       * @param propertyName       *            属性名       * @return       */      public static Object invokeGetterMethod(Object obj, String propertyName) {          String getterMethodName = "get" + StringUtils.capitalize(propertyName);          return invokeMethod(obj, getterMethodName, null, null);      }            /**       * 调用Setter方法,不指定参数的类型       *        * @param obj       * @param propertyName       * @param value       */      public static void invokeSetterMethod(Object obj, String propertyName,              Object value) {          invokeSetterMethod(obj, propertyName, value, null);      }            /**       * 调用Setter方法,指定参数的类型       *        * @param obj       * @param propertyName  字段名       * @param value       * @param propertyType       *            为空,则取value的Class       */      public static void invokeSetterMethod(Object obj, String propertyName,              Object value, Class<?> propertyType) {          value = handleValueType(obj,propertyName,value);          propertyType = propertyType != null ? propertyType : value.getClass();          String setterMethodName = "set" + StringUtils.capitalize(propertyName);          invokeMethod(obj, setterMethodName, new Class<?>[] { propertyType },                  new Object[] { value });      }            private static Object handleValueType(Object obj, String propertyName,              Object value){          String getterMethodName = "get" + StringUtils.capitalize(propertyName);          Class<?> argsType = value.getClass();;          Class<?> returnType = obtainAccessibleMethod(obj, getterMethodName).getReturnType();          if(argsType == returnType){              return value;          }                    if (returnType == Boolean.class) {              String temp = value.toString();              value = (StringUtils.isNotBlank(temp) && Long.valueOf(temp) > 0) ? true : false;          } else if (returnType == Long.class) {              value = Long.valueOf(value.toString());          }else if(returnType == Date.class){              try {                  value = SimpleDateFormatFactory.getInstance(DateUtil.FULL_TIME_FORMAT).parse(value.toString());              } catch (ParseException e) {                  logger.error("类型转型Timpestap-->Date时,发生错误! " + e.getMessage() + "("+value.toString()+")");              }          } else if (returnType == Short.class) {              value = Short.valueOf(value.toString());          } else if (returnType == BigDecimal.class) {              value = BigDecimal.valueOf(Long.valueOf(value.toString()));          } else if (returnType == BigInteger.class) {              value = BigInteger.valueOf(Long.valueOf(value.toString()));          } else if(returnType == String.class){              value = String.valueOf(value);          }else if(returnType == Integer.class){              value = Integer.valueOf(value.toString());          }          return value;      }            public static void main(String[] args) throws Exception {          Timestamp ts = new Timestamp(System.currentTimeMillis());          System.out.println(SimpleDateFormatFactory.getInstance(DateUtil.FULL_TIME_FORMAT).parse(ts.toString()));      }            /**       * 直接调用对象方法,忽视private/protected修饰符       *        * @param obj       * @param methodName       * @param parameterTypes       * @param params       * @return       */      public static Object invokeMethod(final Object obj,              final String methodName, final Class<?>[] parameterTypes,              final Object[] args) {          Method method = obtainAccessibleMethod(obj, methodName, parameterTypes);          if (method == null) { throw new IllegalArgumentException(                  "Devkit: Could not find method [" + methodName                          + "] on target [" + obj + "]."); }          try {              return method.invoke(obj, args);          } catch (IllegalAccessException e) {              e.printStackTrace();          } catch (IllegalArgumentException e) {              e.printStackTrace();          } catch (InvocationTargetException e) {              e.printStackTrace();          }          return null;      }            /**       * 循环向上转型,获取对象的DeclaredMethod,并强制设置为可访问 如向上转型到Object仍无法找到,返回null       *        * 用于方法需要被多次调用的情况,先使用本函数先取得Method,然后调用Method.invoke(Object obj,Object...       * args)       *        * @param obj       * @param methodName       * @param parameterTypes       * @return       */      public static Method obtainAccessibleMethod(final Object obj,              final String methodName, final Class<?>... parameterTypes) {          Class<?> superClass = obj.getClass();          Class<Object> objClass = Object.class;          for (; superClass != objClass; superClass = superClass.getSuperclass()) {              Method method = null;              try {                  method = superClass.getDeclaredMethod(methodName,                          parameterTypes);                  method.setAccessible(true);                  return method;              } catch (NoSuchMethodException e) {                  // Method不在当前类定义,向上转型              } catch (SecurityException e) {                  // Method不在当前类定义,向上转型              }          }          return null;      }            /**       * 不能确定方法是否包含参数时,通过方法名匹配获得方法       *        * @param obj       * @param methodName       * @return       */      public static Method obtainMethod(final Object obj, final String methodName) {          Class<?> clazz = obj.getClass();          Method[] methods = METHODS_CACHEMAP.get(clazz);          if (methods == null) { // 尚未缓存              methods = clazz.getDeclaredMethods();              METHODS_CACHEMAP.put(clazz, methods);          }          for (Method method : methods) {              if (method.getName().equals(methodName))                  return method;          }          return null;                }            /**       * 直接读取对象属性值 忽视private/protected修饰符,不经过getter函数       *        * @param obj       * @param fieldName       * @return       */      public static Object obtainFieldValue(final Object obj,              final String fieldName) {          Field field = obtainAccessibleField(obj, fieldName);          if (field == null) { throw new IllegalArgumentException(                  "Devkit: could not find field [" + fieldName + "] on target ["                          + obj + "]"); }          Object retval = null;          try {              retval = field.get(obj);          } catch (IllegalArgumentException e) {              e.printStackTrace();          } catch (IllegalAccessException e) {              e.printStackTrace();          }          return retval;                }            /**       * 直接设置对象属性值 忽视private/protected修饰符,不经过setter函数       *        * @param obj       * @param fieldName       * @param value       */      public static void setFieldValue(final Object obj, final String fieldName,              final Object value) {          Field field = obtainAccessibleField(obj, fieldName);          if (field == null) { throw new IllegalArgumentException(                  "Devkit: could not find field [" + fieldName + "] on target ["                          + obj + "]"); }          try {              field.set(obj, value);          } catch (IllegalArgumentException e) {              e.printStackTrace();          } catch (IllegalAccessException e) {              e.printStackTrace();          }      }            /**       * 循环向上转型,获取对象的DeclaredField,并强制设为可访问 如向上转型Object仍无法找到,返回null       *        * @param obj       * @param fieldName       * @return       */      public static Field obtainAccessibleField(final Object obj,              final String fieldName) {          Class<?> superClass = obj.getClass();          Class<Object> objClass = Object.class;          for (; superClass != objClass; superClass = superClass.getSuperclass()) {              try {                  Field field = superClass.getDeclaredField(fieldName);                  field.setAccessible(true);                  return field;              } catch (NoSuchFieldException e) {                  // Field不在当前类定义,向上转型              } catch (SecurityException e) {                  // Field不在当前类定义,向上转型              }          }          return null;      }  }