org.onetwo.dbm.jdbc.mapper.DbmBeanPropertyRowMapper Maven / Gradle / Ivy
The newest version!
package org.onetwo.dbm.jdbc.mapper;
import java.beans.PropertyDescriptor;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.onetwo.dbm.jdbc.JdbcUtils;
import org.onetwo.dbm.jdbc.spi.JdbcResultSetGetter;
import org.onetwo.dbm.utils.DbmUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.NotWritablePropertyException;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.core.convert.ConversionService;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSetMetaData;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
public class DbmBeanPropertyRowMapper extends DbmDataRowMapper implements DataRowMapper, DataColumnMapper {
// final protected Logger logger = JFishLoggerFactory.getLogger(this.getClass());
protected ConversionService conversionService = DbmUtils.CONVERSION_SERVICE;
// private DbmTypeMapping sqlTypeMapping;
// protected JdbcResultSetGetter jdbcResultSetGetter;
protected boolean primitivesDefaultedForNullValue = true;
protected Class mappedClass;
protected Set mappedProperties;
protected Map mappedFields;
/*public DbmBeanPropertyRowMapper() {
super();
}*/
public DbmBeanPropertyRowMapper(JdbcResultSetGetter jdbcResultSetGetter, Class mappedClass) {
super(jdbcResultSetGetter);
this.mappedClass = mappedClass;
// this.jdbcResultSetGetter = jdbcResultSetGetter;
this.initialize(mappedClass);
}
public ConversionService getConversionService() {
return conversionService;
}
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
/****
* 通过反射获取bean所有属性,并把驼峰格式的属性名称转成小写和下划线,做成映射
* @author wayshall
* @param mappedClass
*/
protected void initialize(Class mappedClass) {
this.mappedClass = mappedClass;
this.mappedFields = new HashMap();
this.mappedProperties = new HashSet();
PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(mappedClass);
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null) {
this.mappedFields.put(JdbcUtils.lowerCaseName(pd.getName()), pd);
String underscoredName = underscoreName(pd.getName());
if (!JdbcUtils.lowerCaseName(pd.getName()).equals(underscoredName)) {
this.mappedFields.put(underscoredName, pd);
}
this.mappedProperties.add(pd.getName());
}
}
}
/**
* Convert a name in camelCase to an underscored name in lower case.
* Any upper case letters are converted to lower case with a preceding underscore.
* @param name the original name
* @return the converted name
* @since 4.2
* @see #lowerCaseName
*/
protected String underscoreName(String name) {
return JdbcUtils.underscoreName(name);
}
protected void initBeanWrapper(BeanWrapper bw) {
ConversionService cs = getConversionService();
if (cs != null) {
bw.setConversionService(cs);
}
}
@Override
public BeanWrapper mapRowWithBeanWrapper(ResultSet rs, int rowNumber) throws SQLException {
Assert.state(this.mappedClass != null, "Mapped class was not specified");
T mappedObject = BeanUtils.instantiate(this.mappedClass);
BeanWrapper bw = this.createBeanWrapper(mappedObject);
ResultSetWrappingSqlRowSet resutSetWrapper = new ResultSetWrappingSqlRowSet(rs);
SqlRowSetMetaData rsmd = resutSetWrapper.getMetaData();
int columnCount = resutSetWrapper.getMetaData().getColumnCount();
for (int index = 1; index <= columnCount; index++) {
String column = DbmUtils.lookupColumnName(rsmd, index);
// String field = lowerCaseName(column.replaceAll(" ", ""));
this.setColumnValue(resutSetWrapper, bw, rowNumber, index, column);
}
return bw;
}
@SuppressWarnings("unchecked")
@Override
public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
// Assert.state(this.mappedClass != null, "Mapped class was not specified");
// T mappedObject = BeanUtils.instantiate(this.mappedClass);
// BeanWrapper bw = this.createBeanWrapper(mappedObject);
//
// ResultSetWrappingSqlRowSet resutSetWrapper = new ResultSetWrappingSqlRowSet(rs);
// SqlRowSetMetaData rsmd = resutSetWrapper.getMetaData();
// int columnCount = resutSetWrapper.getMetaData().getColumnCount();
//
// for (int index = 1; index <= columnCount; index++) {
// String column = DbmUtils.lookupColumnName(rsmd, index);
//// String field = lowerCaseName(column.replaceAll(" ", ""));
// this.setColumnValue(resutSetWrapper, bw, rowNumber, index, column);
// }
//
// return mappedObject;
return (T)mapRowWithBeanWrapper(rs, rowNumber).getWrappedInstance();
}
public void setColumnValue(ResultSetWrappingSqlRowSet resutSetWrapper,
BeanWrapper bw,
int rowNumber,
int columnIndex,
String column) {
String field = JdbcUtils.lowerCaseName(column);
PropertyDescriptor pd = this.mappedFields.get(field);
if (pd != null) {
try {
Object value = getColumnValue(resutSetWrapper, columnIndex, pd);
if (rowNumber == 0 && logger.isDebugEnabled()) {
logger.debug("Mapping column '" + column + "' to property '" + pd.getName() +
"' of type [" + ClassUtils.getQualifiedName(pd.getPropertyType()) + "]");
}
try {
bw.setPropertyValue(pd.getName(), value);
}
catch (TypeMismatchException ex) {
if (value == null && this.primitivesDefaultedForNullValue) {
if (logger.isDebugEnabled()) {
logger.debug("Intercepted TypeMismatchException for row " + rowNumber +
" and column '" + column + "' with null value when setting property '" +
pd.getName() + "' of type [" +
ClassUtils.getQualifiedName(pd.getPropertyType()) +
"] on object: " + bw.getWrappedInstance(), ex);
}
}
else {
throw ex;
}
}
}
catch (NotWritablePropertyException ex) {
throw new DataRetrievalFailureException(
"Unable to map column '" + column + "' to property '" + pd.getName() + "'", ex);
}
}
else {
// No PropertyDescriptor found
if (rowNumber == 0 && logger.isDebugEnabled()) {
logger.debug("No property found for column '" + column + "' mapped to field '" + field + "'");
}
}
}
protected Object getColumnValue(ResultSetWrappingSqlRowSet rs, int index, PropertyDescriptor pd) {
// return jdbcResultSetGetter.getColumnValue(rs, index, pd);
return jdbcResultSetGetter.getColumnValue(rs, index, pd.getPropertyType());
/*JFishProperty jproperty = Intro.wrap(pd.getWriteMethod().getDeclaringClass()).getJFishProperty(pd.getName(), false);
TypeHandler> typeHandler = sqlTypeMapping.getTypeHander(jproperty.getType(), sqlType);
Object value = typeHandler.getResult(rs, index);
return value;*/
}
protected BeanWrapper createBeanWrapper(T entity) {
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(entity);
bw.setAutoGrowNestedPaths(true);
initBeanWrapper(bw);
return bw;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((mappedClass == null) ? 0 : mappedClass.hashCode());
result = prime * result
+ ((mappedFields == null) ? 0 : mappedFields.hashCode());
result = prime
* result
+ ((mappedProperties == null) ? 0 : mappedProperties.hashCode());
result = prime * result
+ (primitivesDefaultedForNullValue ? 1231 : 1237);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DbmBeanPropertyRowMapper> other = (DbmBeanPropertyRowMapper>) obj;
if (mappedClass == null) {
if (other.mappedClass != null)
return false;
} else if (!mappedClass.equals(other.mappedClass))
return false;
if (mappedFields == null) {
if (other.mappedFields != null)
return false;
} else if (!mappedFields.equals(other.mappedFields))
return false;
if (mappedProperties == null) {
if (other.mappedProperties != null)
return false;
} else if (!mappedProperties.equals(other.mappedProperties))
return false;
if (primitivesDefaultedForNullValue != other.primitivesDefaultedForNullValue)
return false;
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy