在第2章节中,我们介绍了如何通过Spring Boot来实现HTTP接口,以及围绕HTTP接口相关的单元测试、文档生成等实用技能。但是,这些内容还不足以帮助我们构建一个动态应用的服务端程序。不论我们是要做App、小程序、还是传统的Web站点,对于用户的信息、相关业务的内容,通常都需要对其进行存储,而不是像第2章节中那样,把用户信息存储在内存中(重启就丢了!)。

对于信息的存储,现在已经有非常非常多的产品可以选择,其中不乏许多非常优秀的开源免费产品,比如:MySQL,Redis等。接下来,在第3章节,我们将继续学习在使用Spring Boot开发服务端程序的时候,如何实现对各流行数据存储产品的增删改查操作。

作为数据访问章节的第一篇,我们将从最为常用的关系型数据库开始。通过一个简单例子,学习在Spring Boot中最基本的数据访问工具:JdbcTemplate。

数据源配置

在我们访问数据库的时候,需要先配置一个数据源,下面分别介绍一下几种不同的数据库配置方式。

首先,为了连接数据库需要引入jdbc支持,在pom.xml中引入如下配置:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

嵌入式数据库支持

嵌入式数据库通常用于开发和测试环境,不推荐用于生产环境。Spring Boot提供自动配置的嵌入式数据库有H2、HSQL、Derby,你不需要提供任何连接配置就能使用。

比如,我们可以在pom.xml中引入如下配置使用HSQL

<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>

连接生产数据源

以MySQL数据库为例,先引入MySQL连接的依赖包,在pom.xml中加入:

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>

src/main/resources/application.properties中配置数据源信息

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

连接JNDI数据源

当你将应用部署于应用服务器上的时候想让数据源由应用服务器管理,那么可以使用如下配置方式引入JNDI数据源。

spring.datasource.jndi-name=java:jboss/datasources/customers

使用JdbcTemplate操作数据库

Spring的JdbcTemplate是自动配置的,你可以直接使用@Autowired或构造函数(推荐)来注入到你自己的bean中来使用。

下面就来一起完成一个增删改查的例子:

准备数据库

先创建User表,包含属性nameage。可以通过执行下面的建表语句::

CREATE TABLE `User` (
`name` varchar(100) COLLATE utf8mb4_general_ci NOT NULL,
`age` int NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

编写领域对象

根据数据库中创建的User表,创建领域对象:

@Data
@NoArgsConstructor
public class User { private String name;
private Integer age; }

这里使用了Lombok的@Data@NoArgsConstructor注解来自动生成各参数的Set、Get函数以及不带参数的构造函数。如果您对Lombok还不了解,可以看看这篇文章:Java开发神器Lombok的使用与原理

编写数据访问对象

  • 定义包含有插入、删除、查询的抽象接口UserService
public interface UserService {

    /**
* 新增一个用户
*
* @param name
* @param age
*/
int create(String name, Integer age); /**
* 根据name查询用户
*
* @param name
* @return
*/
List<User> getByName(String name); /**
* 根据name删除用户
*
* @param name
*/
int deleteByName(String name); /**
* 获取用户总量
*/
int getAllUsers(); /**
* 删除所有用户
*/
int deleteAllUsers(); }
  • 通过JdbcTemplate实现UserService中定义的数据访问操作
@Service
public class UserServiceImpl implements UserService { private JdbcTemplate jdbcTemplate; UserServiceImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
} @Override
public int create(String name, Integer age) {
return jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age);
} @Override
public List<User> getByName(String name) {
List<User> users = jdbcTemplate.query("select NAME, AGE from USER where NAME = ?", (resultSet, i) -> {
User user = new User();
user.setName(resultSet.getString("NAME"));
user.setAge(resultSet.getInt("AGE"));
return user;
}, name);
return users;
} @Override
public int deleteByName(String name) {
return jdbcTemplate.update("delete from USER where NAME = ?", name);
} @Override
public int getAllUsers() {
return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class);
} @Override
public int deleteAllUsers() {
return jdbcTemplate.update("delete from USER");
} }

编写单元测试用例

  • 创建对UserService的单元测试用例,通过创建、删除和查询来验证数据库操作的正确性。
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter31ApplicationTests { @Autowired
private UserService userSerivce; @Before
public void setUp() {
// 准备,清空user表
userSerivce.deleteAllUsers();
} @Test
public void test() throws Exception {
// 插入5个用户
userSerivce.create("Tom", 10);
userSerivce.create("Mike", 11);
userSerivce.create("Didispace", 30);
userSerivce.create("Oscar", 21);
userSerivce.create("Linda", 17); // 查询名为Oscar的用户,判断年龄是否匹配
List<User> userList = userSerivce.getByName("Oscar");
Assert.assertEquals(21, userList.get(0).getAge().intValue()); // 查数据库,应该有5个用户
Assert.assertEquals(5, userSerivce.getAllUsers()); // 删除两个用户
userSerivce.deleteByName("Tom");
userSerivce.deleteByName("Mike"); // 查数据库,应该有5个用户
Assert.assertEquals(3, userSerivce.getAllUsers()); } }

上面介绍的JdbcTemplate只是最基本的几个操作,更多其他数据访问操作的使用请参考:JdbcTemplate API

通过上面这个简单的例子,我们可以看到在Spring Boot下访问数据库的配置依然秉承了框架的初衷:简单。我们只需要在pom.xml中加入数据库依赖,再到application.properties中配置连接信息,不需要像Spring应用中创建JdbcTemplate的Bean,就可以直接在自己的对象中注入使用。

代码示例

本文的相关例子可以查看下面仓库中的chapter3-1目录:

如果您觉得本文不错,欢迎Star支持,您的关注是我坚持的动力!

