当前位置: 首页 > news >正文

【Java】JPA

你希望深入了解 JPA 这个 ORM 规范,我会从它的定义、核心设计思想、核心组件、常用注解、基本使用方式以及与 Hibernate 的关系等方面,为你做全面且易懂的讲解,帮你彻底搞懂 JPA。

一、JPA 是什么?

JPA(Java Persistence API,Java 持久化 API)不是一个具体的 ORM 框架,而是 Java EE 官方制定的一套对象关系映射的标准规范(接口 + 注解/XML)。

简单理解:

  • JPA 是“接口/规则”,定义了如何将 Java 对象映射到数据库表、如何执行 CRUD 操作等标准;
  • Hibernate、EclipseLink、OpenJPA 是 JPA 的实现(具体干活的框架),其中 Hibernate 是最主流、最成熟的实现,也是 Spring Data JPA 默认的底层实现。

JPA 诞生的核心目的:统一 Java 持久层的开发标准,避免开发者被某一个 ORM 框架绑定(比如早期只用 Hibernate 会导致代码和框架强耦合)。

二、JPA 的核心设计思想

JPA 遵循“面向对象”的设计思路,核心是将数据库表与 Java 实体类(Entity)做映射,让你通过操作 Java 对象来完成数据库操作,无需编写原生 SQL(也支持自定义 SQL)。

核心目标:

  • 消除 JDBC 代码的冗余(不用手动写ConnectionPreparedStatement、结果集映射等);
  • 以面向对象的方式操作数据库(比如用entityManager.persist(user)代替INSERT语句);
  • 提供统一的 API,降低切换 ORM 实现的成本(比如从 Hibernate 切换到 EclipseLink 只需改配置)。

三、JPA 的核心组件

JPA 的核心由 3 部分组成,也是你使用 JPA 必须掌握的核心内容:

1. 核心 API(接口)
API 接口作用
EntityManagerJPA 的核心操作接口,用于执行实体的增删改查、获取事务、创建查询等
EntityManagerFactory用于创建EntityManager的工厂类(重量级对象,全局只创建一个)
EntityTransaction事务管理接口(也可结合 Spring 事务使用,更推荐)
Query/TypedQueryJPA 的查询接口,支持 JPQL/SQL 查询
2. 注解(核心,用于对象-表映射)

JPA 的核心注解都在javax.persistence包下(Spring Boot 中已自动引入),常用注解如下:

注解作用
@Entity标记类为 JPA 实体类,对应数据库中的一张表
@Table配置实体类对应的数据库表名(默认类名小写)
@Id标记字段为主键
@GeneratedValue配置主键生成策略(如自增、UUID 等)
@Column配置字段对应的数据库列名、长度、非空、唯一等属性(默认字段名)
@Transient标记字段不映射到数据库(仅内存使用)
@OneToOne一对一关联关系
@OneToMany一对多关联关系
@ManyToOne多对一关联关系
@ManyToMany多对多关联关系
3. 查询语言:JPQL

JPQL(Java Persistence Query Language)是 JPA 定义的面向对象的查询语言,基于实体类和属性(而非数据库表和字段),最终会被 JPA 实现(如 Hibernate)翻译成原生 SQL。

比如:

  • JPQL:SELECT u FROM User u WHERE u.userName = ?1(User 是实体类名,userName 是实体属性)
  • 对应的 SQL:SELECT * FROM t_user WHERE user_name = ?

JPQL 支持分页、排序、聚合函数(COUNT/SUM 等),也支持原生 SQL 嵌入。

四、JPA 的基本使用(纯 JPA + Spring Boot 两种方式)

