最近有个任务:根据查询SQL直接导出报表
实现关键是,怎么根据sql查询的数据动态生成对象列表,想到Cglib动态代理实现
废话少说,上代码:
定义动态生成Java Bean类:
import java.util import net.sf.cglib.beans.{BeanGenerator, BeanMap} /** * 动态Bean生成 * * @author BarryWang create at 2018/6/19 11:54 * @version 0.0.1 */class DynamicBean { private var `object`: AnyRef = null private var beanMap: BeanMap = null def this(fieldTypeMap: util.Map[String, AnyRef]) { this() this.`object` = generateObject(fieldTypeMap) this.beanMap = BeanMap.create(this.`object`) } /** * 生成对象 * * @param fieldTypeMap 域及类型Map * @return */ private def generateObject(fieldTypeMap: util.Map[String, AnyRef]) = { val generator = new BeanGenerator val keySet = fieldTypeMap.keySet val i = keySet.iterator while (i.hasNext) { val key = i.next generator.addProperty(key, fieldTypeMap.get(key).asInstanceOf[Class[_]]) } generator.create } /** * 设置域值 * * @param filedName 域名 * @param value 值 */ def setValue(filedName: String, value: AnyRef): Unit = { this.beanMap.put(filedName, value) } /** * 获取域值 * * @param fieldName 域名 * @return */ def getValue(fieldName: String): AnyRef = this.beanMap.get(fieldName) /** * 最终对象 * * @return */ def getObject: AnyRef = this.`object`} SQL查询数据转对象:
/** * 根据数据查出数据转成对象列表 * @param database 数据库 * @param querySql 查询SQl * @return */ def getObjectDataList(database: String, querySql: String): ArrayList[Object] = { println(s"database:${database} sql:${querySql}") val rs = DataGenerator.getResultSet(database, querySql) val md = rs.getMetaData val colCount = md.getColumnCount val fieldValMap = new JavaHashMap[String, AnyRef]() for (i <- 0 to colCount - 1) { fieldValMap.put(underLineToCamel(md.getColumnName(i + 1)), Class.forName("java.lang.String")) } // 生成动态 Bean val returnList = new ArrayList[Object](); while (rs.next()) { val objectBean = new DynamicBean(fieldValMap); for (i <- 0 to colCount - 1) { val data = getData(md, i+1, rs) objectBean.setValue(underLineToCamel(md.getColumnName(i + 1)), data) }// println(">> " + objectBean.getValue("zhCnName")) returnList.add(objectBean.getObject) } rs.close() returnList } def underLineToCamel(name: String): String = { val result = new StringBuilder // 快速检查 if (name == null || name.isEmpty) { // 没必要转换 return "" // } else if (!name.contains("_")) { // // 不含下划线,仅将首字母小写 // return name.substring(0, 1).toLowerCase() + name.substring(1); } // 用下划线将原始字符串分割 val camels = name.split("_") for (camel <- camels) { // 跳过原始字符串中开头、结尾的下换线或双重下划线 // 处理真正的驼峰片段 if (result.length == 0) { // 第一个驼峰片段,全部字母都小写 result.append(camel.toLowerCase) } else { // 其他的驼峰片段,首字母大写 result.append(camel.substring(0, 1).toUpperCase) result.append(camel.substring(1).toLowerCase) } } result.toString }
/** * 从ResultSet取数 * @param md * @param index * @param rs * @return */def getData(md: ResultSetMetaData, index: Int, rs: ResultSet): String = { md.getColumnType(index) match { case Types.DECIMAL => { val value = rs.getBigDecimal(index) val bigDecimal = value == null match { case true => "0.0000" case false => value.setScale(4, RoundingMode.HALF_UP).toString() } return bigDecimal } case Types.TIMESTAMP =>{ val value = rs.getTimestamp(index) val timestamp = value == null match { case true => "" case false => DateTools.format(new Date(rs.getTimestamp(index).getTime)) } return timestamp } case Types.DATE => { val value = rs.getDate(index) val date = value == null match { case true => "" case false => DateTools.format(rs.getDate(index), DateTools.DATE_PATTERN) } return date } case _ => { val value = rs.getObject(index) val data = value == null match { case true => "" case false => rs.getObject(index).toString } return data } }}
原文地址:https://www.cnblogs.com/barrywxx/p/9976507.html
时间: 2024-10-06 16:59:53