Spring Data JDBC用法详解(附带实例)
JDBC(Java Database Connectivity)是 Java 连接数据库的原生接口。JDBC 对实现与数据库连接的服务提供商而言,就是接口模型第三方中间件厂商实现与数据的连接提供了标准的方法,对 Java 开发工程师来说就是 API,标准的接口。
JDBC 是所有操作数据库的框架必须使用的,所以为了方便 Java 工程师调用数据库,数据库厂商通常都会实现 JDBC 接口。
Spring 为了支持各种持久化技术,提供了简单的模板以及回调方法:
Spring Data JDBC 相较于传统的 JDBC 而言,只需要在配置文件中配置数据库驱动、连接等相关信息,Java 代码中只需要通过注入模板调用方法执行 SQL 即可。
下面我们主要讲解 JdbcTemplate。其实 Spring 中的 JdbcTemplate 就是对 JDBC 进行了一层封装,将 DataSource 注册到 JdbcTemplate 中,处理了资源的建立和释放,我们只需要提供 SQL 语句和提取结果即可,使得 JDBC 更加易于使用。
JdbcTemplate 中主要提供了以下 4 类方法:
JdbcTemplate 类中支持的回调类:
1) 预编译语句及存储过程创建回调:用于根据 JdbcTemplate 提供的连接创建相应的语句。
2) 预编译语句设值回调:用于预编译语句相应参数设值。
3) 自定义功能回调:
4) 结果集处理回调:
通过 JdbcTemplate 添加学生信息功能,示例代码如下:
业务层代码如下:
测试接口代码如下:
查询学生列表,代码如下:
根据 id 查询学生信息,代码如下:
JDBC 是所有操作数据库的框架必须使用的,所以为了方便 Java 工程师调用数据库,数据库厂商通常都会实现 JDBC 接口。
Spring 为了支持各种持久化技术,提供了简单的模板以及回调方法:
1) JdbcTemplate模板
Spring Data JDBC 抽象框架 core 包提供了 JDBC 模板类,是 Spring 中最基本的 JDBC 模板,是 core 包中的核心类,其他模板都是基于 JdbcTemplate 完成的。JdbcTemplate 利用 JDBC 和简单的索引参数查询对数据库进行简单的访问。2) NamedParameterJdbcTemplate
能够在查询时把值绑定到 SQL 里的命名参数中,而不是索引参数,其内部包含了一个 JdbcTemplate,所以它是基于 JdbcTemplate 的功能又额外增加了参数命名的功能。3) SimpleJdbcTemplate
利用 Java 5 的特性(比如自动装箱、通用和可变参数列表)来简化 JDBC 模板的使用,相较于 NamedParameterJdbcTemplate 主要增加了 JDK 5.0 的反省和可变长度参数的支持。Spring Data JDBC 相较于传统的 JDBC 而言,只需要在配置文件中配置数据库驱动、连接等相关信息,Java 代码中只需要通过注入模板调用方法执行 SQL 即可。
下面我们主要讲解 JdbcTemplate。其实 Spring 中的 JdbcTemplate 就是对 JDBC 进行了一层封装,将 DataSource 注册到 JdbcTemplate 中,处理了资源的建立和释放,我们只需要提供 SQL 语句和提取结果即可,使得 JDBC 更加易于使用。
JdbcTemplate 中主要提供了以下 4 类方法:
- execute() 方法:可以执行 SQL 语句,一般用于执行 DDL(Data Definition Languages,数据定义语言)语句,常用的关键字包括 create、drop、alter 等。
- update() 方法及batchUpdate()方法:update() 方法主要用于单条数据的新增、修改和删除;batchUpdate() 方法用于执行新增、修改、删除批处理的相关语句。
- query() 方法及 queryForXXX() 方法:用于执行查询相关的方法。
- call() 方法:用于执行存储过程、函数相关语句。
JdbcTemplate 类中支持的回调类:
1) 预编译语句及存储过程创建回调:用于根据 JdbcTemplate 提供的连接创建相应的语句。
- PreparedStatementCreator:通过回调获取 JdbcTemplate 提供的 Connection,由用户使用该 Conncetion 创建相关的 PreparedStatement。
- CallableStatementCreator:通过回调获取 JdbcTemplate 提供的 Connection,由用户使用该 Conncetion 创建相关的 CallableStatement。
2) 预编译语句设值回调:用于预编译语句相应参数设值。
- PreparedStatementSetter:通过回调获取 JdbcTemplate 提供的 PreparedStatement,由用户来对预编译语句相应参数设值。
3) 自定义功能回调:
- ConnectionCallback:通过回调获取 JdbcTemplate 提供的 Connection,用户可在该 Connection 执行任何数量的操作。
- StatementCallback:通过回调获取 JdbcTemplate 提供的 Statement,用户可以在该 Statement 执行任何数量的操作。
- PreparedStatementCallback:通过回调获取 JdbcTemplate 提供的 PreparedStatement,用户可以在该 PreparedStatement 执行任何数量的操作。
- CallableStatementCallback:通过回调获取 JdbcTemplate 提供的 CallableStatement,用户可以在该 CallableStatement 执行任何数量的操作。
4) 结果集处理回调:
- RowMapper:用于将结果集每行数据转换为需要的类型,用户需实现方法 mapRow(ResultSet rs,int rowNum) 来完成将每行数据转换为相应的类型。
- RowCallbackHandler:用于处理ResultSet的每一行结果,用户需实现方法 processRow(ResultSet rs) 来完成处理,在该回调方法中无须执行 rs.next(),该操作由 JdbcTemplate 来执行,用户只需按行获取数据然后处理即可。
- ResultSetExtractor:用于结果集数据提取,用户需实现方法 extractData(ResultSet rs) 来处理结果集(必须处理整个结果集)。
JDBC实战
我们主要讲一下 Spring Boot 项目使用 Spring Data JDBC 进行数据库操作。核心依赖如下代码所示:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jdbc</artifactId> </dependency>
通过 JdbcTemplate 添加学生信息功能,示例代码如下:
@Repository public class StudentDaoImpl implements StudentDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public int addStudent(Student student) { String sql = "insert into student(username, password, birthday, sex, address) values (?, ?, ?, ?, ?)"; int row = jdbcTemplate.update( sql, student.getUsername(), student.getPassword(), student.getBirthday(), student.getSex(), student.getAddress() ); return row; } }
业务层代码如下:
@Service public class StudentServiceImpl implements StudentService { @Autowired private StudentDao studentDao; @Override public int addStudent(Student student) { return studentDao.addStudent(student); } }
测试接口代码如下:
/** * 用于测试 spring-boot-starter-jdbc 的接口 */ @RestController @RequestMapping("/student") public class StudentController { @Autowired private StudentService studentService; @PostMapping("/add") public int addStudent(@RequestBody Student student) { return studentService.addStudent(student); } }采用 Postman 解耦测试工具来测试 post 请求,如下图所示,在编号 5 的区域设置请求参数。

查询学生列表,代码如下:
@Override public List<Map<String,Object>> listStudent() { return jdbcTemplate.queryForList("select * from student"); }
根据 id 查询学生信息,代码如下:
修改学生信息,代码如下:@Override public int updateStudent(Student student) { String sql = "update student set username = ?, password = ?, address = ? where id = ?"; int row = jdbcTemplate.update( sql, student.getUsername(), student.getPassword(), student.getAddress(), student.getId() ); return row; }
删除学生信息,代码如下:@Override public int deleteStudent(Long id) { String sql = "delete from student where id = ?"; int row = jdbcTemplate.update(sql,id); return row; }