多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 一、jdbc简介 JDBC(Java DataBase Connectivity)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序, > 术语:什么是持久层:在后面的章节我会经常用到持久层这个词,持久层就是指对数据进行持久化操作的代码,比如将数据保存到数据库、文件、磁盘等操作都是持久层操作。所谓持久就是保存起来的意思。对于web应用最常用的持久层框架就是JDBC、Mybatis、JPA。 ## 二、使用jdbc操作数据库的步骤 直接在 Java 程序中使用 JDBC 比较复杂,需要 7 步才能完成数据库的操作: 1. 加载数据库驱动 2. 建立数据库连接 3. 创建数据库操作对象 4. 定义操作的 SQL 语句 5. 执行数据库操作 6. 获取并操作结果集 7. 关闭对象,回收资源 关键代码如下: ~~~ try { // 1、加载数据库驱动 Class.forName(driver); // 2、获取数据库连接 conn = DriverManager.getConnection(url, username, password); // 3、获取数据库操作对象 stmt = conn.createStatement(); // 4、定义操作的 SQL 语句 String sql = "select * from user where id = 6"; // 5、执行数据库操作 rs = stmt.executeQuery(sql); // 6、获取并操作结果集 while (rs.next()) { // 解析结果集 } } catch (Exception e) { // 日志信息 } finally { // 7、关闭资源 } ~~~ 通过上面的示例可以看出直接使用 JDBC 来操作数据库比较复杂。为此,Spring Boot 针对 JDBC 的使用提供了对应的 Starter 包:spring-boot-starter-jdbc,它其实就是在 Spring JDBC 上做了进一步的封装,方便在 Spring Boot 生态中更好的使用 JDBC,下面进行示例演示。 > 本教程作为spring boot系列教程,并不能将spring jdbc的方方面面讲到,本文只会去讲最重要的部分,如果想更加深入的学习Spring JDBC。建议参考:[https://www.yiibai.com/springjdbc](https://www.yiibai.com/springjdbc) 不论是JDBC,还是封装之后的Spring JDBC,直接操作数据库都比较麻烦。如果企业有成熟的ORM知识积累,并且无特殊需求,不建议直接使用JDBC操作数据库。 ## 三、 将Spring JDBC集成到Spring boot项目 > 在《3-8 配置文件敏感字段加密》master分支的基础上新建一个分支:jdbc 第一步:引入maven依赖包,包括spring JDBC和MySQL驱动。 ~~~ <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> ~~~ 第二步:修改application.yml,增加数据库连接、用户名、密码相关的配置。driver-class-name请根据自己使用的数据库和数据库版本准确填写。 ~~~ spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 datasource: url: jdbc:mysql://127.0.0.1:3306/wyh?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver ~~~ **这里看具体本地数据库版本,如果是mysql 5则使用 5的driver,6以上使用 6 的driver。不要用错!** * mysql-connector-java 5版本及其以下,使用`com.mysql.jdbc.Driver` * mysql-connector-java 6版本及其以上,使用`com.mysql.cj.jdbc.Driver` ## 四、  spring boot jdbc 基础代码 spring jdbc集成完毕之后,我们来写代码做一个基本的测试。首先我们新建一张测试表article ~~~ CREATE TABLE `article` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `author` VARCHAR(32) NOT NULL, `title` VARCHAR(32) NOT NULL, `content` VARCHAR(512) NOT NULL, `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) COMMENT='文章' ENGINE=InnoDB; ~~~ DAO层代码: * jdbcTemplate.update适合于insert 、update和delete操作; * jdbcTemplate.queryForObject用于查询单条记录返回结果 * jdbcTemplate.query用于查询结果列表 * BeanPropertyRowMapper可以将数据库字段的值向Article对象映射,满足驼峰标识也可以自动映射。如:数据库create\_time字段映射到createTime属性。 ~~~ @Repository //持久层依赖注入注解 public class ArticleJDBCDAO { @Resource private JdbcTemplate jdbcTemplate; //保存文章 public void save(Article article) { //jdbcTemplate.update适合于insert 、update和delete操作; jdbcTemplate.update("INSERT INTO article(author, title,content,create_time) values(?, ?, ?, ?)", article.getAuthor(), article.getTitle(), article.getContent(), article.getCreateTime()); } //删除文章 public void deleteById(Long id) { //jdbcTemplate.update适合于insert 、update和delete操作; jdbcTemplate.update("DELETE FROM article WHERE id = ?",id); } //更新文章 public void updateById(Article article) { //jdbcTemplate.update适合于insert 、update和delete操作; jdbcTemplate.update("UPDATE article SET author = ?, title = ? ,content = ?,create_time = ? WHERE id = ?", article.getAuthor(), article.getTitle(), article.getContent(), article.getCreateTime(), article.getId()); } //根据id查找文章 public Article findById(Long id) { //queryForObject用于查询单条记录返回结果 return (Article) jdbcTemplate.queryForObject("SELECT * FROM article WHERE id=?", new Object[]{id},new BeanPropertyRowMapper<>(Article.class)); } //查询所有 public List<Article> findAll(){ //query用于查询结果列表 return (List<Article>) jdbcTemplate.query("SELECT * FROM article ", new BeanPropertyRowMapper<>(Article.class)); } } ~~~ service层接口 ~~~ public interface ArticleService { void saveArticle(Article article); void deleteArticle(Long id); void updateArticle(Article article); Article getArticle(Long id); List<Article> getAll(); } ~~~ service层操作JDBC持久层 ~~~ package com.kimgao.bootlauch.service; import com.kimgao.bootlauch.dao.ArticleJDBCDAO; import com.kimgao.bootlauch.model.Article; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.List; @Service public class ArticlleJDBCService implements ArticleService{ @Resource private ArticleJDBCDAO articleJDBCDAO; @Transactional public void saveArticle( Article article) { articleJDBCDAO.save(article); } @Override public void deleteArticle(Long id){ articleJDBCDAO.deleteById(id); } @Override public void updateArticle(Article article){ if(article.getId() == null){ //抛出异常,以后写 } articleJDBCDAO.updateById(article); } @Override public Article getArticle(Long id){ return articleJDBCDAO.findById(id); } @Override public List<Article> getAll(){ return articleJDBCDAO.findAll(); } } ~~~ 最后,在我们之前的章节为大家实现的ArticleController中调用ArticleRestJDBCService 实现方法,进行从Controller 到 Service 到 DAO层的全流程测试。 * 重点测试一下事务的回滚,人为制造一个被除数为0的异常。 * 在saveArticle方法上使用了@Trasactional注解,该注解基本功能为事务管理,保证saveArticle方法一旦有异常,所有的数据库操作就回滚。 ~~~ @Override @Transactional public void updateArticle(Article article){ if(article.getId() == null){ //抛出异常,以后写 } //删除后新增 articleJDBCDAO.deleteById(article.getId()); articleJDBCDAO.save(article); //articleJDBCDAO.updateById(article) int a = 10/0; } ~~~