Spring Boot 数据操作组件Spring Data JPA

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: 你好看官,里面请!今天笔者讲的是 Spring Boot 数据操作组件Spring Data JPA。不懂或者觉得我写的有问题可以在评论区留言,我看到会及时回复。 注意:本文仅用于学习参考,不可用于商业用途,如需转载请跟我联系。

Spring Boot 数据操作组件Spring Data JPA

如果觉得写的还可以,点个赞支持一下笔者呗!你的点赞和关注会让我更快更新哦。笔者会持续更新关于Java和大数据有关的文章。目前集中精力在更新java框架的内容。

1. 历史发展

持久化操作(对数据库的操作)一直都是 Java 的核心内容,在 Java 的发展历史中,数据库持久化层面的框架也在不断地发展与更新。

JDBC( Java DataBase Connectivity )是 Java 中访问数据库的规范,由 SUN 公司制定(目前 SUN 已经被 Oracle 收购)。原生的 JDBC 代码臃肿、冗余,非常难用。这一度使得 Java EE 在当时备受质疑。所以 SUN 公司推出了大名鼎鼎的 EJB,现在已经很少人有提及 EJB 了,当年曾经大名鼎鼎也是因为是 SUN 公司的产品(连技术圈也开始拼爹了)。但由于 EJB 太重量级,太难用,很快就被当时的新晋小生 Hibernate 所取代(事实再一次告诉我们,爹再牛逼也只能帮你一时,关键还得看自己)。

Hibernate 凭借自身强大的功能迅速走红,与 Struts 和 Spring 组成了当时风靡一时的 SSH 三人组。后来 SUN 公司借鉴了 Hibernate 的设计思路,制定了 JPA( Java Persistence API )规范。在 Hibernate 后来的版本中,也实现了对于 JPA 的完全支持。这也使 HIbernate 在当时进一步巩固了自己在持久层框架的霸主地位。

随着互联网的发展,尤其是移动互联网的飞速扩展,HIbernate 对于性能和灵活性的需求显得捉襟见肘,已经无法满足日新月异的互联网业务场景了。这个时候,又一个年轻人站了出来,它就是 Mybatis。Mybatis 凭借着其简单、高效、灵活等特点迅速成为了新时代的宠儿。

2. 两种思路

数据库持久层框架通常可以分为两种类型,两者的关注对象不同。其中一种关注的重心是数据库(表),对 JDBC 做一定的封装,将 JDBC 冗余的样板代码 “隐藏” 起来,使其变得方便和快捷,此中的代表就是 Mybatis;另一种的关注重心则是 Java Entity。通过实体类来映射表之间的关系,HIbernate 就是这一分类中的翘楚( Spring Data JPA 就是基于 HIbernate 实现的)。

Spring Data JPA 对 JPA( Java Persistence API )进行了进一步的封装,使得对数据库的常用操作变得异常简单。到底能有多简单呢?简单到令人无法相信,不信?那我们走着瞧!

3. 动手

3.1 准备

在使用 Spring Data JPA 之前,我们需要做一些准备工作。因为 Spring Data JPA 是持久层的组件,那么我们肯定会就要用到数据库了。所以,我们需要先安装数据库,不用说你也想到了,我们使用的数据库是 MySQL(如何安装 MySQL 就不用我多说了吧)。MySQL 安装完成后,我们需要创建一个数据库,在本专栏里,数据库的名字叫做 springboot,当然你也可以选择你喜欢的名字。

3.2 添加依赖

要使用 Spring Data JPA 我们需要在 pom 文件中添加如下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

3.3 添加配置

添加完依赖,我们需要增加一些配置,才能让我们的工程访问到数据库。我们需要在 application.yml 文件中添加如下配置:

#数据源配置
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/springboot?characterEncoding=utf8&useSSL=false
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect

配置介绍:

  • url 数据库地址与参数
  • driver-class-name 连接数据库的驱动
  • username 数据库用户名
  • password 数据库密码

上面四项配置比较简单,稍微有点编程经验的一看就能明白是什么,这里就不过多介绍了。我们简单说一下 jpa 下面的几项配置:

