spring data 中的查询方法 find…By、read…By、query…By 和 get…By 有什么区别?

问题描述 投票:0回答:4

我正在查看 Spring Data 的 docs,但没有找到使用方法

read...By
get...By
而不是
find...By
的理由(就像通常所做的那样)。 请澄清:

  • 这个方法有什么作用?
  • 或者这个方法的目的是什么?
  • 什么情况下更适合使用这种方法?
  • 它们有什么区别?

你能写一个

query..By
方法的例子吗?

spring spring-data spring-data-jpa
4个回答
46
投票

编辑:
这个答案涵盖了 docs
中描述的 Spring 查询创建机制 如果您正在寻找具体方法

findById(..)
getById(..)
之间的差异,您可以找到很好的描述here(感谢@smile评论)

原答案:
我不知道其他子项目怎么样,但对于 Spring Data JPA (1.10.2),这些方法将用作别名。每个方法调用都会生成相同的条件查询(以及相同的 SQL 查询)。

在内部,这些前缀之间没有区别。它仅用于查询模式匹配:

private static final String QUERY_PATTERN = "find|read|get|query|stream";

https://github.com/spring-projects/spring-data-commons/blob/8bc022ebd7097b921ae1ef6c87f0ae9fc05bba5f/src/main/java/org/springframework/data/repository/query/parser/PartTree.java#L54

相同的方法用于

remove...By
delete...By
方法:

private static final String DELETE_PATTERN = "delete|remove";

6
投票

我想这会帮助你理解..

两个接口的区别在于其方法的语义。 CRUD 存储库“查找”某些内容,而 JPA 存储库“获取”某些内容。虽然“find”可能根本没有结果,但“get”总是会返回一些东西——否则 JPA 存储库会抛出异常。

来源:https://tuhrig.de/find-vs-get/

你也可以看看这篇文章。 https://softwareengineering.stackexchange.com/questions/182113/how-and-why-to-decide- Between-naming-methods-with-get-and-find-prefixes


2
投票

在我看来,接受的答案是不正确的。这两种情况的内部是不同的:

  • getById()
    返回对具有给定标识符的实体的引用。它调用
    EntityManager.getReference()
    并返回一个惰性代理。因此,当您无法处理此响应时 - 在尝试获取惰性字段时,您将收到 LazyInitializationException。
  • findById()
     
    从数据库获取真实对象

2
投票
我不知道Spring过去是如何实现这一点的,但至少目前来说它们是相同的(只是别名)是不正确的。

(上面这部分与原来接受的内容不正确)

Spring JPA 是 JPA 之上的一层。因此,这些操作中的每一个都映射到

标准 JPA 操作:

findById(id)

 -> [JPA] 
entityManager.find

同时,

getOne(id)

 -> [JPA] 
entityManager.getReference

那么 JPA 有何不同?

entityManager.find

直接进入数据库,执行查询并将所有映射列返回到内存。非常简单。

entityManager.getReference

 较少使用(不太为人所知)。这是一种
懒惰的发现。 也就是说,它不直接进入数据库。仅当使用数据时才会出现。它的主要目标是当您只想引用某个实体,但不会使用该实体(列的值)时。

例如:

class Customer { Long id; ... many other fields } class Order { Customer customer; // ... other }
您想保存新的

Order

:

var order = new Order(); // Opt 1 (find): goes directly to DB and loads everything from this customer. Even tough we don't need it all. // order.setCustomer(repo.findById(123L)); // ... // Opt 2 (get): Won't go to DB at this point - but rather get a reference to a specific id // When saving, may throw exception if customer with given id doesn't exist order.setCustomer(repo.getOne(123L)); orderRepo.saveOrUpdate(order);
您可以查看整篇文章来解释差异,以及更好地了解 

getReference

https://vladmihalcea.com/entitymanager-find-getreference-jpa/. 这篇文章不是关于 Spring,但同样,Spring JPA 只是遵循 JPA。

© www.soinside.com 2019 - 2024. All rights reserved.