关于Spring JDBC RowMapper的一点改进思路

【注】通常我们使用RowMapper(比如ParameterizedRowMapper),都需要定义好查询字段,,如果使用别名就没办法了。还要比如加入group,或者联合查询,也不能够使用,除非不想要非主体Bean之外的字段,那么只能用Map接收返回结果了,或者直接实现RowMapper。基于这一点,提出一个稍微通用的解决思路:所有的Bean都继承一个基类Bean,里面放一个Map(就是存放那些Bean没有指定的字段了,比如sum、count、avg … 各种查询字段或者别名),参考BeanPropertyRowMapper,在mapRow方法里面做些小调整,找不到的column就放到map里面,这样子的话,Bean有的字段就采用getxxx(),没有就从map里面取,好像会有点用。

#具体方法如下#

{private Map<String, Object> aliasFields = new HashMap<String, Object>();(String field, Object value) {aliasFields.put(field, value);}public Object getAliasFields(String field) {return aliasFields.get(field);}}

该类中只放一个map,存储Bean里面没有的字段,剩下的就是改造RowMapper实现类,可以拷贝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 {/// *****就是修改这个地方了!!!!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,比如:

{serialVersionUID = 2233912281609962999L;private Integer id;private String name;private String password;private Date createTime;private Integer type;public Demo() {super.queryBuilder = new QueryBuilder(this);}(Integer id) {this.id = id;}public Integer getId () {return this.id;}(String name) {this.name = name;}public String getName () {return this.name;}(String password) {this.password = password;}public String getPassword () {return this.password;}(Date createTime) {this.createTime = createTime;}public Date getCreateTime () {return this.createTime;}(Integer type) {this.type = type;}public Integer getType () {return this.type;}}

查询的时候,就可以通过Demo Bean取出非表字段的数据,通过getAliasFields(String field)方法。个人感觉能够提高一定的便捷性,后续会加入sbrom中,关于sbrom可以查看,欢迎吐槽!

人生就像是一场旅行,遇到的既有感人的,

关于Spring JDBC RowMapper的一点改进思路

相关文章:

你感兴趣的文章:

标签云: