JDBCTemplate相对于其他ORM框架来说是极其简单和极容易上手的一个数据库连接的封装。在学习JDBCTemplate之前,我们先来了解一下JDBC相关的概念和操作。
JDBC简介
Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。它由一组用Java语言编写的类和接口组成。通常说的JDBC是面向关系型数据库的。
通过下图,我们将了解JDBC在整个系统中的位置。

在整个系统中,java应用程序通过JDBC提供的API连接到JDBC Driver,而这些JDBC驱动器的具体实现是由各大数据库厂家针对JDBC规范而编写,并提供给使用者。
使用JDBC时的实例代码如下:
public class DbUtil {private static final String URL = "jdbc:mysql://127.0.0.1:3306/spring";private static final String USER = "root";private static final String PASSWORD = "123_123";public static void main(String[] args) {Connection conn = null;try {//1.加载驱动程序Class.forName("com.mysql.jdbc.Driver");//2. 建立数据库连接conn = DriverManager.getConnection(URL, USER, PASSWORD);//3.创建数据库操作对象,实现增删改查Statement stmt = conn.createStatement();//4.定义操作的SQL语句//5.执行数据库操作ResultSet rs = stmt.executeQuery("SELECT order_no, amount FROM tb_order");//6.获取并操作结果集while (rs.next()) {System.out.println("订单号:" + rs.getString("order_no") + " 金额:" + rs.getInt("amount"));}} catch (Exception e) {// 日志信息} finally {// 7、关闭资源if (conn != null) {try {conn.close();} catch (SQLException e1) {e1.printStackTrace();}}}}}
通过上述操作,我们会发现整个操作步骤非常复杂,而且涉及到数据库驱动加载、建立链接、执行操作、解析结果、资源的关闭、异常处理等多个步骤。
JDBCTemplate
针对JDBC操作弊端,Spring对数据库的操作在jdbc上面做了再次的封装,使用Spring的注入功能,可以把DataSource注册到JdbcTemplate之中。
JdbcTemplate全限定命名为org.springframework.jdbc.core.JdbcTemplate。
JdbcTemplate主要方法
JdbcTemplate主要提供以下五类方法:
-
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
-
update方法及batchUpdate方法。update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
-
query方法及queryForXXX方法,用于执行查询相关语句;
-
call方法:用于执行存储过程、函数相关语句。
Spring Boot集成
添加依赖
首先添加依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
其中spring-boot-starter-jdbc引入spring jdbc相关依赖,mysql-connector-java引入关于mysql连接相关实现的jar包。
在IDE中点击spring-boot-starter-jdbc,会导航到该starter的依赖,在其中我们可以下面的依赖:
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.2.RELEASE</version>
<scope>compile</scope>
</dependency>
其中spring-jdbc是spring为jdbc提供的工具包,而HikariCP是数据库连接池。号称是“世界上最快”的连接池。
实体类
针对数据库表结构,我们创建如下实体类(使用了Lombok):
@Data
public class Order {
private int id;
private String orderNo;
private int amount;
}
配置数据库连接池
在application.properties中配置数据库连接池
spring.datasource.url=jdbc:mysql://localhost:3306/spring?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.username=root
spring.datasource.password=123_123
# Spring Boot 2.1.0 中,com.mysql.jdbc.Driver 已经过期
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
其中注意不同版本推荐的驱动类。
使用JDBCTemplate
经过以上步骤,我们就可以在Service层或DAO层(根据系统情况调整)中使用JDBCTemplate。
这里OrderService接口定义如下:
package com.secbro.service;
import com.secbro.model.Order;
import java.util.List;
/**
* @author sec
* @version 1.0
* @date 2020/2/29 8:58 AM
**/
public interface OrderService {
/**
* 创建订单
* @param order 订单信息
* @return 记录数
*/
int save(Order order);
/**
* 更新订单
* @param order 订单信息
* @return 记录数
*/
int update(Order order);
/**
* 删除
* @param id id
* @return 条数
*/
int delete(int id);
/**
* 根据ID查询
* @param id 订单id
* @return 订单详情
*/
Order findById(int id);
/**
* 查询所有
* @return 列表
*/
List<Order> findAll();
}
接口的具体实现如下:
package com.secbro.service.impl;
import com.secbro.model.Order;
import com.secbro.service.OrderService;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
/**
* @author sec
* @version 1.0
* @date 2020/2/29 8:58 AM
**/
@Service("orderService")
public class OrderServiceImpl implements OrderService {
@Resource
private JdbcTemplate jdbcTemplate;
@Override
public int save(Order order) {
return jdbcTemplate.update("insert into tb_order(order_no, amount) values(?, ?)", order.getOrderNo(),
order.getAmount());
}
@Override
public int update(Order order) {
return jdbcTemplate.update("update tb_order set amount = ? where id = ?", order.getAmount(), order.getId());
}
@Override
public int delete(int id) {
return jdbcTemplate.update("delete from tb_order where id = ?", id);
}
@Override
public Order findById(int id) {
return jdbcTemplate.queryForObject("select * from tb_order where id = ?", new Object[]{id},
new BeanPropertyRowMapper<>(Order.class));
}
@Override
public List<Order> findAll() {
return jdbcTemplate.query("select * from tb_order", new OrderRowMapper());
}
/**
* RowMapper 可以将数据中的每一行数据封装成用户定义的类,实现RowMapper接口的mapRow方法
*/
class OrderRowMapper implements RowMapper<Order> {
@Override
public Order mapRow(ResultSet rs, int rowNum) throws SQLException {
// 对数据的返回处理
Order order = new Order();
order.setId(rs.getInt("id"));
order.setOrderNo(rs.getString("order_no"));
order.setAmount(rs.getInt("amount"));
return order;
}
}
}
可以看到,直接使用@Resource将JdbcTemplate注入对应的类中便可以使用了。
单元测试
相关的单元测试方法,如下(基于Junit5):
package com.secbro.service;
import com.secbro.model.Order;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.List;
/**
* @author zzs
*/
@Slf4j
@SpringBootTest
class OrderServiceTest {
@Resource
private OrderService orderService;
@Test
void save() {
Order order = new Order();
order.setOrderNo("N003");
order.setAmount(10000);
orderService.save(order);
}
@Test
void update() {
Order order = new Order();
order.setId(1);
order.setOrderNo("N001");
order.setAmount(8888);
orderService.update(order);
}
@Test
void delete() {
orderService.delete(2);
}
@Test
void findById() {
Order order = orderService.findById(3);
log.info("订单信息:{}", order);
}
@Test
void findAll() {
List<Order> list = orderService.findAll();
log.info("所有订单信息:{}", list);
}
}
小结
至此,关于Spring Boot集成JDBCTemplate的基本操作完成,关于集成中可能会发生的错误和源代码分析。我们将在下一篇文章中进行讲解。
















