springJdbcTemplate在itest 开源测试管理项目中的浅层(5个使用场景)封装

导读:主要从4个方面来阐述,1:背景;2:思路;3:代码实现;4:使用一:封装背景,在做项目的时候,用的JPA,有些复杂查询,比如报表用原生的JdbcTemplate,很不方便;需要增加分页功能,以及结果集自动转对像等5个常用功能,见第4节。下面两个图是开源测试管理软件itest的统计功能,因为SQL复杂,有些有200行,所以才有后面的JdbcTemplateWrapper;可以在这体验这些报表(...

springJdbcTemplate在itest 开源测试管理项目中的浅层(5个使用场景)封装

导读:

主要从4个方面来阐述,1:背景;2:思路;3:代码实现;4:使用

一:封装背景,

在做项目的时候,用的JPA ,有些复杂查询,比如报表用原生的JdbcTemplate ,很不方便;需要增加分页功能,以及结果集自动转对像等5个常用功能,见第4节。

下面两个图是开源测试管理软件 itest 的统计功能,因为SQL复杂,有些有200行,所以才有后面的 JdbcTemplateWrapper;可以在这体验这些报表(点测试,然后选择一个项目,然后点度量分析),速度还不错,https://itest.work/demo/login.htm

上面这图,SQL 就有200行

二:封装实现思路

(1)实现spring RowMapper 接口,直接把jdbc 结果集转 JAVA 对像(用的反射,访问量大的业务不推荐用这方式)

(2)不通过RowMapper 接口, 把JdbcTemplate 返回的List<Map<String,Object>> 原生JDBC结果集中,字段名,也就是MAP中的KEY,转换为驼峰规则的JAVA对属性名,方便前端组件使用,不再中间转为VO 或 实体类对像后,再返前端;比传统查询(多了一个LIST的遍历 ,基本对性能影响不大)

(3)封装分页

三:代码实现

两个类,ObjectRowMapper 和 JdbcTemplateWrapper

ObjectRowMapper 代码如下:

  1 package cn.com.mypm.framework.jdbc;  2   3 import java.lang.reflect.Field;  4 import java.sql.ResultSet;  5 import java.sql.ResultSetMetaData;  6 import java.sql.SQLException;  7 import java.util.HashMap;  8 import java.util.Map;  9 import java.util.concurrent.ConcurrentHashMap; 10  11 import org.apache.commons.logging.Log; 12 import org.apache.commons.logging.LogFactory; 13 import org.springframework.jdbc.core.RowMapper; 14 import org.springframework.util.StringUtils; 15  16 import cn.com.mypm.common.util.CalendaUtilities; 17 import cn.com.mypm.framework.common.config.PropertiesBean; 18  19  20  21 /** 22  * 23 * <p>标题: RowMapper 接口实现</p> 24 * <p>业务描述:完成原生结果集到JAVA对像的转换</p> 25 * <p>公司:itest.work</p> 26 * <p>版权:itest 2018</p> 27 * @author itest andy 28 * @date 2018年6月8日 29 * @version V1.0 30  */ 31 @SuppressWarnings("rawtypes") 32 public class ObjectRowMapper implements RowMapper { 33  34   35  private Class<?> objectClass; 36  private String[] columnNames = null; 37  private Field[] fields ; 38  ///缓存 当前结果集字对段和当前class的 Field的对应关系, 39  private Map<String ,Field> currQueryFieldMap ; 40  //缓存当前结果集,字段和 JAVA属性名的对应关系 ,按脱峰规则做的转换 41  private Map<String ,String> fieldClassMap ; 42  private Boolean isConvertSwitch  = null; 43  // MYSQL 是否区分大小写的标记,要是区转,要把结果集中,字段名,大写转为小写 44  private String mysqlLowerCaseTableNames = null; 45  private static Log logger = LogFactory.getLog(ObjectRowMapper.class); 46  //缓存某个class 已处理过的字段映射到属性名的关系,避免同一个类每次重新处理,第一个KEY 为类名 47  private static Map<String, Map<String, String>> dbColumnClassFieldMap = new ConcurrentHashMap<String, Map<String, String>>(); 48   49  public ObjectRowMapper(Class<?> objectClass) { 50this.objectClass = objectClass; 51fields = objectClass.getDeclaredFields(); 52  } 53  54  public void clean(){ 55if(currQueryFieldMap!=null){ 56 currQueryFieldMap.clear(); 57 currQueryFieldMap = null; 58   } 59if(fieldClassMap!=null){ 60 fieldClassMap.clear(); 61 fieldClassMap = null; 62   } 63if(fields!=null){ 64 fields = null; 65   } 66if(columnNames!=null){ 67 columnNames = null; 68   } 69  } 70   71  /** 72   * 该方法自动将数据库字段对应到Object中相应字段 要求: 73   * 字段名严格为驼峰形式 == 数据库字段名去掉下划线转为驼峰形式 74   * 如user_name 转为userName ,如数据库字段名,无下划线 75   * 就只能把首字母变为大小写后的 set ,get 76*/ 77  @Override 78  public Object mapRow(ResultSet rs, int rowNum) throws SQLException { 79  80Object targetObject = null; 81try { 82 targetObject = objectClass.newInstance(); 83} catch (InstantiationException | IllegalAccessException e) { 84 logger.error(e.getMessage(), e); 85   } 86if (columnNames == null) { 87 ResultSetMetaData rsmd = rs.getMetaData(); 88 int columnCount = rsmd.getColumnCount(); 89 columnNames = new String[columnCount]; 90 for (int i = 0; i < columnCount; i  ) { 91  columnNames[i] = rsmd.getColumnLabel(i1); 92 } 93   } 94isConvertSwitch = true; 95  96if(mysqlLowerCaseTableNames == null){ 97 String lowerCaseN
源文地址:http://www.guoxiongfei.cn/cntech/14842.html