前言
在前面的章节中,壹哥 给大家讲解了SpringBoot对Web模块的支持,但是我们开发时还有另一个重头戏,那就是进行数据库的操作。所以从本章开始,我会带大家学习在Spring Boot中实现数据库的操作。
我这里说的数据库,不仅仅有关系型数据库,比如MySQL,还包括非关系型数据库,比如Redis等。
我们现在进行关系型数据库操作时,可以选择的技术框架其实有很多,比如原生的Jdbc,还有Mybatis、JPA等开源框架,接下来我会分别针对这几个技术进行讲解,今天我先讲解在SpringBoot中利用JdbcTemplate实现数据库的CRUD操作。
一. JdbcTemplate
在开始代码实操之前,我们先来了解一些理论内容。
1. JdbcTemplate简介
JDBC虽然能够满足大部分用户最基本的需求,但是在使用JDBC时,必须自己来管理数据库的资源,如获取PreparedStatement,设置SQL语句参数,关闭连接等操作,使用起来非常的麻烦。
所以为了简化对JDBC的操作,Spring为数据库JDBC做了深层次的封装。它利用DI注入功能,把DataSource注入到了JdbcTemplate之中,从而得到了JdbcTemplate操作模板类。JdbcTemplate的出现,使得JDBC的操作更加简单易用。
2. JdbcTemplate的作用
JdbcTemplate可以帮助我们处理资源的建立和释放,运行核心的JDBC工作流,如Statement的建立和执行,而我们只需要提供SQL语句和提取结果;并且也可以使我们避免一些常见的错误,比如忘记关闭数据库连接。
3. JdbcTemplate依赖包介绍
JdbcTemplate位于spring-jdbc-xxx.jar包中,其全限定命名为org.springframework.jdbc.core.JdbcTemplate
。要使用JdbcTemplate还需一个spring-tx-xxx.jar依赖包,该包包含了事务和异常控制。
4. JdbcTemplate的核心方法
在JdbcTemplate中有哪些核心方法供我们调用呢? 我们常用的重要方法有如下几类:
- execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
- update方法:update方法用于执行INSERT、UPDATE、DELETE等DML语句;
- batchUpdate方法用于执行批处理相关语句;
- query方法及queryForXXX方法:用于执行DQL查询相关语句;
- call方法:用于执行存储过程、函数相关语句。
5. JdbcTemplate使用步骤
那么JdbcTemplate到底该怎么使用呢?
- 导入数据库相关依赖包,比如jpa或者jdbc;
- 获取所需的某个DataSource数据源连接池对象;
- 创建JdbcTemplate对象,传入到连接池中;
- 调用execute、update、queryXxx等方法。
二. Spring Boot整合JdbcTemplate
接下来我就带各位利用JdbcTemplate实现CRUD操作,看看都需要做哪些事情吧。
1. 准备工作
我们要注意自己的开发环境,尽量要满足如下要求:
- SpringBoot 2.x
- JDK 1.8
- Maven 3.0
- Intellij Idea
- MySQL
2. 创建一个web项目(略)
首先我创建一个SpringBoot的Web项目,具体创建过程请参考我们之前的章节。最终的项目结构如下图所示:
3. pom.xml文件中添加依赖
在项目的pom.xml文件中添加jdbc、mysql、druid数据源的依赖包。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- 引入Druid依赖 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency>
4. 配置application.yml文件
然后我们创建一个application.yml文件,并在其中配置自己的数据库信息。
spring datasource url jdbc mysql //127.0.0.1 3306/db5?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=true username root password syc driver-class-name com.mysql.cj.jdbc.Driver #mysql6.0之后推荐使用这个驱动包
注意:
- mysql-connector-java版本6.0以前使用的是com.mysql.jdbc.Driver,6.0以后的使用com.mysql.cj.jdbc.Driver。
5. 创建一个数据库配置类
因为本案例中使用的Druid作为数据源,所以我在这里封装一个配置类,把application.yml文件中的信息读取进来。
packagecom.yyg.boot.config; importcom.alibaba.druid.pool.DruidDataSource; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.ComponentScan; importorg.springframework.context.annotation.Configuration; importorg.springframework.core.env.Environment; importjavax.sql.DataSource; /*** @Author 一一哥Sun* @Date Created in 2020/3/30* @Description 第一种配置方式*/publicclassDbConfig { privateEnvironmentenv; publicDataSourcegetDataSource() { DruidDataSourcedataSource=newDruidDataSource(); dataSource.setUrl(env.getProperty("spring.datasource.url")); dataSource.setUsername(env.getProperty("spring.datasource.username")); dataSource.setPassword(env.getProperty("spring.datasource.password")); returndataSource; } }
除了可以使用上面的方法读取application.yml文件中的配置信息之外,我们也可以采用第2种配置方式进行填充配置,代码如下:
packagecom.yyg.boot.config; importcom.alibaba.druid.pool.DruidDataSource; importlombok.Data; importorg.springframework.boot.context.properties.ConfigurationProperties; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.ComponentScan; importorg.springframework.context.annotation.Configuration; importjavax.sql.DataSource; /*** @Author 一一哥Sun* @Date Created in 2020/3/30* @Description 第二种配置数据源的方式*/prefix="spring.datasource") (publicclassSecondDbConfig { privateStringurl; privateStringusername; privateStringpassword; publicDataSourcegetDataSource() { DruidDataSourcedataSource=newDruidDataSource(); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); returndataSource; } }
6. 创建Users实体类
这里我们封装一个Users实体类,用于封装数据库中的信息。
packagecom.yyg.boot.domain; importlombok.Data; importlombok.ToString; /*** @Author 一一哥Sun* @Date Created in 2020/3/30* @Description Description*/publicclassUsers { privateIntegerid; privateStringusername; privateStringpassword; }
7. 创建Dao层代码
接下来我会在dao层包中,创建一个IUserDao接口,内部封装数据库的增删改查方法。
7.1 dao层的IUserDao接口
packagecom.yyg.boot.dao; importcom.yyg.boot.domain.Users; importjava.util.List; /*** @Author 一一哥Sun* @Date Created in 2020/3/30* @Description Description*/publicinterfaceIUserDao { intadd(Usersstudent); intupdate(Usersstudent); intdelete(intid); UsersfindUserById(intid); List<Users>findUserList(); }
7.2 dao层的UserDaoImpl接口实现
编写一个UserDaoImpl实现类,实现上面的IUserDao接口,在这个类中利用原生的SQL语句实现数据库的CRUD操作。
packagecom.yyg.boot.dao.impl; importcom.yyg.boot.dao.IUserDao; importcom.yyg.boot.domain.Users; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.jdbc.core.BeanPropertyRowMapper; importorg.springframework.jdbc.core.JdbcTemplate; importorg.springframework.stereotype.Repository; importjava.util.List; /*** @Author 一一哥Sun* @Date Created in 2020/3/30* @Description Description*/publicclassUserDaoImplimplementsIUserDao { privateJdbcTemplatejdbcTemplate; publicintadd(Usersuser) { returnjdbcTemplate.update("insert into users(username, password) values(?, ?)", user.getUsername(),user.getPassword()); } publicintupdate(Usersuser) { returnjdbcTemplate.update("UPDATE users SET username=? ,password=? WHERE id=?", user.getUsername(),user.getPassword(),user.getId()); } publicintdelete(intid) { returnjdbcTemplate.update("DELETE from TABLE users where id=?",id); } publicUsersfindUserById(intid) { // BeanPropertyRowMapper 使获取的 List 结果列表的数据库字段和实体类自动对应List<Users>list=jdbcTemplate.query("select * from users where id = ?", newObject[]{id}, newBeanPropertyRowMapper(Users.class)); returnlist.size()>0?list.get(0):null; } publicList<Users>findUserList() { // 使用Spring的JdbcTemplate查询数据库,获取List结果列表,数据库表字段和实体类自动对应,可以使用BeanPropertyRowMapperList<Users>list=jdbcTemplate.query("select * from users", newObject[]{}, newBeanPropertyRowMapper(Users.class)); returnlist.size()>0?list:null; } }
8. 创建Service层代码
根据3层架构,我们会有dao层、service层、web层,所以这里我再创建service层的核心业务代码,调用dao层接口。
8.1 创建service层的IUserService接口
packagecom.yyg.boot.service; importcom.yyg.boot.domain.Users; importjava.util.List; /*** @Author 一一哥Sun* @Date Created in 2020/3/30* @Description Description*/publicinterfaceIUserService { intadd(Usersuser); intupdate(Usersuser); intdelete(intid); UsersfindUserById(intid); List<Users>findUserList(); }
8.2 创建service层的UserServiceImpl接口实现
packagecom.yyg.boot.service.impl; importcom.yyg.boot.dao.IUserDao; importcom.yyg.boot.domain.Users; importcom.yyg.boot.service.IUserService; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.stereotype.Service; importjava.util.List; /*** @Author 一一哥Sun* @Date Created in 2020/3/30* @Description Description*/publicclassUserServiceImplimplementsIUserService { privateIUserDaouserDao; publicintadd(Usersuser) { returnuserDao.add(user); } publicintupdate(Usersuser) { returnuserDao.update(user); } publicintdelete(intid) { returnuserDao.delete(id); } publicUsersfindUserById(intid) { returnuserDao.findUserById(id); } publicList<Users>findUserList() { returnuserDao.findUserList(); } }
9. 创建Web层的Controller
然后我们再编写一个Controller,在这里定义几个RESTful风格的URL接口。
packagecom.yyg.boot.web; importcom.yyg.boot.domain.Users; importcom.yyg.boot.service.IUserService; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.web.bind.annotation.*; importjava.util.List; /*** @Author 一一哥Sun* @Date Created in 2020/3/30* @Description Description*/"/user") (publicclassUserController { privateIUserServiceiUserService; "") (publicintaddUser(Usersuser){ returniUserService.add(user); } "/{id}") (publicStringupdateUser(Integerid, Usersuser){ UsersoldUser=newUsers(); oldUser.setId(id); oldUser.setUsername(user.getUsername()); oldUser.setPassword(user.getPassword()); intt=iUserService.update(oldUser); if (t==1){ returnuser.toString(); }else { return"更新学生信息错误"; } } "/{id}") (publicUsersfindUserById(Integerid){ returniUserService.findUserById(id); } "/list") (publicList<Users>findUserList(){ returniUserService.findUserList(); } "/{id}") (publicintdeleteUserById(Integerid){ returniUserService.delete(id); } }
10. 创建启动类
最后我们再编写一个启动类。
packagecom.yyg.boot; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; /*** @Author 一一哥Sun* @Date Created in 2020/3/30* @Description Description*/publicclassJdbcApplication { publicstaticvoidmain(String[] args){ SpringApplication.run(JdbcApplication.class,args); } }
11. 完整项目结构
完整的项目结构如下,各位可以参考创建。
12. 接口测试
启动项目后,我们可以在浏览器或者postman中测试刚才创建的接口。
其他接口我就不再一一测试了,都是可以正常使用的!
结语
至此,我就用JdbcTemplate实现了MySQL数据库的增删改查,整体会有点麻烦,代码实现比Mybatis麻烦一些,更没有JPA简单。对于JdbcTemplate这种技术,各位简单了解即可,现在开发时很少用了。
今日小作业:
思考在SpringBoot中如何整合Mybatis?