Spring的JdbcTemplate使用教程
Spring对数据库的操作在jdbc上面做了基本的封装,让开发者在操作数据库时只需关注SQL语句和查询
结果处理器,即可完成功能(当然,只使用JdbcTemplate,还不能摆脱持久层实现类的编写)。
在配合spring的IoC功能,可以把DataSource注册到JdbcTemplate之中。同时利用spring基于
aop的事务即可完成简单的数据库CRUD操作。
JdbcTemplate的限定命名为org.springframework.jdbc.core.JdbcTemplate。要使用
JdbcTemlate需要导入spring-jdbc和spring-tx两个坐标。
方法说明:
execute方法:
可以用于执行任何SQL语句,一般用于执行DDL语句;
update方法及batchUpdate方法:
update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语
句;
query方法及queryForXXX方法:
用于执行查询相关语句;
call方法:
用于执行存储过程、函数相关语句。
使用案例
项目结构:

项目代码
POM.XML
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
</dependencies>
实体类:
public class Account implements Serializable {
private Integer id;
private String name;
private Double money;
//省略getter setter
}
public class Userinfo implements Serializable {
private Integer id;
private byte[] images; // 对应mysql数据库longBlob类型
private String description; // 对应表的longText类型
// 省略getter setter
}
相对应account表和userinfo表
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_ioc
jdbc.username=root
jdbc.password=admin
jbbc配置类:
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
/**
* 创建数据源并存入Ioc容器
* @return
*/
@Bean
public DataSource createDataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
/**
* 创建JdbcTemplate对象
* @param dataSource
* @return
*/
@Bean
public JdbcTemplate createJdbcTemplate(DataSource dataSource){
return new JdbcTemplate(dataSource);
}
// 操作clob和blob
@Bean
public LobHandler createLobHandler(){
return new DefaultLobHandler();
}
}
主配置类:
@Configuration
@Import(JdbcConfig.class)
@PropertySource("classpath:jdbc.properties")
public class SpringConfiguration {
}
测试类:
/**
*注释部分为不同写法
* 测试JdbcTemplate的使用
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class SpringJdbcTemplateTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testSave(){
jdbcTemplate.update("insert into account(money,name)values(?,?)",6789d,"userTest");
}
@Test
public void testUpdate(){
jdbcTemplate.update("update account set name=?,money=? where id=?","testZZZ",23456d,3);
}
@Test
public void testDelete(){
jdbcTemplate.update("delete from account where id = ? ",4);
}
@Test
public void testFindOne(){
// List<Account> accounts = jdbcTemplate.query("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),1);
// System.out.println(accounts.isEmpty()?"empty":accounts.get(0));
// Account account = jdbcTemplate.queryForObject("select * from account where id = ?",new BeanPropertyRowMapper<Account>(Account.class),1);
// System.out.println(account);
Account account = jdbcTemplate.query("select * from account where id = ?", new ResultSetExtractor<Account>() {
@Override
public Account extractData(ResultSet rs) throws SQLException, DataAccessException {
Account account1 = null;
//1.判断结果集能往下走
if(rs.next()){
account1 = new Account();
account1.setId(rs.getInt("id"));
account1.setName(rs.getString("name"));
account1.setMoney(rs.getDouble("money"));
}
return account1;
}
}, 1);
System.out.println(account);
}
@Test
public void testFindAll(){
List<Account> accountList = jdbcTemplate.query("select * from account where money > ?",new BeanPropertyRowMapper<Account>(Account.class),999d);
for(Account account : accountList){
System.out.println(account);
}
}
@Test
public void testFindCount(){
Integer count = jdbcTemplate.queryForObject("select count(*) from account where money > ?",Integer.class,999d);
System.out.println(count);
}
@Test
public void testQueryForList(){
/**
* 得到某个特定类型的集合。类型是方法的第二个参数指定的
*/
List<Double> list = jdbcTemplate.queryForList("select money from account where money > ?",Double.class,999d);
for(Double money : list){
System.out.println(money);
}
// List<Map<String,Object>> list = jdbcTemplate.queryForList("select * from account where money > ? ",999d);
// for(Map<String,Object> map : list){
// for(Map.Entry<String,Object> me : map.entrySet())
// System.out.println(me.getKey()+","+me.getValue());
// }
}
@Test
public void testQueryForMap(){
Map<String,Object> map = jdbcTemplate.queryForMap("select * from account where id = ?",1);
for(Map.Entry<String,Object> me : map.entrySet()) {
System.out.println(me.getKey()+","+me.getValue());
}
}
@Test
public void testQueryForRowSet(){
SqlRowSet rowSet = jdbcTemplate.queryForRowSet("select * from account where money > ?",999d);
System.out.println(rowSet);
while(rowSet.next()){
String name = rowSet.getString("name");
System.out.println(name);
}
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class SpringLobTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private LobHandler lobHandler;
@Test
public void testWrite(){
try {
//准备images的字节数组
Resource resource = new FileSystemResource("E:\\6.jpg");
byte[] images = FileCopyUtils.copyToByteArray(resource.getFile());
//准备description
String description = "BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器。\n" +
"在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。\n" +
"BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,\n" +
"由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)。\n" +
"根据Eric Raymond的说法,处理BLOB的主要思想就是让文件处理器(如数据库管理器)不去理会文件是什么,\n" +
"而是关心如何去处理它。但也有专家强调,这种处理大数据对象的方法是把双刃剑,\n" +
"它有可能引发一些问题,如存储的二进制文件过大,会使数据库的性能下降。\n" +
"在数据库中存放体积较大的多媒体对象就是应用程序处理BLOB的典型例子。";
//1.创建Userinfo
Userinfo userinfo = new Userinfo();
userinfo.setImages(images);
userinfo.setDescription(description);
jdbcTemplate.execute("insert into userinfo(images,description)values(?,?)", new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
@Override
protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException, DataAccessException {
lobCreator.setBlobAsBytes(ps, 1, userinfo.getImages());
lobCreator.setClobAsString(ps, 2, userinfo.getDescription());
}
});
}catch (Exception e){
e.printStackTrace();
}
}
@Test
public void testRead(){
// Userinfo userinfo = jdbcTemplate.queryForObject("select * from userinfo where id = ?",new BeanPropertyRowMapper<Userinfo>(Userinfo.class),1);
Userinfo userinfo = jdbcTemplate.query("select * from userinfo where id = ?", new ResultSetExtractor<Userinfo>() {
@Override
public Userinfo extractData(ResultSet rs) throws SQLException, DataAccessException {
Userinfo userinfo1 = null;
if(rs.next()){
userinfo1 = new Userinfo();
userinfo1.setId(rs.getInt("id"));
userinfo1.setImages(lobHandler.getBlobAsBytes(rs,"images"));
userinfo1.setDescription(lobHandler.getClobAsString(rs,"description"));
}
return userinfo1;
}
}, 1);
System.out.println(userinfo);
}
}
具名参数使用
在经典的 JDBC 用法中, SQL 参数是用占位符 ? 表示,并且受到位置的限制. 定位参数的问题在于,一旦参数的顺序发生变化, 就必须改变参数绑定.在 Spring JDBC 框架中, 绑定 SQL 参数的另一种选择是使用具名参数(namedparameter).那么什么是具名参数?具名参数: SQL 按名称(以冒号开头)而不是按位置进行指定. 具名参数更易于维护, 也提升了可读性. 具名参数由框架类在运行时用占位符取代具名参数只NamedParameterJdbcTemplate 中得到支持。NamedParameterJdbcTemplate可以使用全部jdbcTemplate方法。
在jdbcConfig中加入组件
@Bean
public NamedParameterJdbcTemplate createNamedParameterJdbcTemplate(JdbcTemplate jdbcTemplate){
return new NamedParameterJdbcTemplate(jdbcTemplate);
}
测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class SpringNamedParameterJdbcTemplateTest {
@Autowired
private NamedParameterJdbcTemplate jdbcTemplate;
@Test
public void testFind(){
Map<String,Object> map = new HashMap<>();
map.put("id",1);
Account account = jdbcTemplate.queryForObject("select * from account where id = :id",map,new BeanPropertyRowMapper<Account>(Account.class));
System.out.println(account);
}
@Test
public void testSave(){
Account account = new Account();
account.setName("NamedParameterJdbcTemplate");
account.setMoney(12345d);
BeanMap beanMap = BeanMap.create(account);
jdbcTemplate.update("insert into account(name,money)values(:name,:money)",beanMap);
}
}
Spring的JdbcTemplate使用教程的更多相关文章
- Spring利用JDBCTemplate实现批量插入和返回id
1.先介绍一下java.sql.Connection接口提供的三个在执行插入语句后可取的自动生成的主键的方法: //第一个是 PreparedStatement prepareStatement(St ...
- Spring 中jdbcTemplate 实现执行多条sql语句
说一下Spring框架中使用jdbcTemplate实现多条sql语句的执行: 很多情况下我们需要处理一件事情的时候需要对多个表执行多个sql语句,比如淘宝下单时,我们确认付款时要对自己银行账户的表里 ...
- spring使用jdbcTemplate和jdbcdaosupport和namedparameter
jdbcTemplate: 首先连接数据库 <!-- 导入外部文件 --> <context:property-placeholder location="classpat ...
- Spring Security3 - MVC 整合教程
下面我们将实现关于Spring Security3的一系列教程. 最终的目标是整合Spring Security + Spring3MVC 完成类似于SpringSide3中mini-web的功能 ...
- Spring Cloud Alibaba基础教程:Nacos的集群部署
继续说说生产环境的Nacos搭建,通过上一篇<Spring Cloud Alibaba基础教程:Nacos的数据持久化>的介绍,我们已经知道Nacos对配置信息的存储原理,在集群搭建的时候 ...
- Spring Cloud Alibaba基础教程:Nacos的数据持久化
前情回顾: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方式> ...
- Spring Cloud Alibaba基础教程:Nacos配置的多文件加载与共享配置
前情回顾: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方式> ...
- Spring Cloud Alibaba基础教程:Nacos配置的多环境管理
前情回顾: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方式> ...
- Spring Cloud Alibaba基础教程:Nacos配置的加载规则详解
前情回顾: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方式(Res ...
随机推荐
- 2019 安易迅java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.安易迅等公司offer,岗位是Java后端开发,因为发展原因最终选择去了安易迅,入职一年时间了,也成为了面试官 ...
- html、css/bootStrap、js/Jquery、ajax与json数据交互总结
设计个个人网站,利用CSS.JavaScript.HTML5.jQuery库和AJAX等 实现网站各功能模块,下面介绍我设计的网站各大功能模块: 个人简历模块: 包涵个人基本信息(利用CSS的flo ...
- c# 读取数据库得到字符串
public string GetProductType(string connectionString, string barCode) { string pro ...
- C# Net 比较2个字符串的相似度(使用余弦相似度)
C# Net 比较2个字符串的相似度(使用余弦相似度) 复制代码使用: /// <summary> /// 比较2个字符串的相似度(使用余弦相似度) /// </summary> ...
- Linux高级运维 第八章 部署docker容器虚拟化平台
8.1 Docker概述 实验环境: CENTOS7.4-63 64位 Dcoker概述 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到 ...
- Eric6安装问题解决
按照http://eric-ide.python-projects.org/eric-download.html中的说明,执行命令:python install.py 却遇到下面的问题: Compil ...
- Spring的感知能力 Aware
在 Spring 框架中有一个 org.springframework.beans.factory.Aware 接口, Aware 是感知感应的意思,那么此接口的作用就是为 Spring 中的 bea ...
- Jupyter Notebook---不需认证,与nginx搭配远程访问及下载
如果默认启动,jupyter notebook需要token或是password登陆,且在nginx后面,下载会报403限制. Blocking Cross Origin request from h ...
- Codeforces Good Bye 2016 E. New Year and Old Subsequence
传送门 题意: 给出一个长度为\(n\)的串,现在有\(q\)个询问,每个询问是一个区间\([l,r]\),要回答在区间\([l,r]\)中,最少需要删多少个数,满足区间中包含\(2017\)的子序列 ...
- 201671010449 杨天超 实验十四 团队项目评审&课程学习总结
项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 作业学习目标 1.掌握软件评审流程及内容 2.个人总结 实验一问题解答 实验一问题链接:https://ww ...