利用java反射技术完成数据库表和实体类的映射关系,会遇到一些很常见的问题,实体类中有的字段数据库没有,或者数据库有的字段,实体类没有等到...该如何解决呢?
大概思路如下:
建立表与对应实体类的一个缓存集合,缓存实体类中跟表有映射关系的字段,用到时直接查询即可,下面给出部分代码:
//实体类中能与数据库对应起来的字段集合 private static Map<String, Map<String, Field>> databaseFieldsMap = new ConcurrentHashMap<String, Map<String, Field>>(); /*** * 缓存中的 数据库和实体类具有映射关系的field 用于反射查询 和实体对象的插入 * @param database 数据库名称 * @param cls 实体类class * @return */ public static Map<String, Field> getTableFields(String database, Class<?> cls){ String key = database + "_" + cls.getSimpleName(); //当前类的对应字段信息 Map<String, Field> tableFields = databaseFieldsMap.get(key); if(tableFields == null){ synchronized (SQLParamHelper.class) { tableFields = databaseFieldsMap.get(key); if(tableFields != null){ return tableFields; } Field[] fields = cls.getDeclaredFields(); Map<String, String> columnMap = getColumnMap(database, cls); if(columnMap != null){ List<Field> lists = new ArrayList<Field>(); tableFields = new LinkedHashMap<String, Field>(); for(Field f : fields){ BeanField bf = f.getAnnotation(BeanField.class); if(bf != null && !bf.persistence()){ continue; } if(Modifier.isStatic(f.getModifiers())){ continue; } //数据库中是否有当前字段 不区分大小写 if(columnMap.containsKey(f.getName().toLowerCase())){ lists.add(f); tableFields.put(f.getName(), f); } } databaseFieldsMap.put(key, tableFields); } } } return tableFields; } /*** * 获取表中的列 转换为 hashMap保存 * @param database * @param cls * @return */ private static Map<String, String> getColumnMap(String database, Class<?> cls){ //获取数据库连接 Connection conn = Data.getConnection(database); Map<String, String> columnMap = new HashMap<String, String>(); ResultSet colRet = null; try { String tableName = getTableName(cls); DatabaseMetaData metaData = conn.getMetaData(); ResultSet rsResult = metaData.getTables(null, "%", tableName, new String[]{"TABLE"}); if(rsResult!=null){ if(metaData != null){ colRet = metaData.getColumns(null,"%", tableName,"%"); while(colRet.next()) { String columnName = colRet.getString("COLUMN_NAME"); String columnType = colRet.getString("TYPE_NAME"); // int datasize = colRet.getInt("COLUMN_SIZE"); // int digits = colRet.getInt("DECIMAL_DIGITS"); // int nullable = colRet.getInt("NULLABLE"); // System.out.println(columnName+" "+columnType+" "+datasize+" "+digits+" "+ nullable); columnMap.put(columnName.toLowerCase(), columnType); } } } } catch (SQLException e) { e.printStackTrace(); return null; } finally { if(colRet != null){ try { colRet.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } return columnMap; } public static String getTableName(Class<?> cls){ String tableName = cls.getSimpleName(); AnnoBean annoBean = cls.getDeclaredAnnotation(AnnoBean.class); if(annoBean != null && annoBean.tableName() != null){ tableName = annoBean.tableName(); } return tableName; }