JdbcTemplate使用小结
org.springframework.jdbc.core.JdbcTemplate.query(String sql, Object[] args, RowMapper<StaffUnionVO> rowMapper) throws DataAccessException
1.自定义rowMapper
public class StaffUnionVO implements RowMapper<StaffUnionVO>, Serializable {
private static final long serialVersionUID = 1544023434308856628L;
public StaffUnionVO() {
}
private String code;// 员工编码
private String name;// 员工姓名
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}private boolean isExistColumn(ResultSet rs, String columnName) {
try {
if (rs.findColumn(columnName) > 0) {
return true;
}
} catch (SQLException e) {
return false;
}
return false;
}
@Override
public StaffUnionVO mapRow(ResultSet rs, int row) throws SQLException {
StaffUnionVO vo = new StaffUnionVO();
if (isExistColumn(rs, "code"))
vo.setCode(rs.getString("code"));
if (isExistColumn(rs, "name"))
vo.setName(rs.getString("name"));
return vo;
}
}
示例: List<StaffUnionVO> vos = JdbcTemplate.query(sql, new Object[0], new StaffUnionVO() );
2.使用BeanPropertyRowMapper
public class StaffUnionVO implements Serializable {
private static final long serialVersionUID = 1544023434308856628L;
public StaffUnionVO() {
}
private String code;// 员工编码
private String name;// 员工姓名
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
示例:List<StaffUnionVO> vos = JdbcTemplate.query(sql, new Object[0], BeanPropertyRowMapper.newInstance(StaffUnionVO.class));
看一下 BeanPropertyRowMapper.java 的源码,可以学到不少东西。
/*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao (cnfree2000@hotmail.com) ***/
package org.springframework.jdbc.core; import java.beans.PropertyDescriptor;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.NotWritablePropertyException;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils; public class BeanPropertyRowMapper<T> implements RowMapper<T> {
protected final Log logger = LogFactory.getLog(super.getClass());
private Class<T> mappedClass;
private boolean checkFullyPopulated = false; private boolean primitivesDefaultedForNullValue = false;
private Map<String, PropertyDescriptor> mappedFields;
private Set<String> mappedProperties; public BeanPropertyRowMapper() {
} public BeanPropertyRowMapper(Class<T> mappedClass) {
initialize(mappedClass);
} public BeanPropertyRowMapper(Class<T> mappedClass, boolean checkFullyPopulated) {
initialize(mappedClass);
this.checkFullyPopulated = checkFullyPopulated;
} public void setMappedClass(Class<T> mappedClass) {
if (this.mappedClass == null) {
initialize(mappedClass);
} else if (!(this.mappedClass.equals(mappedClass)))
throw new InvalidDataAccessApiUsageException(
new StringBuilder().append("The mapped class can not be reassigned to map to ").append(mappedClass)
.append(" since it is already providing mapping for ").append(this.mappedClass).toString());
} 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(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());
}
}
//在大写的字符前加入下滑线
private String underscoreName(String name) {
if (!(StringUtils.hasLength(name))) {
return "";
}
StringBuilder result = new StringBuilder();
result.append(name.substring(0, 1).toLowerCase());
for (int i = 1; i < name.length(); ++i) {
String s = name.substring(i, i + 1);
String slc = s.toLowerCase();
if (!(s.equals(slc))) {
result.append("_").append(slc);
} else {
result.append(s);
}
}
return result.toString();
} public final Class<T> getMappedClass() {
return this.mappedClass;
} public void setCheckFullyPopulated(boolean checkFullyPopulated) {
this.checkFullyPopulated = checkFullyPopulated;
} public boolean isCheckFullyPopulated() {
return this.checkFullyPopulated;
} public void setPrimitivesDefaultedForNullValue(boolean primitivesDefaultedForNullValue) {
this.primitivesDefaultedForNullValue = primitivesDefaultedForNullValue;
} public boolean isPrimitivesDefaultedForNullValue() {
return this.primitivesDefaultedForNullValue;
} public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
Assert.state(this.mappedClass != null, "Mapped class was not specified");
Object mappedObject = BeanUtils.instantiate(this.mappedClass);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(mappedObject);
initBeanWrapper(bw); ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
Set populatedProperties = (isCheckFullyPopulated()) ? new HashSet() : null;//稀少的特性 for (int index = 1; index <= columnCount; ++index) {
String column = JdbcUtils.lookupColumnName(rsmd, index);
PropertyDescriptor pd = (PropertyDescriptor) this.mappedFields
.get(column.replaceAll(" ", "").toLowerCase());
if (pd == null)
continue;
try {
Object value = getColumnValue(rs, index, pd);
if ((this.logger.isDebugEnabled()) && (rowNumber == 0))
this.logger.debug(
new StringBuilder().append("Mapping column '").append(column).append("' to property '")
.append(pd.getName()).append("' of type ").append(pd.getPropertyType()).toString());
try {
bw.setPropertyValue(pd.getName(), value);
} catch (TypeMismatchException e) {
if ((value == null) && (this.primitivesDefaultedForNullValue)) {
this.logger.debug(new StringBuilder().append("Intercepted TypeMismatchException for row ")
.append(rowNumber).append(" and column '").append(column).append("' with value ")
.append(value).append(" when setting property '").append(pd.getName())
.append("' of type ").append(pd.getPropertyType()).append(" on object: ")
.append(mappedObject).toString());
} else {
throw e;
}
}
if (populatedProperties != null) {
populatedProperties.add(pd.getName());
}
} catch (NotWritablePropertyException ex) {
throw new DataRetrievalFailureException(new StringBuilder().append("Unable to map column ")
.append(column).append(" to property ").append(pd.getName()).toString(), ex);
} } if ((populatedProperties != null) && (!(populatedProperties.equals(this.mappedProperties)))) {
throw new InvalidDataAccessApiUsageException(new StringBuilder()
.append("Given ResultSet does not contain all fields necessary to populate object of class [")
.append(this.mappedClass).append("]: ").append(this.mappedProperties).toString());
} return mappedObject;
} protected void initBeanWrapper(BeanWrapper bw) {
} protected Object getColumnValue(ResultSet rs, int index, PropertyDescriptor pd) throws SQLException {
return JdbcUtils.getResultSetValue(rs, index, pd.getPropertyType());
} public static <T> BeanPropertyRowMapper<T> newInstance(Class<T> mappedClass) {
BeanPropertyRowMapper newInstance = new BeanPropertyRowMapper();
newInstance.setMappedClass(mappedClass);
return newInstance;
}
}
1.通过PropertyDescriptor反映射调用set和get方法
2.HashSet、TreeSet equals方法
AbstractSet.java
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Set))
return false;
Collection<?> c = (Collection<?>) o;
if (c.size() != size())
return false;
try {
return containsAll(c);
} catch (ClassCastException unused) {
return false;
} catch (NullPointerException unused) {
return false;
}
}
3.BeanPropertyRowMapper checkFullyPopulated 默认是false,这样的话如果 sql结果集中的字段 和 DTO 字段不匹配,就会抛异常。可以手动设置这个值。
4.PO BO VO DTO POJO DAO概念及其作用(附转换图)
JdbcTemplate使用小结的更多相关文章
- Spring JdbcTemplate操作小结
Spring 提供了JdbcTemplate 来封装数据库jdbc操作细节: 包括: 数据库连接[打开/关闭] ,异常转义 ,SQL执行 ,查询结果的转换 使用模板方式封装 jdbc数据库操作-固定流 ...
- Spring JdbcTemplate小结
提供了JdbcTemplate 来封装数据库jdbc操作细节: 包括: 数据库连接[打开/关闭] ,异常转义 ,SQL执行 ,查询结果的转换 使用模板方式封装 jdbc数据库操作-固定流程的动作,提供 ...
- spring jdbctemplate源码跟踪
闲着没事,看看源码也是一种乐趣! java操作数据库的基本步骤都是类似的: 1. 建立数据库连接 2. 创建Connection 3. 创建statement或者preparedStateement ...
- 编写DAO,通过JdbcTemplate操作数据库的实践
目的:编写DAO,通过Spring中的JdbcTemplate,对数据库中的学生数据进行增删改查操作. 要操作的数据库表结构为: 一.大体框架 1.要利用JdbcTemplate,首先要添加Sprin ...
- 21JDBC_事务&JDBCTemplate
一.JDBC_事务 通过JDBC来操作银行转账的事务 1.API介绍 Connection接口中与事务有关的方法 void setAutoCommit(boolean autoCommit) ...
- 初识JdbcTemplate
1.spring配置文件里注冊:參照使用 Spring jdbcTemplate 进一步简化 JDBC 操作 2.写javabean 3.写rowmapper(依据javabean来封装结果集) 4. ...
- SpringBoot 系列教程之事务隔离级别知识点小结
SpringBoot 系列教程之事务隔离级别知识点小结 上一篇博文介绍了声明式事务@Transactional的简单使用姿势,最文章的最后给出了这个注解的多个属性,本文将着重放在事务隔离级别的知识点上 ...
- SpringBoot2.x入门教程:引入jdbc模块与JdbcTemplate简单使用
这是公众号<Throwable文摘>发布的第23篇原创文章,收录于专辑<SpringBoot2.x入门>. 前提 这篇文章是<SpringBoot2.x入门>专辑的 ...
- JdbcTemplate+PageImpl实现多表分页查询
一.基础实体 @MappedSuperclass public abstract class AbsIdEntity implements Serializable { private static ...
随机推荐
- oracle执行update语句时卡住问题分析及解决办法
转载:http://www.jb51.net/article/125754.htm 这篇文章主要介绍了oracle执行update语句时卡住问题分析及解决办法,涉及记录锁等相关知识,具有一定参考价值, ...
- opencv ---getRotationMatrix2D函数
getRotationMatrix2D函数 主要用于获得图像绕着 某一点的旋转矩阵 Mat getRotationMatrix2D(Point2f center, double angle, dou ...
- cygwin简介及使用
一个是真实的假货,一个是冒牌的真品前指 Cygwin,后指 Linux/VMWare 路不管平还是陡,终归你要走的,如果你愿意投入到linux开发的社群中来,不会安装linux系统,不会配置工作环境是 ...
- HDU 6158 笛卡尔定理+韦达定理
The Designer Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- linux常用端口查询
0 | 无效端口,通常用于分析操作系统1 | 传输控制协议端口服务多路开关选择器2 | 管理实用程序3 | 压缩进程5 | 远程作业登录7 | 回显9 | 丢弃11 | 在线用户13 | 时间17 | ...
- Spark记录-Spark on mesos配置
1.安装mesos #用centos6的源yum安装 # rpm -Uvh http://repos.mesosphere.io/el/6/noarch/RPMS/mesosphere-el-repo ...
- 流媒体技术学习笔记之(九)减少VLC 延迟的方法
之前写过一篇关于在Linux平台上编译Android平台上VLC播放器源代码的文章,vlc这款播放器非常优秀而且是开源的,它的核心是开源视频编解码库ffmpeg.而且这款播放器还支持RTSP协议,这个 ...
- springboot(五):springboot整合shiro-登录认证和权限管理
http://z77z.oschina.io/ http://www.cnblogs.com/aqsunkai/category/982003.html https://www.cnblogs.com ...
- Zookeeper笔记之四字命令
Zookeeper支持一些命令用来获取服务的状态和相关信息,因为这些命令都是四个字母的,所以一般称为四字命令. 四字命令可以使用telnet或者nc向服务器提交,使用下面这个脚本可以当做是一个简易的客 ...
- MySQL-数据操作-增删改查
1.增加: insert into 表 (列名,列名...) values (值,值,值...) insert into 表 (列名,列名...) values (值,值,值...),(值,值,值.. ...