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 ...
随机推荐
- SQL Server 查询性能优化——覆盖索引
覆盖索引又可以称为索引覆盖. 解释一: 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖. 解释二: 索引是高效找到行的一个方法,当能通过检索索引 ...
- LSTM介绍
转自:https://blog.csdn.net/gzj_1101/article/details/79376798 LSTM网络 long short term memory,即我们所称呼的LSTM ...
- C语言复习---获取最小公倍数(公式法:两个数相乘等于最小公倍数乘以最大公约数)
公式法:两个数相乘等于最小公倍数乘以最大公约数 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib ...
- angularJs实现动态增加输入框
摘要:首先,有一个这样的需求,就是说,我点击添加,会动态出现需要输入的输入框.我们需要定义一个对象,类似这种, {spc:{},spctions:[]} 意思是spc对应的是一个对象,spctions ...
- OpenResty 高阶实战之————Redis授权登录使用短连接(5000)和长连接(500W) 使用连接池AB压力测试结果
一.短连接开始测试 ab -n 5000 -c 100 -k 127.0.0.1/test_redis_short #demo1 Concurrency Level: Time taken for t ...
- css 基础1
css 层叠样式表 css手册 样式写在head 中间 style标签 css 样式规则: 选择器 {属性:属性值:属性:属性值} 字体样式属性:font-size 字号大小 color 字体颜色 f ...
- [R语言]关联规则2---考虑items之间严格的时序关系
前面介绍了关联规则1---不考虑用户购买的items之间的时序关系,但在一些情况下用户购买item是有严格的次序关系了,比如在某些休闲游戏中,用户购买了道具A才能购买道具B,且道具A和B只能购买一次, ...
- Linux 网卡流量查看
网卡流量查看 watch more /proc/net/dev # 实时监控流量文件系统 累计值 iptraf # 网卡流量查看工具 nethogs -d 5 eth0 eth1 # 按进程实时统计网 ...
- HDU 2159 FATE (二维背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2159 解题报告:这题实际上是一个二维的背包问题,也可以由01背包扩展而来,01背包用一维数组,可想而知 ...
- python字典转datafarm,pandas
# coding:utf-8 import json import pandas as pd with open("./article_file/all_article.json" ...