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

相关文章
|
9天前
|
安全 Java 开发者
如何在Spring框架中实现横切关注点的集中管理和重用?
【4月更文挑战第30天】如何在Spring框架中实现横切关注点的集中管理和重用?
17 0
|
20小时前
|
前端开发 安全 Java
使用Spring框架加速Java开发
使用Spring框架加速Java开发
5 0
|
23小时前
|
前端开发 Java 应用服务中间件
Spring MVC框架概述
Spring MVC 是一个基于Java的轻量级Web框架,采用MVC设计模型实现请求驱动的松耦合应用开发。框架包括DispatcherServlet、HandlerMapping、Handler、HandlerAdapter、ViewResolver核心组件。DispatcherServlet协调这些组件处理HTTP请求和响应,Controller处理业务逻辑,Model封装数据,View负责渲染。通过注解@Controller、@RequestMapping等简化开发,支持RESTful请求。Spring MVC具有清晰的角色分配、Spring框架集成、多种视图技术支持以及异常处理等优点。
8 1
|
8天前
|
SQL Java 数据库连接
Springboot框架整合Spring JDBC操作数据
JDBC是Java数据库连接API,用于执行SQL并访问多种关系数据库。它包括一系列Java类和接口,用于建立数据库连接、创建数据库操作对象、定义SQL语句、执行操作并处理结果集。直接使用JDBC涉及七个步骤,包括加载驱动、建立连接、创建对象、定义SQL、执行操作、处理结果和关闭资源。Spring Boot的`spring-boot-starter-jdbc`简化了这些步骤,提供了一个在Spring生态中更便捷使用JDBC的封装。集成Spring JDBC需要添加相关依赖,配置数据库连接信息,并通过JdbcTemplate进行数据库操作,如插入、更新、删除和查询。
|
8天前
|
SQL Java 数据库连接
Springboot框架整合Spring Data JPA操作数据
Spring Data JPA是Spring基于ORM和JPA规范封装的框架,简化了数据库操作,提供增删改查等接口,并可通过方法名自动生成查询。集成到Spring Boot需添加相关依赖并配置数据库连接和JPA设置。基础用法包括定义实体类和Repository接口,通过Repository接口可直接进行数据操作。此外,JPA支持关键字查询,如通过`findByAuthor`自动转换为SQL的`WHERE author=?`查询。
|
2月前
|
Java 应用服务中间件 Maven
SpringBoot 项目瘦身指南
SpringBoot 项目瘦身指南
52 0
|
3月前
|
缓存 Java Maven
Spring Boot自动配置原理
Spring Boot自动配置原理
50 0
|
2月前
|
缓存 安全 Java
Spring Boot 面试题及答案整理,最新面试题
Spring Boot 面试题及答案整理,最新面试题
135 0
|
1月前
|
存储 JSON Java
SpringBoot集成AOP实现每个接口请求参数和返回参数并记录每个接口请求时间
SpringBoot集成AOP实现每个接口请求参数和返回参数并记录每个接口请求时间
43 2
|
2月前
|
前端开发 搜索推荐 Java
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革
【Spring底层原理高级进阶】基于Spring Boot和Spring WebFlux的实时推荐系统的核心:响应式编程与 WebFlux 的颠覆性变革