RowMapper匿名类使用
这里直接一个个设置返回实体类的属性
public Student getStudentByName(String name) {
String sql = "select id,name from student where name = ?";
Student student = this.jdbcTemplate.queryForObject(sql, new Object[]{name}, new RowMapper<Student>() {
@Override
public Student mapRow(ResultSet rs, int i) throws SQLException {
Student s = new Student();
s.setId(rs.getString("id"));
s.setName(rs.getString("name"));
return s;
}
});
return student;
}
SingleColumnRowMapper使用
当查询单个字段时,可以直接使用SingleColumnRowMapper
public String getStudentNameById(String id) {
String sql = "select name from test_student where id = ?";
return this.jdbcTemplate.queryForObject(sql, new Object[]{id},
new SingleColumnRowMapper<>(String.class));
}
BeanPropertyRowMapper使用
当查询字段多,或者你想直接偷懒,就用他,他源代码的实现方法已经实现了忽略大小写、驼峰命名转换的映射,不用再自己一个个set属性,方便简单,什么狗屁效率,快速开发就完事了。
public Student getStudentByName(String name) {
String sql = "select id,name from student where name = ?";
Student student = this.jdbcTemplate.queryForObject(sql, new Object[]{name}, new BeanPropertyRowMapper<>(Student.class));
return student;
}
附录BeanPropertyRowMapper源代码实现
initialize函数
- 使用
mappedClass
将po
的class
储存起来 - 把
po
实体类的field小写、field转驼峰小写放入mappedFields
属性,以供后面映射使用
public BeanPropertyRowMapper(Class<T> mappedClass) {
initialize(mappedClass);
}
/**
* Initialize the mapping meta-data for the given class.
* @param mappedClass the mapped class
*/
protected void initialize(Class<T> mappedClass) {
this.mappedClass = mappedClass;
this.mappedFields = new HashMap<>();
this.mappedProperties = new HashSet<>();
PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(mappedClass);
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null) {
// 这里将对象属性名称全部转为小写,放入
this.mappedFields.put(lowerCaseName(pd.getName()), pd);
String underscoredName = underscoreName(pd.getName());
//这里将所以对象属性名称转为驼峰命名放入
if (!lowerCaseName(pd.getName()).equals(underscoredName)) {
this.mappedFields.put(underscoredName, pd);
}
this.mappedProperties.add(pd.getName());
}
}
}
实现mapRow()方法
这个方法,就是将查询数据库字段的值赋予对应对象属性。
/**
* Extract the values for all columns in the current row.
* <p>Utilizes public setters and result set meta-data.
* @see java.sql.ResultSetMetaData
*/
@Override
public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
Assert.state(this.mappedClass != null, "Mapped class was not specified");
T mappedObject = BeanUtils.instantiateClass(this.mappedClass);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(mappedObject);
initBeanWrapper(bw);
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
Set<String> populatedProperties = (isCheckFullyPopulated() ? new HashSet<>() : null);
//这里会根据数据库查询出的字段名称,从mappedFields获取字段,设置value
for (int index = 1; index <= columnCount; index++) {
// 获取数据库结果rs的字段名column
String column = JdbcUtils.lookupColumnName(rsmd, index);
// column 转换小写,变量名=field
String field = lowerCaseName(column.replaceAll(" ", ""));
// 获取column 对应的po的属性的PropertyDescriptor
PropertyDescriptor pd = (this.mappedFields
mappedFields != null ? this.mappedFields.get(field) : null);
if (pd != null) {
try {
// 使用rs、index,pd的class,获取column的值并转换成value
Object value = getColumnValue(rs, index, pd);
if (rowNumber == 0 && logger.isDebugEnabled()) {
logger.debug("Mapping column '" + column + "' to property '" + pd.getName() +
"' of type '" + ClassUtils.getQualifiedName(pd.getPropertyType()) + "'");
}
try {
bw.setPropertyValue(pd.getName(), value);
}
catch (TypeMismatchException ex) {
if (value == null && this.primitivesDefaultedForNullValue) {
if (logger.isDebugEnabled()) {
logger.debug("Intercepted TypeMismatchException for row " + rowNumber +
" and column '" + column + "' with null value when setting property '" +
pd.getName() + "' of type '" +
ClassUtils.getQualifiedName(pd.getPropertyType()) +
"' on object: " + mappedObject, ex);
}
}
else {
throw ex;
}
}
if (populatedProperties != null) {
populatedProperties.add(pd.getName());
}
}
catch (NotWritablePropertyException ex) {
throw new DataRetrievalFailureException(
"Unable to map column '" + column + "' to property '" + pd.getName() + "'", ex);
}
}
else {
// No PropertyDescriptor found
if (rowNumber == 0 && logger.isDebugEnabled()) {
logger.debug("No property found for column '" + column + "' mapped to field '" + field + "'");
}
}
}
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.getName() + "]: " +
this.mappedProperties);
}
return mappedObject;
}