查询方法 find...By、read...By、query...By 和 get...By 在 spring 数据中有啥区别?
Posted
技术标签:
【中文标题】查询方法 find...By、read...By、query...By 和 get...By 在 spring 数据中有啥区别?【英文标题】:What is the difference between query-methods find…By, read…By, query…By, and get…By in spring data?查询方法 find...By、read...By、query...By 和 get...By 在 spring 数据中有什么区别? 【发布时间】:2017-02-13 15:31:54 【问题描述】:我正在查看弹簧数据的docs,但没有找到使用方法read...By
、get...By
而不是find...By
的理由(就像通常那样)。
请澄清:
你能写一个query..By
方法的例子吗?
【问题讨论】:
这四种方法没有区别。这些已作为适合个人偏好的选项提供,因为不同的开发人员可能对他们希望如何命名其访问器方法有不同的偏好。Foo findByName (String name)
、Foo getByName (String name)
、Foo queryByName (String name)
和 Foo readByName (String name)
都是等价的 - 它们会找到一个名称与作为 name
参数传递的值匹配的 Foo
。
【参考方案1】:
在我看来,接受的答案是不正确的。这两种情况在内部是不同的:
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();
// order.setCustomer(repo.findById(123L)); // Opt 1: goes directly to DB and load everything from this customer. But we don't need it all
order.setCustomer(repo.getOne(123L)); // Opt 2: Won't go to DB for the customer
orderRepo.saveOrUpdate(order);
您可以查看解释差异的整篇文章,更好地了解 getReference
此处:https://vladmihalcea.com/entitymanager-find-getreference-jpa/
【讨论】:
【参考方案3】:我想这会帮助你理解..
这两个接口的区别在于它们方法的语义。 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
【讨论】:
你真的试过这个吗?对我来说,get
正在返回 null
,就像 find
..【参考方案4】:
我不知道其他子项目如何,但是对于 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";
【讨论】:
在这里看到了很好的解释:javacodemonk.com/post/87/… 赞成分享它实施的地方!以上是关于查询方法 find...By、read...By、query...By 和 get...By 在 spring 数据中有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章