简体   繁体   English

JPA/JPQL 自动方法查询生成

[英]JPA/JPQL automatic method query generation

I have a co-worker that just blew my mind.我有一个同事让我大吃一惊。 We have a Java 11/Spring Boot/Hibernate/JPA app talking to a MySQL DB.我们有一个 Java 11/Spring Boot/Hibernate/JPA 应用程序与 MySQL 数据库通信。 Apparently JPA JPQL (or something similar to that) is capable of -- but only if you write the repository methods correctly -- building out queries based on your method name.显然,JPA JPQL(或类似的东西)能够 - 但前提是您正确编写存储库方法 - 根据您的方法名称构建查询。

So for instance if we have a JPA entity:例如,如果我们有一个 JPA 实体:

@Entity
@Table(name = "accounts")
@Data
public class Account {
    @Column(name = "account_email")
    private String email;

    // ... many more fields down here
}

And then a repository for it:然后是它的存储库:

@Repository
public interface AccountRepository extends JpaRepository<Account,Long> {
    @Query("FROM Account WHERE email = :email")
    Account findByEmail(@Param(value = "email") String email);
}

Apparently (and this might be a bad example) I could just simplify that to:显然(这可能是一个不好的例子)我可以将其简化为:

@Repository
public interface AccountRepository extends JpaRepository<Account,Long> {
    Account findByEmail(String email);
}

And JPA/JPQL will figure out that since I want to " findByEmail " and Account#email exists, it just wants me to do a SELECT * FROM accounts where email = ? JPA/JPQL 会发现,既然我想“ findByEmail ”并且Account#email存在,它只需要我做一个SELECT * FROM accounts where email = ? . . Amazing!惊人!

The only problem is: I don't see this documented anywhere well , and I don't see it documented anywhere officially .唯一的问题是:我没有看到它在任何地方都有很好的记录,我也没有看到它在任何地方正式记录。 There's a few old blogs that I was able to find that insinuate the same things, but nowhere official (JPA docs, JPQL docs, etc.) that go into detail as to how it works and what its limitations are.我可以找到一些旧博客暗示相同的事情,但没有官方(JPA 文档、JPQL 文档等)详细介绍它的工作原理和局限性。

Can anyone point me in the right direction?谁能指出我正确的方向? What is this mysterious feature/technology called and what are its limitations/capabilities?这种神秘的特性/技术叫什么,它的局限性/能力是什么? Can it only work on SELECTs or can it handle inserts/updates/deletes as well?它只能在 SELECT 上工作还是也可以处理插入/更新/删除?

This is part of the Spring Data support for JPA.这是 Spring Data 对 JPA 的支持的一部分。 You can find more info at the documentation Query Methods and all the supported query-keywords in the appendix section.您可以在文档查询方法和附录部分中的所有支持的查询关键字中找到更多信息。 Here is an excerpt from the documentation:这是文档的摘录:

Query subject keywords查询主题关键词

Keyword关键词 Description描述
find…By, read…By, get…By, query…By, search…By, stream…By查找...通过,阅读...通过,获取...通过,查询...通过,搜索...通过,流...通过 General query method returning typically the repository type, a Collection or Streamable subtype or a result wrapper such as Page, GeoResults or any other store-specific result wrapper.一般查询方法通常返回存储库类型、Collection 或 Streamable 子类型或结果包装器,例如 Page、GeoResults 或任何其他特定于存储的结果包装器。 Can be used as findBy…, findMyDomainTypeBy… or in combination with additional keywords.可用作 findBy...、findMyDomainTypeBy... 或与其他关键字组合使用。
exists…By存在...由 Exists projection, returning typically a boolean result.存在投影,通常返回布尔结果。
count…By数……按 Count projection returning a numeric result.计数投影返回数字结果。
delete…By, remove…By删除...通过,删除...通过 Delete query method returning either no result (void) or the delete count.删除查询方法返回无结果 (void) 或删除计数。
…First…, …Top… ……第一……,……顶…… Limit the query results to the first of results.将查询结果限制为第一个结果。 This keyword can occur in any place of the subject between find (and the other keywords) and by.此关键字可以出现在 find(和其他关键字)和 by 之间的主题的任何位置。
…Distinct… …清楚的… Use a distinct query to return only unique results.使用不同的查询仅返回唯一的结果。 Consult the store-specific documentation whether that feature is supported.请查阅特定于商店的文档是否支持该功能。 This keyword can occur in any place of the subject between find (and the other keywords) and by.此关键字可以出现在 find(和其他关键字)和 by 之间的主题的任何位置。

Query predicate keywords查询谓词关键字

Logical keyword逻辑关键字 Keyword expressions关键字表达式
AND And
OR或者 Or或者
AFTER After, IsAfter之后,是之后
BEFORE Before, IsBefore之前,是之前
CONTAINING包含 Containing, IsContaining, Contains包含,IsContaining,包含
BETWEEN之间 Between, IsBetween之间,IsBetween
ENDING_WITH ENDING_WITH EndingWith, IsEndingWith, EndsWith EndingWith、IsEndingWith、EndsWith
EXISTS存在 Exists存在
FALSE错误的 False, IsFalse假的,是假的
GREATER_THAN比...更棒 GreaterThan, IsGreaterThan大于,大于
GREATER_THAN_EQUALS GREATER_THAN_EQUALS GreaterThanEqual, IsGreaterThanEqual大于等于,大于等于
IN In, IsIn在,伊辛
IS Is, Equals, (or no keyword)是,等于,(或没有关键字)
IS_EMPTY是空的 IsEmpty, Empty是空的,空的
IS_NOT_EMPTY IS_NOT_EMPTY IsNotEmpty, NotEmpty IsNotEmpty, NotEmpty
IS_NOT_NULL IS_NOT_NULL NotNull, IsNotNull NotNull,IsNotNull
IS_NULL一片空白 Null, IsNull空,是空
LESS_THAN少于 LessThan, IsLessThan小于,小于
LESS_THAN_EQUAL LESS_THAN_EQUAL LessThanEqual, IsLessThanEqual小于等于,小于等于
LIKE喜欢 Like, IsLike喜欢,喜欢
NEAR靠近 Near, IsNear近,近
NOT不是 Not, IsNot不,不是
NOT_IN NOT_IN NotIn, IsNotIn不在,不在
NOT_LIKE不喜欢 NotLike, IsNotLike不喜欢,不喜欢
REGEX正则表达式 Regex, MatchesRegex, Matches正则表达式,匹配正则表达式,匹配
STARTING_WITH从...开始 StartingWith, IsStartingWith, StartsWith开始于,开始于,开始于
TRUE真的 True, IsTrue真的,是真的
WITHIN Within, IsWithin内,是内

Not much of a mystery and quite well documented to be perfectly honest.没什么神秘的,而且有据可查,完全诚实。 What you mention is called a derived query which basically infers the JPQL query from the method name.您提到的称为派生查询,它基本上从方法名称中推断出 JPQL 查询。 A simple Google search can turn up quite some documentation of this feature.一个简单的谷歌搜索可以找到相当多的这个特性的文档。 Also the Spring Data JPA documentation clearly documents this and well as its usage. Spring Data JPA 文档也清楚地记录了这一点及其用法。 Check here for more. 在这里查看更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM