cglib根據數據動態生成對象


最近有個任務:根據查詢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
}
}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM