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 ...
随机推荐
- 【洛谷P1087】FBI树
题目大意:后序遍历 题解:建立二叉树的码风不知道怎么突然跟线段树一样了...当然,这道题不建树也是可以的. 代码如下 #include <bits/stdc++.h> using name ...
- npm 设置地址
-- 查看当前地址: npm config get registry https://registry.npmjs.org/ npm config get disturl undefined -- 设 ...
- 960CSS框架,之前有用过 了解下框架基本原理
http://blog.sina.com.cn/s/blog_8173443e010160b8.html CSS框架已经出现很长时间了,关于这些框架的用处也被我们讨论了很多遍了.有人说,CSS框架不够 ...
- pthread_detach pthread_create实例
//pool.h 1 #ifndef POOL_H #define POOL_H #include <pthread.h> class pool { public: pool(); ~po ...
- 【CSS】定义元素的位置
CSS定义元素的位置html元素的position属性,有4个属性值,分别是static.relative.fixed.absolute static: 1.默认值,一般不显式设置为static 2. ...
- 在“安装”阶段发生异常。 System.Security.SecurityException: 未找到源,但未能
写Windows服务的时候,运行了一下,就是没反应,命令框一闪而过,查了一下异常,大致是题目的那样.原因是因为权限不足.但是在网上搜的方法都不顶用. 解决方法如下: (1)以管理员身份运行CMD: ( ...
- 说说SQL Server的数据类型
以SQL Server为例,SQL Server的数据类型总共有33种,归纳为一下类别: 精确数字 Unicode字符串 近似数字 二进制字符串 日期和时间 其他数据类型 字符串 1.数字数据类型 ...
- 如何把手机app的视频下载到手机上?网页上的视频怎么下载?
手机上小视频怎么下载?求推荐不需要安装软件的下载方法? 如何把手机app的视频下载到手机上?比如把快手上的视频下载到手机上? 如何免费下载视频? ... 答案当然是用iiiLab提供的在线视频解析下载 ...
- 第11月第31天 keyboardwillshow CGAffineTransformMakeTranslation
1. - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)registerN ...
- 关于markdown文件插入图片遇到的小问题和解决办法
今天用md文件时候发现需要插入图片,以前没做过,所以写下来分享下. 1.先在自己的github上建一个仓库,里面新建个img文件夹存放图片,怎么建仓库可以上网找资料,这里就不详细说明了.建好的仓库如下 ...