我正在查看 Spring Data 的 docs,但没有找到使用方法
read...By
、get...By
而不是 find...By
的理由(就像通常所做的那样)。
请澄清:
你能写一个
query..By
方法的例子吗?
编辑:
这个答案涵盖了 docs
中描述的 Spring 查询创建机制
如果您正在寻找具体方法
findById(..)
与getById(..)
之间的差异,您可以找到很好的描述here(感谢@smile评论)
原答案:
我不知道其他子项目怎么样,但对于 Spring Data JPA (1.10.2),这些方法将用作别名。每个方法调用都会生成相同的条件查询(以及相同的 SQL 查询)。
在内部,这些前缀之间没有区别。它仅用于查询模式匹配:
private static final String QUERY_PATTERN = "find|read|get|query|stream";
相同的方法用于
remove...By
与 delete...By
方法:
private static final String DELETE_PATTERN = "delete|remove";
我想这会帮助你理解..
两个接口的区别在于其方法的语义。 CRUD 存储库“查找”某些内容,而 JPA 存储库“获取”某些内容。虽然“find”可能根本没有结果,但“get”总是会返回一些东西——否则 JPA 存储库会抛出异常。
在我看来,接受的答案是不正确的。这两种情况的内部是不同的:
getById()
返回对具有给定标识符的实体的引用。它调用 EntityManager.getReference()
并返回一个惰性代理。因此,当您无法处理此响应时 - 在尝试获取惰性字段时,您将收到 LazyInitializationException。
findById()
从数据库获取真实对象。
我不知道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。