SpringBoot整合JPA 基础使用

一、什么是JPA

‌‌1.JPA的定义和基本概念‌‌

‌JPA(Java Persistence API)‌是Java中用于进行持久化操作的一种规范,它定义了一系列用于操作关系型数据库的API接口。通过这些接口,开发人员可以方便地进行数据库的增删改查等操作,而无需关注具体的数据库操作细节。JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

‌2.JPA的核心概念‌

JPA的核心概念包括对象-关系映射(ORM)和实体对象持久化。ORM技术是一种将对象模型和关系模型进行映射的技术,通过ORM,开发人员可以将Java对象直接映射到数据库表中,从而避免了手动编写SQL语句的繁琐工作。JPA提供了一套注解和配置方式,可以方便地将Java类与数据库表进行映射,使得开发人员可以直接操作Java对象,而无需手动维护SQL语句。

‌3.JPA的用途和目标‌

JPA的目标是简化企业应用开发,使得开发者能够更容易地实现对象与数据库表之间的映射关系。它定义了对象-关系映射(ORM)以及实体对象持久化的标准接口,旨在规范和简化Java对象的持久化工作。通过提供统一的API和封装数据库操作细节,JPA使得开发人员可以更加方便地进行数据库操作,提高了代码的可维护性和可读性。

‌4.JPA的优势‌

使用JPA的优势包括提高代码的可维护性和可读性。通过使用JPA,开发人员可以使用面向对象的方式来操作数据库,无需直接操作SQL语句,这使得代码更加直观和易于理解。此外,JPA还提供了一些高级特性,如缓存管理、事务管理等,这些特性可以帮助开发人员更好地进行性能优化和并发控制。

二、JPA的使用

1.准备数据库脚本

sql 复制代码
DROP TABLE IF EXISTS user;

CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);

2.初始化数据

sql 复制代码
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

3.xml文件导入依赖

java 复制代码
<!-- JPA框架 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

4.引入JPA配置

java 复制代码
spring:
  jpa:
      hibernate:
        # ddl-auto 枚举:
        # none(默认):禁用DDL处理
        # validate:验证schema,不对数据库做任何操作
        # update:更新schema
        # create:创建schema,并销毁之前数据
        # create-drop:会话创建时创建schema,会话关闭时销毁schema
        ddl-auto: update
      # jpa配置:在控制台显示Hibernate的sql(可选)
      show-sql: true

(1)加载数据库驱动,springboot3.0开始mysql驱动改为com.mysql.cj.jdbc.Driver,而非com.mysql.jdbc.Driver。

(2)jpa底层实现采用hibernate,自动建表配置使用update,表示第一次创建schema,后续只做更新操作。

5.创建实体对象

java 复制代码
import lombok.Data;

import javax.persistence.*;

@Entity
@Data
@Table(name = "user")
public class UserDO  {
    private static final long serialVersionUID = -2952735933715107252L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private Integer age;

    private String email;

}

6.定义Repository接口

java 复制代码
public interface UserRepository extends JpaRepository<UserDO, Long> {

    /**
     * 根据用户姓名查找用户
     *
     * @param name 用户姓名
     * @return 找到的用户对象,如果不存在返回 null
     */
    UserDO findByName(String name);

    /**
     * 根据用户姓名或电子邮箱查找用户
     *
     * @param name  用户姓名
     * @param email 用户电子邮箱
     * @return 找到的用户对象,如果不存在返回 null
     */
    UserDO findByNameOrEmail(String name, String email);

    /**
     * 根据用户姓名计数用户数量
     *
     * @param name 用户姓名
     * @return 具有该姓名的用户数量
     */
    Long countByName(String name);

    /**
     * 根据用户名进行模糊搜索
     *
     * @param name 用户姓名(可以包含通配符)
     * @return 匹配的用户列表
     */
    List<UserDO> findByNameLike(String name);

    /**
     * 根据用户姓名忽略大小写查找用户
     *
     * @param name 用户姓名
     * @return 找到的用户对象,如果不存在返回 null
     */
    UserDO findByNameIgnoreCase(String name);

    /**
     * 根据用户姓名查找用户,并按年龄降序排列
     *
     * @param name 用户姓名
     * @return 匹配的用户列表,按年龄降序排列
     */
    List<UserDO> findByNameContainingOrderByAgeDesc(String name);

    /**
     * 根据用户姓名进行分页查询
     *
     * @param name     用户姓名
     * @param pageable 分页信息
     * @return 包含用户对象的分页结果
     */
    Page<UserDO> findByName(String name, Pageable pageable);
}

注:Repository接口用于定义对实体对象UserDO进行持久化操作的方法。

7.创建controller层调用Repository接口方法

这里只是简单测了根据ID查询

java 复制代码
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserRepository userRepository;

    /**
     * 测试单条查询
     */
    @GetMapping("/id")
    public void testSelectOne() {
        // 从 UserRepository 中查找 ID 为 1 的用户
        Optional<UserDO> user = userRepository.findById(1L);
        System.out.println(user);
    }
}

测试效果:

三、JPA的常用

