//首先说下思路:1.通过反射获取所有字段信息,获取注解的信息(包括表名,列名,列的类型等) // 2.然后传递过来一个list结果集合,通过一些简单的计算和逻辑控制,生成对应的sql语句用stringBuff er拼接。 // 3.关键点:每次在循环这个list结果集合的时候,调用List.subList(0, resultList.size()).clea r();该方法,可以每次清除掉你本次已经走过的步长的数据。这样经过每次的迭代,最终集合的数据越 来越少,从而提高效率。 /** * * 功能说明:通过反射获取集合的值,并构建insert语句 * * @author: 吕兵阳 * @param theCalcResult 要保存的数据集合 * @throws Exception * @return 返回本次执行的sql添加语句 * @DATE:2014-10-17 @TIME: 下午12:57:31 */ private String optionTheCalcResultList( List<?> theCalcResult) throws Exception { if (theCalcResult == null || theCalcResult.isEmpty()) { // 过滤为空的直接return return null; } // 初始化一个map,保存<columnName,fieldName>的信息 Map<String, String> resultMap = new HashMap<String, String>(); // 声明保存列的集合 List<String> columnList = new ArrayList<String>(); // 声明表名 String tabName = ""; // 获取当前传入对象的全类名 String className = theCalcResult.get(0).getClass().getName(); // 用于存储标记是时间类型的列名<columnName,columnType> Map<String, String> markDateCol = new HashMap<String, String>(); Class<?> c = null;// 声明当前传入的结果集类 c = ClassUtils.getClass(className);// 得到当前传入的结果集类 if (c.isAnnotationPresent(Table.class)) { // 得到类的注解 Annotation claAnno = c.getAnnotation(Table.class); Object objTab = org.springframework.core.annotation.AnnotationUtils .getValue(claAnno, "name"); if (objTab == null) { logger.debug("*************没有注解信息**************"); return null; } tabName = objTab.toString();// 表名 } // 得到当前结果集中主表类的所有字段 Field[] f = c.getDeclaredFields(); for (Field field : f) { if (field.isAnnotationPresent(Column.class)) { Annotation anno = field.getAnnotation(Column.class); Object objColumn = org.springframework.core.annotation.AnnotationUtils .getValue(anno, "name"); if (objColumn == null) { continue; } // 得到字段的属性 Class<?> wordType = field.getType(); // 判断字段是否是时间类型 if (wordType.equals(java.util.Date.class)) { markDateCol.put(objColumn.toString(), field.getName()); } resultMap.put(objColumn.toString(), field.getName()); columnList.add(objColumn.toString()); } } List<Class<?>> css = ClassUtils.getAllSuperclasses(c);// 得到当前传入的结果集类的所有父类集合 // 得到当前传入的结果集类的所有父类集合的所有字段 for (Class<?> class1 : css) { Field[] fs = class1.getDeclaredFields(); for (Field field : fs) { if (field.isAnnotationPresent(Column.class)) { Annotation anno = field.getAnnotation(Column.class); Object suObjColumn = org.springframework.core.annotation.AnnotationUtils .getValue(anno, "name"); if (suObjColumn == null) { continue; } // 得到字段的属性 Class<?> wordType = field.getType(); // 判断字段是否是时间类型 if (wordType.equals(java.util.Date.class)) { markDateCol .put(suObjColumn.toString(), field.getName()); } columnList.add(suObjColumn.toString()); resultMap.put(suObjColumn.toString(), field.getName()); } } } DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); StringBuffer sb = new StringBuffer(); // 要返回的sql语句的string缓冲类 StringBuffer inSql = new StringBuffer(); Object value = null; List<String> columns = new ArrayList<String>();// 列的集合 for (int i = 0; i < theCalcResult.size(); i++) { sb.append("(select "); int j = 0; for (String columnName : columnList) { j++; String fieldName = resultMap.get(columnName); String firstLetter = fieldName.substring(0, 1).toUpperCase(); // 获得字段第一个字母大写 String getMethodName = "get" + firstLetter + fieldName.substring(1); // 转换成字段的get方法 Method getMethod = c.getMethod(getMethodName, new Class[] {}); value = getMethod.invoke(theCalcResult.get(i), new Object[] {}); if ("ID".equals(columnName)) { value = "sys_guid()"; } else if (markDateCol.containsKey(columnName)) { value = value == null ? null : (Date) value; value = df.format(value); value = "to_date('" + value + "','yyyy-mm-dd hh24:mi:ss')"; } else { value = value == null ? "null" : "'" + value + "'"; } if (columns.size() < columnList.size()) { columns.add(columnName); } if (j == columnList.size()) { if ((i + 1) != theCalcResult.size()) { sb.append(value + " from dual) union all "); } else { sb.append(value + " from dual)"); } } else { sb.append(value + ", "); } } } if (StringUtils.isBlank(inSql)) { inSql.append("insert into " + tabName + "( "); inSql.append(StringUtils.join(columns.toArray(), ",") + " )"); } inSql.append(sb); logger.debug("输出的sql语句:" + inSql.toString()); return inSql.toString(); }
public boolean saveResult(List<?> resultList) { int step = 3;//步长 int commitCount = resultList.size() / step;//分几次执行 int remainderNumber = resultList.size() % step;//是否有余数 if (remainderNumber != 0) { commitCount++; } logger.debug("#################saveResult方法begin#################"); logger.debug("总共:" + resultList.size() + "条"); String[] sqlArray = new String[commitCount]; for (int i = 0; i < sqlArray.length; i++) { List<Object> tempList = new ArrayList<Object>(); if (!resultList.isEmpty()) { for (int j = 0; j < step; j++) { if (step > resultList.size()) { break; } tempList.add(resultList.get(j)); } if (step > resultList.size()) { for (int j = 0; j < resultList.size(); j++) { tempList.add(resultList.get(j)); } } } try { sqlArray[i] = this.optionTheCalcResultList(tempList); logger.debug("步长为:" + step + ",分:" + commitCount + "次执行,本次执行第:" + i + "次"); } catch (Exception e) { logger.debug("####################构建sql语句出错##########################"); new EagleException("系统错误,请联系管理员!"); } if (!resultList.isEmpty()) { if (step > resultList.size()) { resultList.subList(0, resultList.size()).clear(); } else { resultList.subList(0, step).clear(); } } } this.getJdbcTemplate().batchUpdate(sqlArray);//调用spring的批量保存 logger.debug("#################saveResult方法end#################"); return true; }
下面为打印的logger日志: 2014-10-18 23:31:48,327 TheoCalcDomainBaseService - #################saveResult方法begin################# 2014-10-18 23:31:48,334 TheoCalcDomainBaseService - 总共:10条 2014-10-18 23:31:48,395 TheoCalcDomainBaseService - 输出的sql语句:insert into LLT_TRANPSRRESULT( PART_INDEX,PSR_ID,DATA_TIME,CALC_TIME,CALC_PERIOD,ID,YEARMONTH,COMPANY_ID,COMPANY_NAME )(select null, null, to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), '0', sys_guid(), null, '单位id0', '单位测试name0' from dual) union all (select null, null, to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), '1', sys_guid(), null, '单位id1', '单位测试name1' from dual) union all (select null, null, to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), '2', sys_guid(), null, '单位id2', '单位测试name2' from dual) 2014-10-18 23:31:48,396 TheoCalcDomainBaseService - 步长为:3,分:4次执行,本次执行第:0次 2014-10-18 23:31:48,401 TheoCalcDomainBaseService - 输出的sql语句:insert into LLT_TRANPSRRESULT( PART_INDEX,PSR_ID,DATA_TIME,CALC_TIME,CALC_PERIOD,ID,YEARMONTH,COMPANY_ID,COMPANY_NAME )(select null, null, to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), '3', sys_guid(), null, '单位id3', '单位测试name3' from dual) union all (select null, null, to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), '4', sys_guid(), null, '单位id4', '单位测试name4' from dual) union all (select null, null, to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), '5', sys_guid(), null, '单位id5', '单位测试name5' from dual) 2014-10-18 23:31:48,404 TheoCalcDomainBaseService - 步长为:3,分:4次执行,本次执行第:1次 2014-10-18 23:31:48,407 TheoCalcDomainBaseService - 输出的sql语句:insert into LLT_TRANPSRRESULT( PART_INDEX,PSR_ID,DATA_TIME,CALC_TIME,CALC_PERIOD,ID,YEARMONTH,COMPANY_ID,COMPANY_NAME )(select null, null, to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), '6', sys_guid(), null, '单位id6', '单位测试name6' from dual) union all (select null, null, to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), '7', sys_guid(), null, '单位id7', '单位测试name7' from dual) union all (select null, null, to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), '8', sys_guid(), null, '单位id8', '单位测试name8' from dual) 2014-10-18 23:31:48,410 TheoCalcDomainBaseService - 步长为:3,分:4次执行,本次执行第:2次 2014-10-18 23:31:48,412 TheoCalcDomainBaseService - 输出的sql语句:insert into LLT_TRANPSRRESULT( PART_INDEX,PSR_ID,DATA_TIME,CALC_TIME,CALC_PERIOD,ID,YEARMONTH,COMPANY_ID,COMPANY_NAME )(select null, null, to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), to_date('2014-10-18 23:31:48','yyyy-mm-dd hh24:mi:ss'), '9', sys_guid(), null, '单位id9', '单位测试name9' from dual) 2014-10-18 23:31:48,412 TheoCalcDomainBaseService - 步长为:3,分:4次执行,本次执行第:3次 2014-10-18 23:31:48,412 TheoCalcDomainBaseService - #################saveResult方法end#################