java bean自动进行rowMapper or handler的类

一般情况下在进行jdbc编程的时候避免不了的要写n多的bean类,用来封装数据库获取的查询结果集,同时又要写n多的rowMapper或者handler来操作装配结果集中的数据进入bean中,最近研究了下自己写了一个对java bean自动进行rowMapper or handler的类 AutoBoxingRowMapper(其实现了spring jdbc的rowMapper),这是一个通用的rowMapper,大多数情况下可以帮助我们省去写n多的rowMapper类。

(注:在应用该类之前应该约定你的java bean中的属性名字的与sql查询中列名不区分大小写匹配,该类保证结果集与bean之间满足toLowerCase(columnName) = toLowerCase(propertyName)时才自动装配)

代码如下:



package com.loansystem.common.util;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.JdbcUtils;

/**
*
* 对查询数据结果集进行bean自动装箱
* (注:结果集与bean之间满足toLowerCase(columnName) = toLowerCase(propertyName))时才自动装箱
*/
public class AutoBoxingRowMapper implements RowMapper {

// protected final Log logger = LogFactory.getLog(this.getClass());

private boolean stringNotEmpty = true;//结果集中由字段值全部以string类型返回其值,并且为空时以空串""返回

private Class<Object> beanClass;//即将要进行包装的bean的Class

private Map<String,PropertyDescriptor> beanPropertyMap = new HashMap<String,PropertyDescriptor>();//即将要进行包装的bean的属性描述,以Map形式保存

public boolean isStringNotEmpty() {
return stringNotEmpty;
}

public void setStringNotEmpty(boolean stringNotEmpty) {
this.stringNotEmpty = stringNotEmpty;
}

public Class<Object> getBeanClass() {
return beanClass;
}

public void setBeanClass(Class<Object> beanClass) {
this.beanClass = beanClass;
}

public Map<String, PropertyDescriptor> getBeanPropertyMap() {
return beanPropertyMap;
}

public void setBeanPropertyMap(Map<String, PropertyDescriptor> beanPropertyMap) {
this.beanPropertyMap = beanPropertyMap;
}

/**
* 自动装配sql查询结果集的各列值到beanClass所指定的bean中的对应属性上,满足toLowerCase(columnName) = toLowerCase(propertyName)时进行装配
* @param beanClass - 要装配的bean的java.lang.Class
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public AutoBoxingRowMapper(Class beanClass){
super();
this.beanClass = beanClass;

//初始化beanClass对应的bean的所有属性
PropertyDescriptor[] props = null;
try {
props = Introspector.getBeanInfo(this.getBeanClass(), Object.class)
.getPropertyDescriptors();
if (props != null) {
for (int i = 0; i < props.length; i++) {
this.beanPropertyMap.put(props[i].getName().toLowerCase().trim(), props[i]);
}
}
} catch (IntrospectionException e) {
// logger.error(e, e);
}
}

/**
* 自动装配sql查询结果集的各列值到beanClass所指定的bean中的对应属性上,满足toLowerCase(columnName) = toLowerCase(propertyName)时进行装配
* @param beanClass - 要装配的bean的java.lang.Class
* @param stringNotEmpty - 是否将结果集中由字段值全部以string类型返回其值,并且为空时以空串""返回,default true
*/
@SuppressWarnings({"rawtypes"})
public AutoBoxingRowMapper(Class beanClass,boolean stringNotEmpty){
this(beanClass);
this.stringNotEmpty = stringNotEmpty;
}

public Object mapRow(ResultSet rs, int rowNum) throws SQLException {

Object defaultInstance = null;
try {
defaultInstance = this.getBeanClass().newInstance();//获取bean的实例
} catch (Exception e) {
// logger.error(e, e);
}
if(defaultInstance == null){
// logger.error("attempt to new a instance of class named : " + this.getBeanClass().getName() + " but failed!!!");
return null;
}
//获取元数据
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();

PropertyDescriptor propertyDescriptor = null;
try {
for (int i = 1; i <= columnCount; i++) {
String key = getColumnKey(JdbcUtils.lookupColumnName(rsmd, i));//获取resultset结果集中第i列对应的列名
Object obj = getColumnValue(rs, i, key);//获取resultset结果集中第i列对应的值

propertyDescriptor = this.beanPropertyMap.get(key);
if(propertyDescriptor == null){//当前列名key对应的属性在bean中找不到,给予警告
// logger.warn("no corresponding property defined in class : " + this.getBeanClass().getName() + " for sql query resultset column '" + key + "' !!!");
continue;
}else{当前列名key对应的属性在bean中找到,则调用其setXxx方法设置其值
propertyDescriptor.getWriteMethod().invoke(defaultInstance, obj);
}
}
} catch (Exception e) {
// logger.error(e, e);
}

return defaultInstance;
}

protected String getColumnKey(String columnName) {
return columnName == null ? null : columnName.toLowerCase().trim();
}

@SuppressWarnings("rawtypes")
protected Object getColumnValue(ResultSet rs, int index, String columnName) throws SQLException {
Object val = null;
if(stringNotEmpty){//所有列以string类型解析(前提做到要约定你的bean中的所有属性都定义成string类型)
val = rs.getString(index) == null ? "" : rs.getString(index);
}else{//所有类型以其bean类中对应的属性类型进行解析
PropertyDescriptor propertyDescriptor = this.beanPropertyMap.get(columnName);

if(propertyDescriptor != null){
Class propertyTypeClass = propertyDescriptor.getPropertyType();
String className = propertyTypeClass.getName();
if(className.equals("int") || className.equals(Integer.class.getName())){
val = rs.getInt(index);
return val;
}else if(className.equals("short") || className.equals(Short.class.getName())){
val = rs.getShort(index);
return val;
}else if(className.equals("byte") || className.equals(Byte.class.getName())){
val = rs.getByte(index);
return val;
}else if(className.equals("long") || className.equals(Long.class.getName())){
val = rs.getLong(index);
return val;
}else if(className.equals("float") || className.equals(Float.class.getName())){
val = rs.getFloat(index);
return val;
}else if(className.equals("double") || className.equals(Double.class.getName())){
val = rs.getDouble(index);
return val;
}else if(className.equals("char") || className.equals(Character.class.getName())){
val = rs.getString(index);
return val;
}else if(className.equals(String.class.getName())){
val = rs.getString(index);
return val;
}else if(className.equals(java.util.Date.class.getName())){
val = rs.getDate(index);
return val;
}else if(className.equals(java.math.BigDecimal.class.getName())){
val = rs.getBigDecimal(index);
return val;
}else{//Object
val = rs.getObject(index);
return val;
}
}else{
val = JdbcUtils.getResultSetValue(rs, index);
}
}
return val;
}
}



应用时,DAO中类似代码示例:



List<Object> list = this.getJdbcTemplate().query(sql, new AutoBoxingRowMapper(Department.class,false));

Map<String,Object> map = this.callProcedure(procName, new Object[]{deptNo,0,5}, new AutoBoxingRowMapper(Employee.class,false),true);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值