1.常用注解

|-----------------|-------------------------------------------------------|
| 注解 | 描述 |
| @Entity | 声明该类为实体类。 |
| @Table | 指定实体类映射的数据库表,通常与@Entity注解一起使用。 |
| @Id | 声明实体类的属性或字段作为数据库表的主键。 |
| @GeneratedValue | 指定主键的生成策略。 |
| @Column | 用于标注实体类中的属性与数据库表中的字段之间的映射关系。 |
| @Transient | 声明实体类的属性或字段不是持久化的。 |
| @Basic | 指定实体类属性的存取策略。 |
| @Temporal | 指定java.util.Date或java.util.Calendar 属性映射到数据库类型时的时间精度。 |
| @Enumerated | 指定枚举类型的属性映射。 |
| @OneToOne | 指定一对一的关联映射。 |
| @OneToMany | 指定一对多的关联映射。 |
| @ManyToOne | 指定多对一的关联映射。 |
| @ManyToMany | 指定多对多的关联映射。 |
| @JoinColumn | 指定关联的外键列。 |
| @MapKey | 指定映射关系中的键。 |

2.常用查询方法

|--------|------------------------------|---------------------------|
| 方法类型 | 方法名称 | 描述 |
| 查询方法 | findBy/getBy/queryBy/readBy | 后面跟要查询的字段名,用于精确匹配。 |
| 查询方法 | find/get/query/read | 后面跟要查询的字段名,使用条件表达式进行模糊匹配。 |
| 查询方法 | findAll/getAll | 不跟字段名,表示查询所有记录。 |
| 支持的关键字 | And | 连接多个查询条件,相当于 SQL 中的 AND。 |
| 支持的关键字 | Or | 连接多个查询条件,相当于 SQL 中的 OR。 |
| 支持的关键字 | Between | 查询字段在某个范围内的记录。 |
| 支持的关键字 | LessThan/LessThanEqual | 查询字段小于或小于等于某个值的记录。 |
| 支持的关键字 | GreaterThan/GreaterThanEqual | 查询字段大于或大于等于某个值的记录。 |
| 支持的关键字 | IsNull/IsNotNull | 查询字段为空或不为空的记录。 |
| 支持的关键字 | Like/NotLike | 模糊查询字段值。 |
| 支持的关键字 | OrderBy | 指定查询结果的排序方式。 |
| 删除方法 | deleteBy/removeBy | 后面跟要查询的字段名,用于精确匹配。 |
| 删除方法 | delete/remove | 后面跟要查询的字段名,使用条件表达式进行模糊匹配。 |
| 统计方法 | countBy | 后面跟要查询的字段名,用于精确匹配。 |
| 统计方法 | count | 不跟字段名,表示统计所有记录数。 |
| 更新方法 | updateBy | 后面跟要查询的字段名,用于精确匹配。 |
| 更新方法 | update | 后面跟要查询的字段名,使用条件表达式进行模糊匹配。 |
| 支持的关键字 | Set | 设置要更新的字段的值。 |
| 支持的关键字 | Where | 指定更新操作的条件。 |

3.部分查询关键字映射示例

|-------------------|-----------------------------------------|
| 部分查询关键字映射示例 ||
| 关键字 | 使用示例 |
| And | findByLastnameAndFirstname |
| Or | findByLastnameOrFirstname |
| Is,Equals | findByFirstnameIs,findByFirstnameEquals |
| Between | findByStartDateBetween |
| LessThan | findByAgeLessThan |
| LessThanEqual | findByAgeLessThanEqual |
| GreaterThan | findByAgeGreaterThan |
| GreaterThanEqual | findByAgeGreaterThanEqual |
| After | findByStartDateAfter |
| Before | findByStartDateBefore |
| IsNull | findByAgeIsNull |
| IsNotNull,NotNull | findByAge(Is)NotNull |
| Like | findByFirstnameLike |
| NotLike | findByFirstnameNotLike |
| StartingWith | findByFirstnameStartingWith |
| EndingWith | findByFirstnameEndingWith |
| Containing | findByFirstnameContaining |
| OrderBy | findByAgeOrderByLastnameDesc |
| Not | findByLastnameNot |
| In | findByAgeIn(Collection ages) |
| NotIn | findByAgeNotIn(Collection ages) |
| TRUE | findByActiveTrue() |
| FALSE | findByActiveFalse() |
| IgnoreCase | findByFirstnameIgnoreCase |

相关推荐
求知若饥7 分钟前
NestJS 项目实战-权限管理系统开发(六)
后端·node.js·nestjs
禁默36 分钟前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
Cachel wood42 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Code哈哈笑1 小时前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
gb42152871 小时前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端
程序猿进阶1 小时前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
zfoo-framework1 小时前
【jenkins插件】
java
风_流沙1 小时前
java 对ElasticSearch数据库操作封装工具类(对你是否适用嘞)
java·数据库·elasticsearch
颜淡慕潇1 小时前
【K8S问题系列 |19 】如何解决 Pod 无法挂载 PVC问题
后端·云原生·容器·kubernetes