欢迎关注我的公众号:程序猿DD,获得独家整理的学习资源和日常干货推送。

如果您对我的专题内容感兴趣,也可以关注我的博客:didispace.com

Spring Boot 2.x基础教程:使用JdbcTemplate访问MySQL数据库的更多相关文章

  1. Spring Boot 2.x基础教程:使用Flyway管理数据库版本

    之前已经介绍了很多在Spring Boot中使用MySQL的案例,包含了Spring Boot最原始的JdbcTemplate.Spring Data JPA以及我们国内最常用的MyBatis.同时, ...

  2. Spring Boot 2.x基础教程:使用JTA实现多数据源的事务管理

    在一个Spring Boot项目中,连接多个数据源还是比较常见的.之前也介绍了如何在几种常用框架的场景下配置多数据源,具体可见: Spring Boot 2.x基础教程:JdbcTemplate的多数 ...

  3. Spring Boot 2.x基础教程:使用国产数据库连接池Druid

    上一节,我们介绍了Spring Boot在JDBC模块中自动化配置使用的默认数据源HikariCP.接下来这一节,我们将介绍另外一个被广泛应用的开源数据源:Druid. Druid是由阿里巴巴数据库事 ...

  4. Spring Boot 2.x基础教程:Spring Data JPA的多数据源配置

    上一篇我们介绍了在使用JdbcTemplate来做数据访问时候的多数据源配置实现.接下来我们继续学习如何在使用Spring Data JPA的时候,完成多数据源的配置和使用. 添加多数据源的配置 先在 ...

  5. Spring Boot 2.x基础教程:使用Swagger2构建强大的API文档

    随着前后端分离架构和微服务架构的流行,我们使用Spring Boot来构建RESTful API项目的场景越来越多.通常我们的一个RESTful API就有可能要服务于多个不同的开发人员或开发团队:I ...

  6. Spring Boot 2.x基础教程:JSR-303实现请求参数校验

    请求参数的校验是很多新手开发非常容易犯错,或存在较多改进点的常见场景.比较常见的问题主要表现在以下几个方面: 仅依靠前端框架解决参数校验,缺失服务端的校验.这种情况常见于需要同时开发前后端的时候,虽然 ...

  7. Spring Boot 2.x基础教程:Swagger接口分类与各元素排序问题详解

    之前通过Spring Boot 2.x基础教程:使用Swagger2构建强大的API文档一文,我们学习了如何使用Swagger为Spring Boot项目自动生成API文档,有不少用户留言问了关于文档 ...

  8. Spring Boot 2.x基础教程:Swagger静态文档的生成

    前言 通过之前的两篇关于Swagger入门以及具体使用细节的介绍之后,我们已经能够轻松地为Spring MVC的Web项目自动构建出API文档了.如果您还不熟悉这块,可以先阅读: Spring Boo ...

  9. Spring Boot 2.x基础教程:找回启动日志中的请求路径列表

    如果您看过之前的Spring Boot 1.x教程,或者自己原本就对Spring Boot有一些经验,或者对Spring MVC很熟悉.那么对于Spring构建的Web应用在启动的时候,都会输出当前应 ...

  10. Spring Boot 2.x基础教程:使用MyBatis的XML配置方式

    上一篇我们介绍了如何在Spring Boot中整合我们国人最常用的MyBatis来实现对关系型数据库的访问.但是上一篇中使用了注解方式来实现,而对于很多MyBatis老用户还是习惯于XML的开发方式, ...

随机推荐

  1. Linux 创建网络会话

    Linux 创建网络会话 RHEL7系统支持网络会话功能,允许用户在多个配置文件中快速切换(非常类似于firewalld防火墙服务中的区域技术).如果我们在公司网络中使用笔记本电脑时需要手动指定网络的 ...

  2. 解析crash

    命令行 1.查找 symbolicatecrash find /Applications/Xcode.app -name symbolicatecrash -type f 2.此时会出现一个路径 sy ...

  3. PSR-1之PHP代码文件必须以不带BOM的UTF-8编码

    BOM——Byte Order Mark,就是字节序标记 在UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE“的字符,它的编码是FEFF.而FFFE在UCS中是不存在的字符 ...

  4. ansible安装与核心组件详解

    第1章 安装anisble 1.1 安装epel源 rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarc ...

  5. Java提供的JDBC标准- 六大步骤

    JDBC 1.//加载驱动 class.forname 2.//创建连接connection 3.//创建 管道流 statement或  preparestatement预处理4.//执行sql语句 ...

  6. cocos2dx Vec2

    //SE是坐标重叠部分 // returns true if segment A-B intersects with segment C-D. S->E is the overlap part ...

  7. 【题解】CTSC1999家园(网络流)

    CTSC1999家园 建模方法类似我NOI2019网络同步赛我的T1写法[[题解]NOI2019Route](70分) 问题的焦点是:空间时间载具. 考虑如何击破时间限制,可以对每个点关于每个时刻建立 ...

  8. 菜鸟系列Fabric源码学习 — MVCC验证

    Fabric 1.4 源码分析 MVCC验证 读本节文档之前建议先查看[Fabric 1.4 源码分析 committer记账节点]章节. 1. MVCC简介 Multi-Version Concur ...

  9. selenium自动化测试入门 定位frame和iframe中的元素对象

    < frame> <iframe> 标签,浏览器会在标签中打开一个特定的页面窗口(框架),它在本窗口中嵌套进入一个网页,当用selenium定位页面元素的时候会遇到定位不到fr ...

  10. 「洛谷P1306」斐波那契公约数 解题报告

    P1306 斐波那契公约数 题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很"简单"问题:第n项和第m项的最大公 ...