基于spring和反射的批量保存工具方法

//首先说下思路: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#################


你可能感兴趣的:(java,注解,spring,反射,批量保存,列名,表名,betachUpdate)