show-sql 很简单,设为 true 代表打印 sql,false 则为不打印;

database-platform 也不难,用来指定使用哪种 MySQL 的存储引擎,我们这里使用的是 InnoDB。

ddl-auto 这个配置简单说一下,它有四个值可选,具体含义如下:

  • create 每次启动重新创建表(启动过程中原来的数据会被清除)
  • create-drop 每次启动重新创建表,并在程序结束是删除表,如果表不存在会报错
  • update 每次启动如表结构不一致,则更新表结构,原数居会保留(一般使用该项)
  • validate 每次启动验证表结构,如果不一致则报错

3.4 创建实体

我们可以在之前创建的 User 类中加入如下注解,使其变成我们的实体类:

@Data
@Entity
public class User {
    @Id
    @GeneratedValue
    private Integer id;
    private String name;
  .......
}

注解介绍:

在 User 类中,我们是用了三个新注解——@Entity、@Id 和 @GeneratedValue。@Entity 用来声明 User 是一个实体类,将会与数据库里的 user 表对应起来;@Id 和 @GeneratedValue 则标识 user 的 id 属性为 user 表的自增 Id。

如果想要自定义表名,比如想要让与 User 类对应的表叫做 t_user 的话,那么只需要使用 @Table(name = “t_user”) 即可。同样想要自定义列名也非常简单,比如想要将 name 与表里的 user_name 对应,只需要在 name 属性上加上 @Column(name = “user_name”) 即可。

3.5 生成表结构

接下来我们可以让 Spring Data JPA 根据实体类来生成表结构了,启动程序,会在控制台看到如下日志:

Hibernate: 
create table user 
(id integer not null, age integer not null, birth_day date, 
email varchar(255), name varchar(255) not null, primary key (id)) 
engine=InnoDB

看到上面的日志输出,说明 user 表被创建了,我们可以登录 MySQL 去验证一下:

网络异常,图片无法展示
|

我们看到,user 表已经被成功创建。我们再检查一下 user 表的结构是否符合我们的预期,使用 desc user 命令查看,结果如下:

网络异常,图片无法展示
|

OK,user 表的结构跟我们的 User 实体类一致。

3.6 完善剩余代码

创建 User 类的持久化接口 UserRepository:

public interface UserRepository extends JpaRepository<User,Integer> {
}

UserRepository 中不需要写任何代码,但依然可以帮我们完成增删改查的操作,下面我们继续。

创建 UserController 并实现增删改查四个方法:

@Api
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserRepository userRepository;
    @ApiOperation(value = "根据id获取用户信息")
    @GetMapping("/{id}")
    public User get(@PathVariable int id) {
        return userRepository.findById(id).get();
    }
    @ApiOperation(value = "创建用户")
    @PostMapping("")
    public User create(@RequestBody User user) {
        return userRepository.save(user);
    }
    @ApiOperation(value = "更新用户")
    @PutMapping("")
    public User update(@RequestBody User user) {
        return userRepository.save(user);
    }
    @ApiOperation(value = "删除用户")
    @DeleteMapping("/{id}")
    public void delete(@PathVariable Integer id) {
        userRepository.deleteById(id);
    }
}

3.7 效果

接下来我们启动程序,打开 Swagger 去验证一下这些接口是否好用。首先,我们调用 create 方法来创建一个 user。

参数如下:

{
  "age": 18,
  "birthDay": "2011-01-01",
  "email": "xiaoming@imooc.com",
  "name": "小明"
}

执行完成后,登录 MySQL 查看,结果如下:

网络异常,图片无法展示
|

我们通过 Controller 中的 create 方法 调用了 UserRepository 中的 save 方法成功插入了一条用户信息。其他方法的效果就不在这里一一演示了,留给你自己去把玩吧。

4. 扩展

4.1 基于方法名查询

假如我想要个性化查询怎么办呢?比如我想按照年龄来查询用户,其实也非常简单,只需要按照 Spring Data JPA 的规范在 UserRepository 中定义相应的接口即可。没错,就是只定义个接口,不需要写实现!

