Spring Boot 数据操作组件Spring Data JPA

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介: 你好看官,里面请!今天笔者讲的是 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 等高级特性。更多有意思的功能等待你去发现。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
6月前
|
人工智能 Java 机器人
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
Spring AI Alibaba集成Ollama,基于Java构建本地大模型应用,支持流式对话、knife4j接口可视化,实现高隐私、免API密钥的离线AI服务。
5496 2
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
|
5月前
|
前端开发 Java 应用服务中间件
《深入理解Spring》 Spring Boot——约定优于配置的革命者
Spring Boot基于“约定优于配置”理念,通过自动配置、起步依赖、嵌入式容器和Actuator四大特性,简化Spring应用的开发与部署,提升效率,降低门槛,成为现代Java开发的事实标准。
|
5月前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
5月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
635 3
|
XML Java 数据库连接
Spring Boot的数据访问之Spring Data JPA以及Hibernate的实战(超详细 附源码)
Spring Boot的数据访问之Spring Data JPA以及Hibernate的实战(超详细 附源码)
892 0
|
11月前
|
SQL Java 编译器
深入理解 Spring Data JPA 的导入与使用:以 UserRepository为例
本文深入解析了 Spring Data JPA 中 `UserRepository` 的导入与使用。通过示例代码,详细说明了为何需要导入 `User` 实体类、`JpaRepository` 接口及 `@Repository` 注解。这些导入语句分别用于定义操作实体、提供数据库交互方法和标识数据访问组件。文章还探讨了未导入时的编译问题,并展示了实际应用场景,如用户保存、查询与删除操作。合理使用导入语句,可让代码更简洁高效,充分发挥 Spring Data JPA 的优势。
661 0
|
Java Spring
Spring Boot利用Spring Data JPA实现排序与分页查询实战(附源码,超详细)
Spring Boot利用Spring Data JPA实现排序与分页查询实战(附源码,超详细)
812 0
|
Java 数据库连接 API
【Java笔记+踩坑】Spring Data JPA
从常用注解、实体类和各层编写方法入手,详细介绍JPA框架在增删改查等方面的基本用法,以及填充用户名日期、分页查询等高级用法。
【Java笔记+踩坑】Spring Data JPA
|
Java Spring 数据库
怎样动动手指就能实现数据操作?Spring Data JPA背后的魔法揭秘
【8月更文挑战第31天】在Java开发中,数据库交互至关重要。传统的JDBC操作繁琐且难维护,而Spring Data JPA作为集成JPA的数据访问层解决方案,提供了CRUD等通用操作接口,显著减少代码量。通过继承`JpaRepository`,开发者能轻松实现数据的增删改查,甚至复杂查询和分页也不再困难。本文将通过示例详细介绍如何利用Spring Data JPA简化数据访问层的开发,提升代码质量和可维护性。
230 0
|
存储 Java 数据库