【spring 官方ORM框架】spring-data-jpa详细教程

简介: 【spring 官方ORM框架】spring-data-jpa详细教程

部分内容参照 spring-data-jpa V2.6.5官方文档。


一、框架特性

1666272658089.jpg

  • 基于Spring和JPA强大支持构建数据库
  • 支持查询领域特定语言Querydsl(domain specification language)
  • 模型类(实体类)的透明审计
  • 分页查询、支持动态查询、整合自定义的数据访问程序
  • 启动时注解查询验证
  • 基于XML实体映射
  • 注解@EnableJpaRepositories配置数据库


二、框架实战


框架核心的类就是Repository库。看一下该类的UML图。

1666272684643.jpg

框架支持两种查询方法,其一是根据方法名派生,又叫做命名查询,无需写SQL语言;其二是使用@Query注解,又称为注解查询。


2.1 命名查询


下表是命名查询支持的方法名及其对应的持久化查询语句。


命名查询支持的方法名

关键字 例子 JPQL (Java持久化查询语言)

Distinct

findDistinctByLastnameAndFirstname

select distinct … where x.lastname = ?1 and x.firstname = ?2

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, Null

findByAge(Is)Null

… 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 (参数后追加%)

EndingWith

findByFirstnameEndingWith

… where x.firstname like ?1 (参数前追加 %)

Containing

findByFirstnameContaining

… where x.firstname like ?1 (参数封装在 %内)

OrderBy

findByAgeOrderByLastnameDesc

… where x.age = ?1 order by x.lastname desc

Not

findByLastnameNot

… where x.lastname <> ?1

In

findByAgeIn(Collection<Age> ages)参数支持数组和可变参数类型

… where x.age in ?1

NotIn

findByAgeNotIn(Collection<Age> ages)参数支持数组和可变参数类型

… where x.age not in ?1

True

findByActiveTrue()

… where x.active = true

False

findByActiveFalse()

… where x.active = false

IgnoreCase

findByFirstnameIgnoreCase

… where UPPER(x.firstname) = UPPER(?1)


2.2 注解查询@Query


2.2.1 基本用法


?是占位符,解释后面的数字代表的参数,称为基于位置的参数。


public interface UserRepository extends JpaRepository<User, Long> {
  @Query("select u from User u where u.emailAddress = ?1")
  User findByEmailAddress(String emailAddress);
}

2.2.2 like用法


%表示like表达式的占位符。


public interface UserRepository extends JpaRepository<User, Long> {
  @Query("select u from User u where u.firstname like %?1")
  List<User> findByFirstnameEndsWith(String firstname);
}

2.2.3 命名参数


默认使用基于位置的参数,也可以使用下述命名参数。这种方式写的太复杂,没有基于位置的好用。


public interface UserRepository extends JpaRepository<User, Long> {
  @Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
  User findByLastnameOrFirstname(@Param("lastname") String lastname,
                                 @Param("firstname") String firstname);
}

2.2.4 SpEL( Spring Expression Language)


@Query注解支持Spring表达式语言,这种方法也是太多复杂,不过我们遇到也要知道是可以这样写的。


@Entity
public class User {
  @Id
  @GeneratedValue
  Long id;
  String lastname;
}
public interface UserRepository extends JpaRepository<User,Long> {
  @Query("select u from #{#entityName} u where u.lastname = ?1")
  List<User> findByLastname(String lastname);
}

2.2.5 更新语句


JPA的更新操作很复杂,首先要开启事务,接着告诉框架是执行什么操作,最后是在@Query注解里写更新SQL。


@Transactional
@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);

当然还有另一种方法就是,首先更新模型类,再执行save操作。这个过程执行了两次数据IO,第一次是查询旧的模型类,然后对象更新,再进行保存。


2.2.6 删除语句


interface UserRepository extends Repository<User, Long> {
  void deleteByRoleId(long roleId);
  @Transactional
  @Modifying
  @Query("delete from User u where u.role.id = ?1")
  void deleteInBulkByRoleId(long roleId);
}

2.3 实体状态监测策略


版本和ID属性检测


2.4 排序


public interface UserRepository extends JpaRepository<User, Long> {
  @Query("select u from User u where u.lastname like ?1%")
  List<User> findByAndSort(String lastname, Sort sort);
  @Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%")
  List<Object[]> findByAsArrayAndSort(String lastname, Sort sort);
}
repo.findByAndSort("lannister", Sort.by("firstname"));                
repo.findByAndSort("stark", Sort.by("LENGTH(firstname)"));            
repo.findByAndSort("targaryen", JpaSort.unsafe("LENGTH(firstname)")); 
repo.findByAsArrayAndSort("bolton", Sort.by("fn_len"));      