方式 1:纯 JPA 原生使用(理解底层原理)
// 1. 定义实体类importjavax.persistence.*;@Entity// 标记为实体类@Table(name="t_user")// 对应数据库表 t_userpublicclassUser{@Id// 主键@GeneratedValue(strategy=GenerationType.IDENTITY)// 自增主键(MySQL 适用)privateLongid;@Column(name="user_name",length=50,nullable=false,unique=true)// 映射字段:列名 user_name,长度 50,非空,唯一privateStringuserName;@Column(nullable=false)// 非空privateIntegerage;@Transient// 该字段不映射到数据库privateStringtempField;// 必须有无参构造器(JPA 反射需要)publicUser(){}// 有参构造器、getter/setter 省略}// 2. 原生 JPA 操作(手动管理 EntityManager)publicclassJpaNativeDemo{publicstaticvoidmain(String[]args){// 1. 创建 EntityManagerFactory(全局唯一,重量级)EntityManagerFactoryemf=Persistence.createEntityManagerFactory("jpa_demo");// 2. 创建 EntityManager(轻量级,每次操作创建/关闭)EntityManagerem=emf.createEntityManager();// 3. 开启事务EntityTransactiontx=em.getTransaction();tx.begin();try{// 4. 操作数据库:保存用户Useruser=newUser();user.setUserName("张三");user.setAge(25);em.persist(user);// 插入数据(对应 INSERT)// 5. 查询用户UserfindUser=em.find(User.class,1L);// 根据主键查询(对应 SELECT)System.out.println("查询到用户:"+findUser.getUserName());// 6. 修改用户findUser.setAge(26);em.merge(findUser);// 更新数据(对应 UPDATE)// 7. 删除用户// em.remove(findUser); // 删除数据(对应 DELETE)// 8. 提交事务tx.commit();}catch(Exceptione){// 回滚事务tx.rollback();e.printStackTrace();}finally{// 关闭资源em.close();emf.close();}}}// 3. 配置文件(META-INF/persistence.xml)<?xml version="1.0"encoding="UTF-8"?><persistence xmlns="http://java.sun.com/xml/ns/persistence"version="2.1"><persistence-unit name="jpa_demo"transaction-type="RESOURCE_LOCAL"><!--JPA 实现类(Hibernate--><provider>org.hibernate.jpa.HibernatePersistenceProvider</provider><!--映射的实体类--><class>com.example.entity.User</class><properties><!--数据库连接信息--><property name="javax.persistence.jdbc.driver"value="com.mysql.cj.jdbc.Driver"/><property name="javax.persistence.jdbc.url"value="jdbc:mysql://localhost:3306/test?useSSL=false"/><property name="javax.persistence.jdbc.user"value="root"/><property name="javax.persistence.jdbc.password"value="123456"/><!--Hibernate配置--><property name="hibernate.hbm2ddl.auto"value="update"/><!--自动更新表结构--><property name="hibernate.show_sql"value="true"/><!--打印 SQL--><property name="hibernate.format_sql"value="true"/><!--格式化 SQL--><property name="hibernate.dialect"value="org.hibernate.dialect.MySQL8Dialect"/><!--数据库方言--></properties></persistence-unit></persistence>
方式 2:Spring Boot + Spring Data JPA(实际开发主流)

Spring Data JPA 是 Spring 对 JPA 的进一步封装,提供了通用的 CRUD 接口,无需手动写基础操作代码,是实际开发中最常用的方式:

步骤 1:引入依赖(pom.xml)
<dependencies><!-- Spring Boot JPA 起步依赖(自动引入 Hibernate) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- MySQL 驱动 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!-- Spring Boot Web(方便测试) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
步骤 2:配置 application.yml
spring:# 数据库连接配置datasource:url:jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=Asia/Shanghaiusername:rootpassword:123456driver-class-name:com.mysql.cj.jdbc.Driver# JPA 配置jpa:hibernate:ddl-auto:update# 表结构策略:none(无)、create(每次创建)、update(更新)、validate(校验)show-sql:true# 打印 SQLproperties:hibernate:format_sql:true# 格式化 SQLopen-in-view:false# 关闭 Open Session In View(避免性能问题)database-platform:org.hibernate.dialect.MySQL8Dialect# 数据库方言
步骤 3:编写 Repository 接口(核心,无需写实现)
importorg.springframework.data.jpa.repository.JpaRepository;importorg.springframework.data.jpa.repository.Query;importorg.springframework.data.repository.query.Param;importjava.util.List;// 继承 JpaRepository<实体类, 主键类型>,自动获得 CRUD 方法publicinterfaceUserRepositoryextendsJpaRepository<User,Long>{// 1. 按方法名自动生成 SQL(无需写 JPQL/SQL)UserfindByUserName(StringuserName);// 根据用户名查询List<User>findByAgeGreaterThan(Integerage);// 查询年龄大于指定值的用户// 2. 自定义 JPQL 查询(推荐)@Query("SELECT u FROM User u WHERE u.age BETWEEN :minAge AND :maxAge")List<User>findByAgeRange(@Param("minAge")IntegerminAge,@Param("maxAge")IntegermaxAge);// 3. 自定义原生 SQL 查询@Query(value="SELECT * FROM t_user WHERE age = ?1",nativeQuery=true)List<User>findByAge(Integerage);}
步骤 4:编写 Service 和 Controller(测试)
// Service 层(整合事务)importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjava.util.List;@ServicepublicclassUserService{@AutowiredprivateUserRepositoryuserRepository;// 保存用户(事务)@TransactionalpublicUsersaveUser(Useruser){returnuserRepository.save(user);// 内置 save 方法}// 根据 ID 查询publicUsergetUserById(Longid){// findById 返回 Optional,避免空指针returnuserRepository.findById(id).orElse(null);}// 查询所有用户publicList<User>getAllUsers(){returnuserRepository.findAll();}// 自定义查询:按年龄范围publicList<User>getUsersByAgeRange(Integermin,Integermax){returnuserRepository.findByAgeRange(min,max);}// 删除用户@TransactionalpublicvoiddeleteUser(Longid){userRepository.deleteById(id);}}// Controller 层(测试接口)importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;importjava.util.List;@RestController@RequestMapping("/users")publicclassUserController{@AutowiredprivateUserServiceuserService;// 新增用户@PostMappingpublicUseraddUser(@RequestBodyUseruser){returnuserService.saveUser(user);}// 根据 ID 查询@GetMapping("/{id}")publicUsergetUser(@PathVariableLongid){returnuserService.getUserById(id);}// 查询所有@GetMappingpublicList<User>getAll(){returnuserService.getAllUsers();}// 按年龄范围查询@GetMapping("/age-range")publicList<User>getByAgeRange(@RequestParamIntegermin,@RequestParamIntegermax){returnuserService.getUsersByAgeRange(min,max);}// 删除用户@DeleteMapping("/{id}")publicStringdelete(@PathVariableLongid){userService.deleteUser(id);return"删除成功";}}

