Skip to content

❤️ JpaRepository

JpaRepository 中有许多默认方法,也可以在继承了 JpaRepository 的接口中自定义方法,这些方法会根据方法名自动生成相应条件的 SQL 语句,无需额外配置

java
// JpaRepository<实体名,主键的数据类型>
@Repository
public interface CustomerRepository extends JpaRepository<Customer, Long> {

    Customer save(Customer customer);

	// 查询接口
    Optional<Customer> findById(Long id);

    List<Customer> findByCustName(String custName);
}

如果你定义了一个继承自 `Repository` 接口的自定义接口,Spring 容器会自动为你创建这个接口的实例,并注入到 IOC 容器中,也就是不需要加 `@Repository`

💛 新增,修改

不推荐使用 save 方法去 update,因为 save 方法是先 select 来判断是要 create,还是 update,这增加了开销

`save` 既可以 C,也可以 U:

  • 主键为空 >>> C
  • 主键不存在 >>> C
  • 主键已存在 >>> U

当然,可以实现 Persistable 接口,来自定义判断逻辑

  • save(实体对象) 增改,但是会等待一个事务的提交,其才会影响到数据库
  • saveAll(集合) 批量增改
  • saveAndFlush(实体对象) 增改,并立即提交这个操作
  • saveAllAndFlush(集合)
java
// 不带主键,就是新增
customerRepository.save(new Customer(null, 33L, "nelson", "France"));

// 带主键,就是修改
customerRepository.save(new Customer(1L, 2L, "Kite", "Japen"));
java
customerRepository.saveAllAndFlush(List.of(
	new Customer(null, 33L, "nelson", "France"),
	new Customer(null, 33L, "nelson", "France")
));

💛 查

  • 【普通】
    • findAll() 无条件查
    • findAllById(id集合)
  • 【条件】
    • findAll(Example 条件对象)
  • 【排序】
    • findAll(Sort 排序对象)

java
// 构造条件
Example<Customer> example1 = Example.of(new Customer(null, 33L, null, null));  // null值不会作为条件拼接到where条件中
// 构造排序规则
Sort sort = Sort.by("custName").descending();

customerRepository.findAll(example1, sort);

💙 Example

  • Example.of(实体对象)
  • Example.of(实体对象, ExampleMatcher) 支持模糊,范围,忽略大小写查询

WARNING

  • 支持动态条件,如果值为 null,则不拼接该 WHERE 条件
  • 不支持范围查询

💛 其他方法

判断是否存在

  • Boolean existsById(id) 看对应 id 的数据是否存在
  • Boolean exists(Example 条件对象) 复杂条件查询数据是否存在
java
System.out.println(customerRepository.existsById(1L));
java
// 构建条件,id为1,并且name为Kite的数据
Example<Customer> example = Example.of(new Customer(1L, null, "Kite", null));  

System.out.println(customerRepository.exists(example));

判断数量

  • count()
  • count(Example 条件对象)
java
long count = customerRepository.count();
System.out.println(count);

当你在定义 @Bean 注解的方法参数中使用 Repository 接口时,Spring 会自动注入相应的 Repository 实例,你不需要手动进行依赖注入

💛 SimpleJpaRepository

❤️ 方法名派生

关键词

通过方法名的语义自动生成 sql,支持 RD,不支持 CU

💛 查

find 结果限制条件 By 条件 Ignore 忽略条件 OrderBy 排序条件

结果限制条件

  • Distinct 限制结果不重复
  • First
  • One 不推荐使用,如果数据记录有多个,会报错
  • TopN 限制结果数为 N 个
java
findDistinctByName

条件名称

java
// 首先会去Person类中找addressZipCode属性,但是找不到,那就 ……
// 找Person类中address属性的子属性zipCode,然后作为条件
List<Person> findByAddressZipCode(ZipCode zipCode);
java
// 根据emailAddress和lastname忽略大小写的查找,结果去重,并根据Firstname进行升序排序
findDistinctByEmailAddressAndLastnameAllIgnoreCaseOrderByFirstnameAsc(EmailAddress emailAddress, String lastname)

❤️ 自定义 sql

可以使用 QueryRewriter 动态更改已定义的 sql ,类似 AOP #待学习

WARNING

  • 支持编写 sql 实现范围查询
  • 不支持动态查询,如果值为 null,也会拼接进 sql

💛 查

  • Like / NotLike 模糊查询,需要与通配符结合使用
  • Contains 包含模糊查询,相当于 Like %……%
  • StartsWith / EndsWith 查询指定前缀/后缀开头
  • In / NotIn 字符串在指定集合中
  • Null / NotNull
java
public interface UserRepository extends JpaRepository<User, Long> {
    // 传入的firstname,lastname参数会被注入到sql中
	@Query("select u from User u where u.emailAddress = ?1")
	User findByEmailAddress(String emailAddress);

	@Query("select u from User u where u.firstname like %?1")
	List<User> findByFirstnameEndsWith(String firstname);
}

💛 删改

https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html#jpa.modifying-queries