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

相关文章
|
19天前
|
XML 安全 Java
|
22天前
|
缓存 NoSQL Java
什么是缓存?如何在 Spring Boot 中使用缓存框架
什么是缓存?如何在 Spring Boot 中使用缓存框架
29 0
|
5天前
|
IDE Java 测试技术
互联网应用主流框架整合之Spring Boot开发
通过本文的介绍,我们详细探讨了Spring Boot开发的核心概念和实践方法,包括项目结构、数据访问层、服务层、控制层、配置管理、单元测试以及部署与运行。Spring Boot通过简化配置和强大的生态系统,使得互联网应用的开发更加高效和可靠。希望本文能够帮助开发者快速掌握Spring Boot,并在实际项目中灵活应用。
23 5
|
15天前
|
缓存 Java 数据库连接
Spring框架中的事件机制:深入理解与实践
Spring框架是一个广泛使用的Java企业级应用框架,提供了依赖注入、面向切面编程(AOP)、事务管理、Web应用程序开发等一系列功能。在Spring框架中,事件机制是一种重要的通信方式,它允许不同组件之间进行松耦合的通信,提高了应用程序的可维护性和可扩展性。本文将深入探讨Spring框架中的事件机制,包括不同类型的事件、底层原理、应用实践以及优缺点。
46 8
|
25天前
|
存储 Java 关系型数据库
在Spring Boot中整合Seata框架实现分布式事务
可以在 Spring Boot 中成功整合 Seata 框架,实现分布式事务的管理和处理。在实际应用中,还需要根据具体的业务需求和技术架构进行进一步的优化和调整。同时,要注意处理各种可能出现的问题,以保障分布式事务的顺利执行。
45 6
|
3月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
224 2
|
4天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
42 14
|
27天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
42 1
SpringBoot入门(7)- 配置热部署devtools工具
|
1月前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
43 2
 SpringBoot入门(7)- 配置热部署devtools工具
下一篇
DataWorks