public interface UserRepository extends JpaRepository<User,Integer> {
    public List<User> findByAge(Integer age);
}

在 UserRepository 中加入上面一句代码就完成了根据年龄查询用户的功能。当然,我们需要在 Controller 里面调用一下:

@ApiOperation(value = "根据年龄查询用户")
@GetMapping("/age/{age}")
public List<User> getByAge(@PathVariable Integer age) {
    return userRepository.findByAge(age);
}

OK,这样就搞定了,可以去 Swagger 上测试一下了,效果就不在这里展示了。

更多关键字规则对照表:

关键字 例子 JPQL 片段
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is,Equals findByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Before findByStartDateBefore … where x.startDate < ?1
IsNull findByAgeIsNull … where x.age is null
IsNotNull,NotNull findByAge(Is)NotNull … where x.age not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … where x.firstname not like ?1
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection ages) … where x.age not in ?1
True findByActiveTrue() … where x.active = true
False findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)

4.2 分页、排序

那么想要分页、排序该怎么办呢?支持吗?方便吗?必须的!而且比上面的还简单,UserRepository 中不需要添加任何内容,直接在 Controller 里调用即可:

@ApiOperation(value = "分页获取用户列表")
@GetMapping("")
public Page<User> list(String property, String direction, Integer page, Integer size) {
    Pageable pageable = PageRequest.of(page, size, Sort.Direction.fromString(direction),property);
    return userRepository.findAll(pageable);
}

PS:页码从 0 开始哦

打完收工!就是如此简单,两行代码解决战斗!

嗯,这操作很 Spring Boot!Spring Boot 就是想让你只专注于你想专注的事情,其他脏活累活它来帮你完成。其实这些都是基于一个理念——约定由于配置。

5. 总结

这一小节我们学习了 Spring Data JPA 的相关内容,对其特点与用法有了比较全面的认识。并且通过几个小例子进一步巩固了对它的理解。这里只是对 Spring Data JPA 进行了一些初步的学习,其实它还有很多很强大的功能,比如我们可以使用 JPQL 来执行自定义操作,还可以使用原生 SQL 去开发我们想要的功能。这些功能可以通过 @Query 注解来实现,另外还可以像 Mybatis 那样基于 Example 进行查询,或者使用 JPA Query 等高级特性。更多有意思的功能等待你去发现。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
16小时前
|
存储 Java 数据库
如何在Spring Boot中实现多租户数据隔离
如何在Spring Boot中实现多租户数据隔离
|
4天前
|
Java 数据库连接 Maven
文本,使用SpringBoot工程创建一个Mybatis-plus项目,Mybatis-plus在编写数据层接口,用extends BaseMapper<User>继承实体类
文本,使用SpringBoot工程创建一个Mybatis-plus项目,Mybatis-plus在编写数据层接口,用extends BaseMapper<User>继承实体类
|
3天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的高校党建基本数据管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的高校党建基本数据管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
9 1
|
3天前
|
物联网
好的资源链接,gitee全糖咖啡,B站视频转成mp4,全糖咖啡 / 物联网网关数据上传,,全糖咖啡 / springboot+百度智能车牌检测
好的资源链接,gitee全糖咖啡,B站视频转成mp4,全糖咖啡 / 物联网网关数据上传,,全糖咖啡 / springboot+百度智能车牌检测
|
4天前
|
JavaScript Java 数据安全/隐私保护
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码(2)
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码
12 0
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码(2)
|
16小时前
|
存储 Java 数据库
在Spring Boot中实现多租户架构的数据隔离
在Spring Boot中实现多租户架构的数据隔离
|
16小时前
|
SQL 存储 Java
深入理解Spring Boot中的数据访问层设计
深入理解Spring Boot中的数据访问层设计
|
4天前
|
JavaScript Java 关系型数据库
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码(1)
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码
10 0
|
Java 应用服务中间件 Spring
Netweaver的端口号和Spring boot内嵌的Tomcat端口
Netweaver的端口号和Spring boot内嵌的Tomcat端口
Netweaver的端口号和Spring boot内嵌的Tomcat端口
|
2天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的药店库存管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的药店库存管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
8 1