1. 前言
从 Spring Boot 快速入门系列前两篇中(Spring Boot 快速入门系列(先导篇) —— 从 Hello World 开始、Spring Boot 快速入门系列(I) —— 属性配置篇),我们已经学习和了解如何通过 IDEA 完成一个简单化轻量级的后端服务项目搭建,以及如何使用 application.properties 文件和读取配置文件内容的几种方式等,今天我们就来演示一下通过 Spring Data JPA 完成基础的数据库(CRUD)持久化操作。
2. Spring Data JPA 简介
JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的框架有 Hibernate、TopLink 等。
Spring Data JPA 框架,主要针对的就是 Spring 框架唯一没有简化到的业务逻辑代码,因此 Spring 开发者不需要关心持久层业务逻辑的工作,唯一需要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 插件帮你完成!
3. Spring Data JPA 使用
下面我们来操作一下 Spring Boot 框架下 Spring Data JPA 的使用。
本文就简单演示下如何配置 Spring Data JPA 以及由 Java 实体对象自动映射生成数据库表。
1)首先第一步,通过Maven项目的 pom.xml 文件引入 mysql 数据库的连接驱动、Druid 数据库连接池和 Spring Data JPA 数据持久化操作依赖的Jar 包,具体的引入方式如下;
<!-- mysql 连接驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- druid 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<!-- spring data jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
接下来配置 application.properties 文件,添加如下:
# 配置mysql数据源
spring.datasource.driver-class-name=org.gjt.mm.mysql.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db_test?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
# 配置 druid数据库连接池
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 数据库连接池的最小维持连接数
spring.datasource.dbcp2.min-idle=5
# 初始化提供的连接数
spring.datasource.dbcp2.initial-size=5
# 最大的连接数
spring.datasource.dbcp2.max-total=5
# 等待连接获取的最大超时时间
spring.datasource.dbcp2.max-wait-millis=200
# druid监控配置
spring.datasource.filters=stat,wall,log4j
# 配置实体类自动映射创建数据库表
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
注:上面这种 properties 形式的配置有点冗余,后面会改成主流的 yml 形式的书写方式。
2)在 domain 包下创建 Game 实体类:
package cn.giserway.helloworld.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @program: helloworld
*
* @author: giserway
*
**/
@Entity
@Table(name="t_game")
public class Game {
@Id
@GeneratedValue
private Integer id;
@Column(length=150)
private String gameName;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getGameName() {
return gameName;
}
public void setGameName(String gameName) {
this.gameName = gameName;
}
@Override
public String toString() {
return "Game{" +
"id=" + id +
", gameName='" + gameName + '\'' +
'}';
}
}
3)Mac 系统下启动 MySQL 数据库服务步骤(在系统偏好设置中):
点击 MySQL 图标,打开如下:
点击 Start MySQL Server 按钮即可启动服务,如显示如下图所示即启动成功:
4)创建 db_test 数据库
通过 iTerm 终端连接 mysql 数据库,命令和操作步骤如下:
# 连接本地mysql命令,回车输入密码
mysql -uroot -p
# 显示数据库
show databases;
# 创建 db_test 数据库
create database db_test;
# 使用 db_test 数据库
use db_test;
5)通过 IDEA 软件创建 mysql 数据库连接,点击右侧 Database 数据库管理工具,如下图所示:
配置自己的数据库连接 ip 和端口号(mysql默认端口号:3306),数据库的用户名和密码,再点击【Test Connection】按钮测试数据库连接是否成功,如下图显示 Successful 表示测试连接 ok。
通过 IDEA 软件的右侧数据库管理,查看刚刚 iTerm 终端通过mysql命令创建的 db_test 数据库了,如下图所示:
注:目前数据库没有新建自己的表。
6)启动 HelloWorldApplication 类,会在 db_test 数据库中自动创建 t_game 表 和 hibernate_sequence 表(记录主键 id),如下图所示:
注:此时表 t_game 中无数据。
7)下面我们开始使用 Spring Data JPA 来实现数据库的 CRUD 操作,视图层采用 Freemarker 模板实现。
这里先把 application.properties 修改成 application.yml 主流格式,具体修改如下所示:
# 应用的访问端口
server:
port: 9999
# 配置mysql数据源
spring:
datasource:
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/db_test?useUnicode=true&characterEncoding=utf8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource # 配置 druid数据库连接池
filters: stat,wall,log4j # druid监控配置
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化提供的连接数
max-total: 5 # 最大的连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
jpa:
hibernate.ddl-auto: update # 配置实体类自动映射创建数据库表
show-sql: true
注:yml格式有个注意点,冒号后面一定要加个空格
8)在 dao 包下创建 GameDao 类实现 JpaRepository 接口,代码如下:
package cn.giserway.helloworld.dao;
import cn.giserway.helloworld.domain.Game;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @program: helloworld
*
* @author: giserway
*
**/
public interface GameDao extends JpaRepository<Game, Integer> {
}
9)在 controller 包下创建 GameController 类,代码如下:
package cn.giserway.helloworld.controller;
import cn.giserway.helloworld.dao.GameDao;
import cn.giserway.helloworld.domain.Game;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.Resource;
/**
* @program: helloworld
*
* @author: giserway
*
**/
@Controller
@RequestMapping("/game")
public class GameController {
@Autowired
private GameDao gameDao;
/**
* 查询所有游戏列表
* @return
*/
@RequestMapping(value="/list")
public ModelAndView list(){
ModelAndView mav = new ModelAndView();
mav.addObject("gameList", gameDao.findAll());
mav.setViewName("gameList");
return mav;
}
/**
* 添加游戏
* @param game
* @return
*/
@RequestMapping(value="/add",method=RequestMethod.POST)
public String add(Game game){
gameDao.save(game);
return "forward:/game/list";
}
/**
* 跳转修改视图
* @param id
* @return
*/
@GetMapping(value="/preUpdate/{id}")
public ModelAndView preUpdate(@PathVariable("id") Integer id){
ModelAndView mav = new ModelAndView();
mav.addObject("game", gameDao.getOne(id));
mav.setViewName("gameUpdate");
return mav;
}
/**
* 修改游戏
* @param game
* @return
*/
@PostMapping(value="/update")
public String update(Game game){
gameDao.save(game);
return "forward:/game/list";
}
/**
* 删除游戏
* @param id
* @return
*/
@RequestMapping(value="/delete",method= RequestMethod.GET)
public String delete(Integer id){
gameDao.deleteById(id);
return "forward:/game/list";
}
}
10)在 templates (模板文件存放位置)文件夹(src/main/resources/templates)下新建一个 gameList.ftl(游戏展示)、gameUpdate.ftl (游戏更新),在 static (静态页面存放位置)文件夹下新建 gameAdd.html(游戏添加)文件,Freemarker 模板标签语法在这里不做解释,请自行学习了解。
先添加 Freemarker 依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
文件结构如下:
代码如下所示:
gameList.ftl
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>游戏管理页面</title>
</head>
<body>
<a href="/gameAdd.html">添加游戏</a>
<table>
<tr>
<th>编号</th>
<th>游戏名称</th>
<th>操作</th>
</tr>
<#list gameList as game>
<tr>
<td>${game.id}</td>
<td>${game.gameName}</td>
<td>
<a href="/game/preUpdate/${game.id}">修改</a>
<a href="/game/delete?id=${game.id}">删除</a>
</td>
</tr>
</#list>
</table>
</body>
</html>
gameUpdate.ftl
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>游戏更新页面</title>
</head>
<body>
<form action="/game/update" method="post">
<input type="hidden" name="id" value="${game.id}"/>
游戏名称:<input type="text" name="gameName" value="${game.gameName}"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
gameAdd.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>游戏添加页面</title>
</head>
<body>
<form action="game/add" method="post">
游戏名称:<input type="text" name="gameName"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
11)重新启动 Spring Boot 项目,操作演示动图如下:
图片内容包括:
- 启动项目;
- 查询数据库 db_test 的 t_game 表中没有数据;
- 打开浏览器输入 http://localhost:9999/game/list,浏览器显示游戏列表为空;
- 通过添加游戏按钮添加游戏后再次查看数据库表 t_game,发现数据库表中新增了一条记录,再连续添加,查看 t_game 表,又多了几条记录,并且表的主键 id 是自增长的;
- 修改游戏名称,查看数据库;
- 删除游戏操作查看库;
- 查看控制台 hibernate 的sql 记录。
4. 小结
今天我们通过 Spring Data JPA 学会了简单的数据库的持久化操作。开发人员通过项目的 pom.xml 文件添加需要依赖的 Jar,实体类上添加简单的注解,dao 层实现 JpaRepository 接口,其他都交给 Spring Data JPA 来帮你完成!包括数据库表自动创建和数据库表的基本 CRUD 操作。就是这么简单!开始你的 Spring Boot 的 CRUD 之旅吧!
下一篇文章我们将会演示 Spring Boot 快速入门系列(III)—— 数据库操作篇之 Spring jdbcTemplate 。
# 精彩推荐 #
Spring Boot 快速入门系列(先导篇) —— 从 Hello World 开始
Spring Boot 快速入门系列(I) —— 属性配置篇