今天在看寫代碼的時候忽然發現,在類和數據庫字段之間沒有作過任何的映射關係,可是數據會自動的映射好
如下是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