2.5 表关系


2.5.1 如何设计库表


确定表与表之间的关联关系,一对一、一对多、多对多。

关系 使用频次 例子 备注 建表原则
一对一 较少 学生表 可以制作成一张表,特殊的一对多关系,太复杂时,采用分表策略 主表的主键和从表的外键(唯一),形成主外键关系,外键唯一unique;主表的主键和从表的主键,形成主外键关系
一对多 非常多 院系和学生,部门和员工,客户和订单,分类和商品 从表中建外键与主表进行关联 在从表(多方)创建一个字段,字段作为外键指向主表(一方)的主键
多对多 较多 学生表和课表,老师和学生表,用户和角色表 创建中间关系表 创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键


设计数据库表时,不要想太复杂,就根据这三种关系进行字段的设计。

1666273282813.jpg


2.5.2 JPA关系表操作步骤


使用注解标注列完成表关系的建立。

@OneToOne

@OneToMany

@ManyToMany


番外篇


FW1 Querydsl是啥


Querydsl是一个Java开源框架,它支持构造静态类型的类似sql的查询。不需要将查询写成内联字符串或外部化到XML文件中。目前 Querydsl 支持的平台包括 JPA,JDO,SQL,Java Collections,RDF,Lucene,Hibernate Search。


与简单的字符串相比,使用流畅的API的好处是:


  • IDE中的代码完成
  • 几乎不允许语法上无效的查询
  • 可以安全地引用域类型和属性
  • 更好地对域类型的更改进行重构

相关文章
|
11天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
554 6
|
9天前
|
XML 前端开发 Java
控制spring框架注解介绍
控制spring框架注解介绍
|
9天前
|
存储 NoSQL Java
Spring Session框架
Spring Session 是一个用于在分布式环境中管理会话的框架,旨在解决传统基于 Servlet 容器的会话管理在集群和云环境中的局限性。它通过将用户会话数据存储在外部介质(如数据库或 Redis)中,实现了会话数据的跨服务器共享,提高了应用的可扩展性和性能。Spring Session 提供了无缝集成 Spring 框架的 API,支持会话过期策略、并发控制等功能,使开发者能够轻松实现高可用的会话管理。
Spring Session框架
|
16天前
|
Java 应用服务中间件 开发者
深入探索并实践Spring Boot框架
深入探索并实践Spring Boot框架
27 2
|
16天前
|
机器学习/深度学习 数据采集 JavaScript
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
ADR药品不良反应监测系统是一款智能化工具,用于监测和分析药品不良反应。该系统通过收集和分析病历、处方及实验室数据,快速识别潜在不良反应,提升用药安全性。系统采用Java开发,基于SpringBoot框架,前端使用Vue,具备数据采集、清洗、分析等功能模块,并能生成监测报告辅助医务人员决策。通过集成多种数据源并运用机器学习算法,系统可自动预警药品不良反应,有效减少药害事故,保障公众健康。
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
|
8天前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
2月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
3月前
|
Java 测试技术 数据库
Spring Boot中的项目属性配置
本节课主要讲解了 Spring Boot 中如何在业务代码中读取相关配置,包括单一配置和多个配置项,在微服务中,这种情况非常常见,往往会有很多其他微服务需要调用,所以封装一个配置类来接收这些配置是个很好的处理方式。除此之外,例如数据库相关的连接参数等等,也可以放到一个配置类中,其他遇到类似的场景,都可以这么处理。最后介绍了开发环境和生产环境配置的快速切换方式,省去了项目部署时,诸多配置信息的修改。
|
3月前
|
Java 应用服务中间件 开发者
Java面试题:解释Spring Boot的优势及其自动配置原理
Java面试题:解释Spring Boot的优势及其自动配置原理
101 0
|
8天前
|
XML Java 关系型数据库
springboot 集成 mybatis-plus 代码生成器
本文介绍了如何在Spring Boot项目中集成MyBatis-Plus代码生成器,包括导入相关依赖坐标、配置快速代码生成器以及自定义代码生成器模板的步骤和代码示例,旨在提高开发效率,快速生成Entity、Mapper、Mapper XML、Service、Controller等代码。
springboot 集成 mybatis-plus 代码生成器
下一篇
无影云桌面