今天在看写代码的时候忽然发现,在类和数据库字段之间没有作过任何的映射关系,可是数据会自动的映射好
如下是spring代码的具体实现直接贴代码
讲述映射实现的过程
关注下BeanPropertyRowMapper这个类java
protected void initialize(Class<T> mappedClass) { this.mappedClass = mappedClass; this.mappedFields = new HashMap<String, PropertyDescriptor>(); this.mappedProperties = new HashSet<String>(); PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(mappedClass); for (PropertyDescriptor pd : pds) { if (pd.getWriteMethod() != null) { this.mappedFields.put(pd.getName().toLowerCase(), pd); String underscoredName = underscoreName(pd.getName()); if (!pd.getName().toLowerCase().equals(underscoredName)) { this.mappedFields.put(underscoredName, pd); } this.mappedProperties.add(pd.getName()); } } }
这段代码是实现映射的地方spring
String underscoredName = underscoreName(pd.getName());
这个方法是把java类中的驼峰转化成数据库的下划线的方法数据库
if (!pd.getName().toLowerCase().equals(underscoredName)) { this.mappedFields.put(underscoredName, pd); }
这段代码是检测当前字段是否须要处理驼峰命名,若是是须要转化的则须要从新赋值,key是数据库的对应字段名app
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); } } } 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; }
这个方法中的PD是经过数据库的column获取的,正好能够跟上面讲述的转化赋值对应,而后这个从mappedFields中获取到的PD中的name就是该数据库字段对应的javaBean中的值this
至此spring的默认规则的映射实现已经讲述完了debug
附连接
使用Spring的NamedParameterJdbcTemplate完成DAO操做
(这个是NamedParameterJdbcTemplate的一个操做讲解)
http://zmx.iteye.com/blog/373736code