五、JPA 的核心优势与适用场景

优势:
  1. 标准化:遵循 Java 官方规范,不绑定具体实现,可灵活切换 ORM 框架;
  2. 简化开发:无需写基础 CRUD 代码,Spring Data JPA 按方法名自动生成 SQL;
  3. 面向对象:以操作 Java 对象的方式操作数据库,符合面向对象编程思想;
  4. 灵活查询:支持 JPQL、原生 SQL、方法名查询三种方式,兼顾简洁性和灵活性;
  5. 无缝整合 Spring:与 Spring Boot/Spring 事务/AOP 等生态完美融合。
适用场景:
  • 中大型企业级应用,追求代码规范、低耦合;
  • 业务逻辑以简单 CRUD 为主,无需复杂 SQL;
  • 希望快速开发,减少重复的数据库操作代码;
  • 需兼顾跨数据库兼容性(JPA 自动适配不同数据库方言)。
局限性:
  • 复杂 SQL(如多表关联、分组聚合、存储过程)不如 MyBatis 灵活;
  • 自动生成的 SQL 可能存在性能问题(需手动优化);
  • 学习成本略高(需理解 ORM 思想、JPQL、关联关系等)。

总结

  1. JPA 是ORM 规范,而非具体框架,Hibernate 是其最主流的实现,Spring Data JPA 是 Spring 对 JPA 的进一步封装(开发首选);
  2. JPA 的核心是通过注解实现 Java 实体类与数据库表的映射,通过EntityManager或 Spring Data JPA 接口完成数据库操作;
  3. Spring Boot + Spring Data JPA 是实际开发的主流方式,核心优势是简化 CRUD 开发、统一规范、整合 Spring 生态,适合中大型应用的快速开发。
http://www.jsqmd.com/news/142631/

相关文章:

  • 数据滤波神器卡尔曼滤波:如何在噪声中找到真实信号?[特殊字符]
  • PaddlePaddle + GPU算力组合推荐:中文自然语言处理最佳实践
  • Windows 32位系统音视频处理终极方案:FFmpeg-Builds-Win32完全指南
  • 深度解析edge-tts语音合成:从403错误到流畅使用的完整实战指南
  • 合规文化建设:从意识到行为的转变
  • 14、图数据结构的C实现与遍历算法
  • WinDbg Preview下载集成Visual Studio?全面讲解方法
  • SDXL-ControlNet Canny模型:从零开始的AI图像控制终极指南
  • Tduck问卷调查系统完整使用指南:从零开始构建专业表单
  • Windows 11 个性化改造利器:ExplorerPatcher 深度使用手册
  • 【边缘计算新突破】:Open-AutoGLM如何应对移动端资源瓶颈?
  • iOS自动化测试终极指南:从零开始掌握iOS-Tagent
  • VirtualApp沙盒技术:零基础搭建应用多开环境全攻略
  • 3步搞定LogicFlow节点缩放:从卡顿到流畅的完整优化指南
  • 2025净化工程节能改造公司TOP5权威推荐:资深机构甄选指南 - mypinpai
  • Elasticsearch内存模型快速理解:资源分配对性能的影响分析
  • 小电视空降助手:B站广告智能跳过插件完全指南
  • 酷安Lite桌面端终极指南:一键安装免费Windows客户端
  • VRCX:如何彻底解决VRChat社交管理难题?
  • 2025年浙江无尘车间厂推荐排行榜,精选无尘车间装修供应商推荐 - 工业推荐榜
  • MoveIt2 机器人运动规划框架终极实战指南
  • Open-AutoGLM插件使用避坑指南:8个常见错误及最佳实践方案
  • 售后好的矩形方管生产厂有哪些?矩形方管加工厂哪个值得选? - 工业品牌热点
  • 基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
  • 15、图算法:最小生成树与节点着色
  • Sublime Monokai Extended:终极代码配色方案完整指南
  • Rete.js完整指南:轻松构建可视化编程界面的终极方案
  • 口碑与实力兼具的高性价比干冰清洗设备品牌推荐 - 工业品网
  • PDF补丁丁终极跨平台指南:3分钟搞定Windows/Linux双系统PDF处理
  • 终极指南:5步轻松获取游戏DLC的CreamApi完整教程