/* * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.hasor.data.jdbc.mapper; import net.hasor.core.Hasor; import net.hasor.core.utils.BeanUtils; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 用于 POJO 的 RowMapper * @version : 2013-12-18 * @author 赵永春(zyc@hasor.net) */ public class BeanPropertyRowMapper<T> extends AbstractRowMapper<T> { private Class<T> requiredType; private boolean caseInsensitive = false; private Map<String, String> columnMapping = new HashMap<String, String>(); // /** Create a new BeanPropertyRowMapper.*/ public BeanPropertyRowMapper() { } /** Create a new BeanPropertyRowMapper.*/ public BeanPropertyRowMapper(final Class<T> requiredType) { Hasor.assertIsNotNull(requiredType, "requiredType is null."); this.requiredType = requiredType; this.loadMapping(); } /** Set the type that each result object is expected to match. <p>If not specified, the column value will be exposed as returned by the JDBC driver.*/ public void setRequiredType(final Class<T> requiredType) { Hasor.assertIsNotNull(requiredType, "requiredType is null."); this.requiredType = requiredType; this.loadMapping(); } private void loadMapping() { /*借助用属性名统一大写,来实现属性感性。*/ this.columnMapping.clear(); List<String> prop = BeanUtils.getPropertysAndFields(this.requiredType); for (String pName : prop) { this.columnMapping.put(pName.toUpperCase(), pName); } } public boolean isCaseInsensitive() { return this.caseInsensitive; } public void setCaseInsensitive(final boolean caseInsensitive) { this.caseInsensitive = caseInsensitive; } @Override public T mapRow(final ResultSet rs, final int rowNum) throws SQLException { T targetObject; try { targetObject = this.requiredType.newInstance(); return this.tranResultSet(rs, targetObject); } catch (InstantiationException e) { throw new SQLException(e); } catch (IllegalAccessException e) { throw new SQLException(e); } } private T tranResultSet(final ResultSet rs, final T targetObject) throws SQLException { ResultSetMetaData rsmd = rs.getMetaData(); int nrOfColumns = rsmd.getColumnCount(); for (int i = 1; i <= nrOfColumns; i++) { String colName = rsmd.getColumnName(i); /*处理属性*/ if (!this.caseInsensitive) { colName = this.columnMapping.get(colName.toUpperCase()); } Class<?> paramType = BeanUtils.getPropertyOrFieldType(this.requiredType, colName); if (paramType == null) { continue; } Object colValue = this.getColumnValue(rs, i, paramType); BeanUtils.writePropertyOrField(targetObject, colName, colValue); } return targetObject; } /**取得指定列的值*/ protected Object getColumnValue(final ResultSet rs, final int index, final Class<?> requiredType) throws SQLException { Object resultData = getResultSetValue(rs, index); if (requiredType != null) { return convertValueToRequiredType(resultData, requiredType); } else { return resultData; } } /** * Static factory method to create a new BeanPropertyRowMapper (with the mapped class specified only once). * @param mappedClass the class that each row should be mapped to */ public static <T> BeanPropertyRowMapper<T> newInstance(final Class<T> mappedClass) { BeanPropertyRowMapper<T> newInstance = new BeanPropertyRowMapper<T>(); newInstance.setRequiredType(mappedClass); return newInstance; } }