Spring Data JPA 中使用 @Query 进行动态查询?

2024-04-27

我在 Spring Boot 应用程序中使用规范,可以通过不同的过滤器选项过滤结果。但是,我需要使用特殊的过滤器@Query在我的存储库方法中,据我所知,我无法在此查询中构建动态 WHERE 子句。

还有 QueryDSL 和 CriteriaAPI 选项,但我找不到使用它们的示例@Query.

那么,是否可以动态构建 WHERE 子句或为查询创建过滤器@Query?这是我的方法:

// there are more filters that omitted for brevity 

@Query("SELECT r FROM Recipe r WHERE r.title LIKE %:text%")
Page<Recipe> findByFields(@Param("text") String text);

我尝试在此方法中使用我的规范,但不可能将它们与@Query :((



Update:


@Entity
public class Recipe {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    @Enumerated(value = EnumType.STRING)
    private HealthLabel healthLabel;

    // code omitted for brevity

    @OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<RecipeIngredient> recipeIngredients = new ArrayList<>();
}

@Entity
public class RecipeIngredient {

    @EmbeddedId
    private RecipeIngredientId recipeIngredientId = new RecipeIngredientId();

    @Column(nullable = false)
    private BigDecimal amount;

    @ManyToOne(optional = true, fetch = FetchType.LAZY)
    @MapsId("recipeId")
    @JoinColumn(name = "recipe_id", referencedColumnName = "id")
    private Recipe recipe;

    @ManyToOne(optional = true, fetch = FetchType.LAZY)
    @MapsId("ingredientId")
    @JoinColumn(name = "ingredient_id", referencedColumnName = "id")
    private Ingredient ingredient;
}

@Entity
public class Ingredient {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true, nullable = false, length = 50)
    private String name;

    @OneToMany(mappedBy = "ingredient", cascade = CascadeType.ALL)
    private Set<RecipeIngredient> recipeIngredients = new HashSet<>();
}

这也是我无法过滤的枚举:

@Getter
@AllArgsConstructor
public enum HealthLabel {

    DEFAULT("Default"),
    EGG_FREE("Egg-free"),
    VEGETARIAN("Vegetarian"),
    WHEAT_FREE("Wheat-free");

    private String label;
}

没有什么可以阻止您使用Specification(这基本上是CriteriaAPI 但更易于使用)。您基本上需要以下 JPQL 的动态版本。

SELECT r FROM Recipe r 
JOIN r.recipeIngredients ri 
JOIN ri.ingredient i
WHERE i.name LIKE :name

现在,如果您可以用 JPQL 编写它,您也可以使用CriteriaAPI来写它(一般来说)。

public static Specification<Recipe> findByIngredientName(String name) {
  return (root, query, criteriaBuilder) -> {
     Join<Recipe, RecipeIngredient> ingredients = root.join("ingredients");
     Join< RecipeIngredient, Ingredient> ingredient = ingredients.join("ingredient");      
     return criteriaBuilder.like(ingredient.get("name"), "%" + name + "%"); 
  };
}

这是检索的规范Recipe含有一个Ingredient with a name like某物。您需要 2 个联接,无需查询,只需一个联接。

您现在甚至可以使用组合多个谓词Predicate.and。所以如果你创建另一个Predicate为了Recipe.name您可以将它们链接在一起,JPA 将处理其余的事情。

public static Specification<Recipe> findName(String name) {
  return (root, query, criteriaBuilder) -> { 
     return criteriaBuilder.like(root.get("title"), "%" + name + "%"); 
  };
}
Specification<Recipe> specs = findByName("recipe").and(findByIngredientName("ingredient"));
recipeRepository.findAll(specs);

这就是你所需要的。您接收哪些参数以及如何接收这些参数取决于您构建请求/响应对象的方式,并且是非常主观的。如果您想要排序顺序,请使用findAll这需要一个Specification and a Sort

Specification<Recipe> specs = findByName("recipe").and(findByIngredientName("ingredient"));
recipeRepository.findAll(specs, Sort.by("title"));

上面将生成一个SQL形式

SELECT recipesapp0_.id as id1_1_, recipesapp0_.title as title2_1_ FROM recipes_application$recipe recipesapp0_ 
INNER JOIN recipes_application$recipe_ingredient recipeingr1_ ON recipesapp0_.id=recipeingr1_.recipe_id 
INNER JOIN recipes_application$ingredient recipesapp2_ ON recipeingr1_.ingredient_id=recipesapp2_.id 
WHERE (recipesapp0_.title like ?) AND (recipesapp2_.name like ?) ORDER BYrecipesapp0_.title ASC

NOTE:下次当有人要求澄清您的用例时,请明确说明,而不是对他们不友好!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Data JPA 中使用 @Query 进行动态查询? 的相关文章

随机推荐

  • 如何在matlab中显示图像上的点?

    我有一些像素点 比如 p1 1 1 和 p2 1 10 等等 我想以任何颜色在图像上显示这些点 这个怎么做 MATLAB plot http www mathworks com help techdoc ref plot html文档非常全
  • emacs24 语义补全

    我正在尝试使用 emacs 24 及其附带的 cedet 版本来完成语义 补全适用于我在自己的源文件中定义的类 但补全不适用于标准库或 STL 内容这是我的 emacs 配置 require cedet require semantic r
  • NodeJS 如何在没有 WebSocket 的情况下处理持久连接?

    我对 NodeJS 真的很陌生 如果我对某些东西听起来很天真 我很抱歉 并且我一直在深入研究示例的源代码聊天应用 http github com ry node chat 但是 我无法理解一件事 我知道 WebSockets 有助于处理持久
  • 如何在 Visual Studio Code 中查找并替换所有出现的位置(在所有文件中)?

    我不知道如何使用 Visual Studio Code 1 0 版查找和替换不同文件中出现的所有单词 我的印象是这应该是可能的 因为执行 Ctrl Shift F 可以让我简单地搜索文件夹 但我不知道如何从这里继续 我查看了各种组合键htt
  • public open fun navigateUp() 的参数太多

    我在 Kotlin 中创建了一个新的 Android 项目 我还使用向导创建了一个新的导航抽屉活动 一如既往 没有任何东西是开箱即用的 以下行显示编译错误 val navController findNavController R id n
  • 如何在注册和结账过程中更改magento中的“送货信息”标签

    我想将 帐单信息 标签文本更改为 运输和帐单信息 我尝试使用 Mage Checkout csv 但这没有帮助 请提出解决方案 谢谢你 Use the 翻译文件translate csv在你的主题中 出于演示目的 我将使用默认包 app d
  • asp.net mvc 在哪里设置默认文化?

    用于多语言 asp net mvc 网站 我应该在哪里将线程的文化设置为默认语言 对于我的情况是 tr TR 此外 如果它不存在 我需要将其保存在 cookie 中 在 Application Start 中还是其他 我有多个站点 域 因此
  • 在 Linux 上的 makefile 和 Makefile 之间进行选择

    我想在一个目录中同时使用 Makefile 和 makefile 进行 make 默认情况下 它将执行makefile 我可以选择执行 Makefile 吗 提前致谢 最简单的选择是使用 f make f Makefile From man
  • 如何在 github 提交中设置用户名别名?

    我刚刚在大学读完一个学期 决定将我的所有项目从 bitbucket 我的课程所需 导入到 github 我所有其他项目都在其中 我成功导入了它们 不幸的是 当我从事这些项目时 我在三台不同的计算机之间切换 因此 提交历史记录中有许多我自己所
  • 在 Cygwin 中启用 Postgresql

    我安装了Cygwin与 Perl 和Postgresql已启用软件包 然后输入 usr bin cygserver config This will install the service 然后输入 net start cygserver
  • set()是如何实现的?

    我见过有人这么说setpython 中的对象具有 O 1 成员资格检查 他们如何在内部实施以实现这一点 它使用什么类型的数据结构 该实施还有哪些其他影响 这里的每个答案都非常有启发性 但我只能接受一个 所以我将选择最接近我原来问题的答案 谢
  • 您能否推荐一个 JQuery 插件来组成一组可映射到 SQL 查询的条件? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我发现了http redquerybuilder appspot com http redquerybu
  • 在内存无法容纳的大文件中查找“n”个最重复的单词/字符串

    我想验证我的伪代码 建议优化和更好的方法 最重复的单词 按排名 此处的排名定义了您要选择的排名 即前 X 个最重复的单词 外部按字母顺序对所有文件进行排序 下列的这里提到的算法 http www tcs fudan edu cn rudol
  • Javascript 已禁用,简短的问题

    只是一些关于 javascript 和网站的简短问题 1 通过启用 javascript 是否意味着在浏览器设置中安装并启用了 sun java 或者每个浏览器都始终启用 JavaScript 吗 2 如果禁用 javascript 我的网
  • PL/SQL 中的 BEGIN - END 块原子事务

    这些信息应该很容易找到 但我没有任何运气 当我有一个BEGIN ENDPL SQL 中的块 它是否表现为原子事务 它将尝试在命中时提交END阻止 如果出现问题会回滚更改吗 如果不是 我如何确保 BEGIN END 块内的代码的行为类似于原子
  • 删除记录时出现SystemStackError(堆栈级别太深)

    删除记录时出现 Stack Overflow 错误 SystemStackError 堆栈级别太深 应用程序 控制器 orders controller rb 18 在 销毁 中 我发现了另一个与 ruby 相关的系统堆栈错误 但我没有完全
  • .NET中的文档管理系统[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有谁知道可以与 NET集成的文档管理系统 或模块 Thanks 以下是当今企业中一些最常见的 DMS
  • CentOs Php 和 MySql 配置

    我已经安装了 php 并运行了一段时间 但我开始从事一个连接到数据库 即 mysql 的项目 所以我安装了 mysql 5 1 73 现在当我使用它连接到数据库时线 dbhandle mysql connect hostname usern
  • 作用域类型变量需要显式 foralls。为什么?

    如果你想使用 GHC词法作用域类型变量 http www haskell org ghc docs 7 6 2 html users guide other type extensions html scoped type variable
  • Spring Data JPA 中使用 @Query 进行动态查询?

    我在 Spring Boot 应用程序中使用规范 可以通过不同的过滤器选项过滤结果 但是 我需要使用特殊的过滤器 Query在我的存储库方法中 据我所知 我无法在此查询中构建动态 WHERE 子句 还有 QueryDSL 和 Criteri