spring data之JDBCTemplate学习笔记
一、spring 数据访问哲学
1、为避免持久化的逻辑分散在程序的各个组件中,数据访问的功能应到放到一个或多个专注于此的组件中,一般称之为数据访问对象(data access object,DAO)。
2、良好的的Repository应以接口的形式向外暴露出去,服务对象通过接口访问Repository对象,这样做可以使服务对象很方便的进行测试,甚至可以创建mock来进行测试。
3、数据访问层应该是与持久化技术无关的方式来进行访问的,这样可以使得切换底层的持久层框架对程序的其他地方所带来的影响最小。

服务对象与Repository之间的关系,服务对象不会处理数据访问,而是将其委托给Repository。
二、spring 的数据访问异常体系
在使用原生的JDBC访问数据时,应用程序必须去捕获JDBC抛出的异常SQLException,而且大多数情况下,异常不会告诉你哪里出了问题、如何处理。
spring JDBC提供的数据访问异常体系解决了这两个问题,spring提供了很多数据访问异常,分别描述了他们抛出时所对应的问题。spring为读取和写入数据的几乎所有错误都提供了异常。而且spring 提供的异常均继承自DataAccessException,该异常为运行时异常,所以在代码中不必强制去捕获。
这样做的好处是:
- 开发者可以从底层繁琐复杂的技术细节中解脱出来。
- 开发者可以选择自己感兴趣的异常进行处理 。
常见的spring异常
| 异常类 | 说明 |
| CleanupFailureDataAccessException | 执行 DAO 操作成功,但在释放数据资源时发生异常,如关闭 Connection 时发生异常。 |
| ConcurrencyFailureException | 并发地操作数据时发生异常,如无法获取乐观锁或悲观锁时、死锁引发的失败等场景。 |
| DataAccessResourceFailureException | 访问数据资源失败,如无法获取数据连接,无法获取 Hibernate 的会话等场景。 |
| DataRetrievalFailureException | 获取数据失败,如找不到对应主键的数据或使用了错误的列索引等场景。 |
| DataSourceLookupFailureException | 无法从 JNDI 中查找到数据源。 |
| DataIntegrityViolationException | 数据操作违反了数据一致性限制时抛出,如插入重复的主键或引用不存在的外键场景。 |
| InvalidDataAccessApiUsageException | 不正确地调用某一种持久化技术时抛出,如在 Spring JDBC 中查询对象在调用前没有事先进行编译操作,就会抛出该异常。这种异常主要是因为不正确地使用持久化技术而产生的。 |
| InvalidDataAccessResourceUsageException | 在访问数据源时使用了不正确的方法时抛出,如写错 SQL 语句。 |
| PermissionDeniedDataAccessException | 数据访问权限不足时抛出。如仅拥有只读权限却试图更改数 |
| UncategorizedDataAccessException | 其它未被分类的异常。 |
| ................ | ................. |
为了使用spring 的数据访问异常,必须使用spring支持的数据访问模板。
三、数据访问模板
模板方法将过程中与特定实现相关的部分委托给接口,接口的不同实现定义了过程中的具体行为。(设计模式中模板模式的案例?没看过源码,不确定是不是
spring在进行数据访问过程中将固定的和可变的明确划分为两个不同的类:模板和回调。模板管理过程中固定的部分,回调处理自定义的数据访问代码。

模板与回调的职责,模板类处理固定部分:事物控制、管理资源以及异常处理,回调处理语句、绑定参数以及整理结果集。
如果直接使用JDBC,可以使用JdbcTemplate,若使用ORM框架,可以考虑使用JpaTemplate或者HibernateTemplate等。
| 模板类 | 用途 |
| jdbc.core.JdbcTemplate | JDBC链接 |
| jdbc.core.namedparam.NamedParameterJdbcTemplate | 支持命名参数的JDBC链接 |
| orm.ibatis.SqlMapClientTemplate | IBATIS SqlMap客户端 |
| orm.Jpa.JpaTemplate | java持久化API的实体管理器 |
| ............ | ........... |
spring 提供的数据访问模板
四、数据源的配置
spring多种数据源配置方式
- JDBC驱动程序定义的数据源
- JNDI查找的数据源
- 连接池的数据源
考虑到现在基本都是spring boot的天下了,基本也不使用XML配置了,故此仅给出java配置。
1、JNDI数据源(没用过仅做记录)
java配置:
@Bean
public JndiObjectFactoryBean dataSource(){
JndiObjectFactoryBean factoryBean = new JndiObjectFactoryBean();
factoryBean.setJndiName("jdbc/myProjectDS");//指定JNDI中资源的名称。
factoryBean.setResourceRef(true);//若运行在java服务器中需要设置为true
factoryBean.setProxyInterface(DataSource.class);
return factoryBean;
}
2、数据源连接池
常见的数据库连接池有以下几个:
- Apache commons DBCP
- c3p0
- BoneCP
- Druid
java配置:
@Bean
public BasicDataSource dataSource(){
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("org.h2.Driver");
ds.setUrl("jdbc:h2:tcp://localhost/~/test");
ds.setUsername("root");
ds.setPassword("123");
ds.setInitialSize(5);
ds.setMaxActive(10);
return ds;
}
3、基于JDBC的驱动的数据源
这种数据源是最简单的配置方式,spring 提供了三个这样的数据源类
- DriverManagerDataSource:在每个连接请求时都会返回一个新建的链接
- simpleDriverDataSOurce:与DriverManagerDataSource类似,不同的是他直接使用JDBC驱动
- SingleConnectionDataSource:在每个连接请求时都会返回同一个连接,可认为是只有一个连接的池,该类不适合多线程的应用程序。
@Bean
public DataSource dataSource(){
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName("org.mysql.Driver");
driverManagerDataSource.setUrl("url");
driverManagerDataSource.setUsername("root");
driverManagerDataSource.setPassword("1");
return driverManagerDataSource;
}
4、嵌入式数据源,H2
嵌入式数据源作为应用的一部分运行,而不是独立的数据库服务器,对生产环境没有啥用处,但对开发和测试而言是非常好的方案
@Bean
public DataSource dataSource(){
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:schema.sql")
.addScript("classpath:test-data.sql")
.build();
}
五、使用JDBC模板
spring共提供三个JDBC模板:
- JdbcTemplate最基本的springJDBC模板,支持简单的JDBC数据库访问功能以及基于索引的参数查询
- NamedParameterJdbcTemplate:该模板可以将值以命名参数的形式绑定到SQL中,而非简单的索引值。
- SimpleJdbcTepmlate:已被废弃,不做介绍。
1、首先需要配置一个JDBCTemplate,只需为期设置DataSource即可。
代码如下
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}
2、编写数据访问相关接口及实现类
图省事,省去了接口类,实际使用过程中自行添加。
UserRepository类
@Repository
public class UserRepository {
private JdbcOperations jdbcOperations;
@Autowired
public UserRepository(JdbcOperations jdbcOperations) {
this.jdbcOperations = jdbcOperations;
} public void addUser(User user){
jdbcOperations.update("insert into user (username,password,email) values(?,?,?) ",
user.getUsername(),user.getPassword(),user.getEmail());
}
public User findUser(String id){
return jdbcOperations.queryForObject("select * from user where id = "+id,(resultSet, i) -> User.builder()
.username(resultSet.getString("username"))
.password(resultSet.getString("password"))
.email(resultSet.getString("email"))
.id(resultSet.getLong("id"))
.build());
}
}
UserController类:
@RestController
public class UserController {
private final UserRepository repository; @Autowired
public UserController(UserRepository repository) {
this.repository = repository;
} @GetMapping("/addUser")
public String aa(){
repository.addUser(User.builder()
.email("abc@aa.com")
.username("tom")
.password("123456")
.build());
return "succ";
} @GetMapping("/query/{id}")
public User queryUser(@PathVariable String id){
return repository.findUser(id);
}
}
NamedParameterJdbcTemplate简单使用:
配置
@Bean
public NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource){
return new NamedParameterJdbcTemplate(dataSource);
}
使用map绑定参数
public void addUser(User user){
Map<String,Object> data = new HashMap<>(8);
data.put("username","zhangsan");
data.put("password","123456");
data.put("email","asd@asd.com");
data.put("id", 123432);
jdbcOperations.update("insert into user(username,password,email,id) values (:username,:password,:email,:id)",data);
}
JdbcOperations API(下次有空了总结哈):https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcOperations.html
Z、参考资料
https://blog.csdn.net/deniro_li/article/details/82820966
spring data之JDBCTemplate学习笔记的更多相关文章
- JdbcTemplate学习笔记
JdbcTemplate学习笔记 1.使用JdbcTemplate的execute()方法执行SQL语句 Java 代码 jdbcTemplate.execute("CREATE TABLE ...
- Spring实战第一章学习笔记
Spring实战第一章学习笔记 Java开发的简化 为了降低Java开发的复杂性,Spring采取了以下四种策略: 基于POJO的轻量级和最小侵入性编程: 通过依赖注入和面向接口实现松耦合: 基于切面 ...
- Spring实战第八章学习笔记————使用Spring Web Flow
Spring实战第八章学习笔记----使用Spring Web Flow Spring Web Flow是一个Web框架,它适用于元素按规定流程运行的程序. 其实我们可以使用任何WEB框架写流程化的应 ...
- #Spring实战第二章学习笔记————装配Bean
Spring实战第二章学习笔记----装配Bean 创建应用对象之间协作关系的行为通常称为装配(wiring).这也是依赖注入(DI)的本质. Spring配置的可选方案 当描述bean如何被装配时, ...
- Spring Cloud微服务学习笔记
Spring Cloud微服务学习笔记 SOA->Dubbo 微服务架构->Spring Cloud提供了一个一站式的微服务解决方案 第一部分 微服务架构 1 互联网应用架构发展 那些迫使 ...
- spring data jpa入门学习
本文主要介绍下spring data jpa,主要聊聊为何要使用它进行开发以及它的基本使用.本文主要是入门介绍,并在最后会留下完整的demo供读者进行下载,从而了解并且开始使用spring data ...
- Spring Data Jpa 入门学习
本文主要讲解 springData Jpa 入门相关知识, 了解JPA规范与Jpa的实现,搭建springboot+dpringdata jpa环境实现基础增删改操作,适合新手学习,老鸟绕道~ 1. ...
- Spring jdbctemplate学习笔记
/*List<?> config = getDB(" select t.datavalue from sys_config t where t.configid = '15' & ...
- Spring 4.0.2 学习笔记(2) - 自动注入及properties文件的使用
接上一篇继续, 学习了基本的注入使用后,可能有人会跟我一样觉得有点不爽,Programmer的每个Field,至少要有一个setter,这样spring配置文件中才能用<property> ...
随机推荐
- bzoj 1242 弦图判定 MCS
题目大意: 给定一张无向图,判断是不是弦图. 题解: 今天刚学了<弦图与区间图> 本来写了一个60行+的学习笔记 结果因为忘了保存重启电脑后被还原了... 那就算了吧. MCS最大势算法, ...
- Java常见设计模式之单例模式
1.何为单例模式? 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的 ...
- python中报中文编码异常,Non-ASCII ,but no encoding declared
异常信息: SyntaxError: Non-ASCII character '\xe5' in file a.py on line 9, but no encoding declared; see ...
- JS判断提交表单不能为空 等的验证
转自:https://blog.csdn.net/qiu512300471/article/details/23259811 <script type="text/javascript ...
- python 基础 操作文件和目录
获得当前目录路径 :os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir() 删除一个文件:os.remove(filename) 删除多个空目录 :os.removefir ...
- Android 使用技巧
1.Android 模拟器使用虚拟SD卡 首先创建一个虚拟的SD卡 mksdcard 500M ~/sdcard.img 启动模拟器的时候指定虚拟的SD卡 emulator -sdcard ~/sdc ...
- cadence spb 16.5 破解过程实例和使用感受_赤松子耶_新浪博客
cadence spb 16.5 破解过程实例和使用感受_赤松子耶_新浪博客 Cadence Allegro16.5详细安装具体的步骤 1.下载SPB16.5下来后,点setup.exe,先安装第一项 ...
- Http协议以及模拟http请求发送数据
1 为什么要使用http协议 假设我现在有两个客户端浏览器,一个是google,一个是IE浏览器:我现在有两个服务器,一个是tomcat,一个是JBoss;在最初的情况下是:如果google要往tom ...
- 18_andriod常用布局&内容回顾
线性布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:androi ...
- Centos 6.5 hadoop 2.2.0 全分布式安装
hadoop 2.2.0 cluster setup 环境: 操作系统:Centos 6.5 jdk:jdk1.7.0_51 hadoop版本:2.2.0 hostname ip master ...