【注】通常我們使用RowMapper(比如ParameterizedRowMapper),都需要定義好查詢字段,如果使用別名就沒辦法了。還要比如加入group,或聯(lián)合查詢,也不能夠使用,除非不想要非主體Bean以外的字段,那末只能用Map接收返回結果了,或直接實現(xiàn)RowMapper?;谶@1點,提出1個略微通用的解決思路:所有的Bean都繼承1個基類Bean,里面放1個Map(就是寄存那些Bean沒有指定的字段了,比如sum、count、avg … 各種查詢字段或別名),參考BeanPropertyRowMapper,在mapRow方法里面做些小調劑,找不到的column就放到map里面,這模樣的話,Bean有的字段就采取getxxx(),沒有就從map里面取,好像會有點用。
#具體方法以下#
public abstract class BaseEntity {
private Map<String, Object> aliasFields = new HashMap<String, Object>();
public void setAliasField(String field, Object value) {
aliasFields.put(field, value);
}
public Object getAliasFields(String field) {
return aliasFields.get(field);
}
}
該類中只放1個map,存儲Bean里面沒有的字段,剩下的就是改造RowMapper實現(xiàn)類,可以拷貝BeanPropertyRowMapper,換個類名,直接修改mapRow方法,具體以下(改動量非常小,看注釋):
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 = PropertyAccessorFactory.forBeanPropertyAccess(mappedObject);
initBeanWrapper(bw);
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
Set<String> populatedProperties = (isCheckFullyPopulated() ? new HashSet<String>() : null);
for (int index = 1; index <= columnCount; index++) {
String column = JdbcUtils.lookupColumnName(rsmd, index);
PropertyDescriptor pd = this.mappedFields.get(column.replaceAll(" ", "").toLowerCase());
if (pd != null) {
try {
Object value = getColumnValue(rs, index, pd);
if (logger.isDebugEnabled() && rowNumber == 0) {
logger.debug("Mapping column '" + column + "' to property '" +
pd.getName() + "' of type " + pd.getPropertyType());
}
try {
bw.setPropertyValue(pd.getName(), value);
}
catch (TypeMismatchException e) {
if (value == null && primitivesDefaultedForNullValue) {
logger.debug("Intercepted TypeMismatchException for row " + rowNumber +
" and column '" + column + "' with value " + value +
" when setting property '" + pd.getName() + "' of type " + pd.getPropertyType() +
" on object: " + mappedObject);
}
else {
throw e;
}
}
if (populatedProperties != null) {
populatedProperties.add(pd.getName());
}
}
catch (NotWritablePropertyException ex) {
throw new DataRetrievalFailureException(
"Unable to map column " + column + " to property " + pd.getName(), ex);
}
} else {/// *****就是修改這個地方了!?。。?/span>
Object value = JdbcUtils.getResultSetValue(rs, index);
((BaseEntity)mappedObject).setAliasField(column, value);
}
}
if (populatedProperties != null && !populatedProperties.equals(this.mappedProperties)) {
throw new InvalidDataAccessApiUsageException("Given ResultSet does not contain all fields " +
"necessary to populate object of class [" + this.mappedClass + "]: " + this.mappedProperties);
}
return mappedObject;
}
剩下的就是具體的Bean,繼承BaseEntity,比如:
public class Demo extends BaseEntity implements Serializable {
public static final long serialVersionUID = 2233912281609962999L;
private Integer id;
private String name;
private String password;
private Date createTime;
private Integer type;
public Demo() {
super.queryBuilder = new QueryBuilder(this);
}
public void setId (Integer id) {
this.id = id;
}
public Integer getId () {
return this.id;
}
public void setName (String name) {
this.name = name;
}
public String getName () {
return this.name;
}
public void setPassword (String password) {
this.password = password;
}
public String getPassword () {
return this.password;
}
public void setCreateTime (Date createTime) {
this.createTime = createTime;
}
public Date getCreateTime () {
return this.createTime;
}
public void setType (Integer type) {
this.type = type;
}
public Integer getType () {
return this.type;
}
}
查詢的時候,就能夠通過Demo Bean取出非表字段的數(shù)據,通過getAliasFields(String field)方法。個人感覺能夠提高1定的便捷性,后續(xù)會加入sbrom中,關于sbrom可以查看http://blog.csdn.net/yefeng_918/article/details/44747033,歡迎吐槽!