【问题标题】:Get WHERE clause as HQL string from Criteria or: Dynamic WHERE clause with dynamic columns in select从 Criteria 获取 WHERE 子句作为 HQL 字符串或:动态 WHERE 子句在选择中具有动态列
【发布时间】:2015-06-15 10:13:13
【问题描述】:

我想为我的应用程序构建过滤器搜索。但是,有一些限制。我必须能够动态添加条件以及动态修改我想要获取的列和连接。

我尝试过使用 JPA 存储库(来自 Spring Data)和 Specifications,它根据需要构建 WHERE 子句,但是我无法控制哪些列以及哪些将 Hibernate 问题连接到数据库。

我也尝试过将 Hibernate Criteria API 与 Projections 结合使用。发出的查询符合预期,我可以完全控制选定的列和连接,以及 WHERE 子句,但是,结果转换被证明对于解析嵌套对象来说太麻烦了(我尝试使用自定义结果转换器,但是无济于事,对于单层对象,默认行为很好)。

我现在的“解决方案”是根据情况构建 HQL 字符串。但是,我已经编写了构建 WHERE 子句的代码,我想知道是否有办法重用它(例如,从 Spring 规范的谓词或从 Hibernate 限制中获取 HQL 字符串)。

当然,如果有更好的方法来做这一切,如果你能分享,我将不胜感激。

【问题讨论】:

    标签: java hibernate jpa spring-data criteria


    【解决方案1】:

    您需要使用QueryDSL

    第 1 步:com.mysema.querydsl:querydsl-aptcom.mysema.querydsl:querydsl-corecom.mysema.querydsl:querydsl-jpa 依赖项添加到您的项目中。

    第 2 步:将 @QueryEntity 注释添加到您希望在其上运行动态查询的实体类。如果查询将包含嵌套类,请将注释添加到嵌套实体类中。下面是一个例子:

    @Entity
    @QueryEntity
    @Table(name = "users")
    public class User {
      @OneToMany
      private Address address;
    }
    
    @Entity
    @QueryEntity
    @Table(name = "address")
    public class Address {
      @ManyToOne
      private Country country;
    }
    
    @Entity
    @QueryEntity
    @Table(name = "country")
    public class Country { }
    

    第 3 步:在process 阶段运行com.mysema.maven:apt-maven-plugin Maven 插件,如下所示:

    <build>
      <plugins>
        <plugin>
          <groupId>com.mysema.maven</groupId>
          <artifactId>apt-maven-plugin</artifactId>
          <version>1.1.1</version>
          <executions>
            <execution>
              <goals>
                <goal>process</goal>
              </goals>
              <configuration>
                <outputDirectory>target/generated-sources/java</outputDirectory>
                <processor>com.mysema.query.apt.QuerydslAnnotationProcessor</processor>
              </configuration>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>
    

    第 4 步:更改 Spring Data JPA 存储库接口以扩展 QueryDslPredicateExecutor

    interface UserRepository extends JpaRepository<User, Long>, QueryDslPredicateExecutor<User> {}
    

    通过此设置,APT 插件将为每个带有 QueryEntity 注释的类生成 Q 类。然后,您可以使用这些类生成动态查询。例如:

    QUser user = QUser.user;
    
    BooleanExpression query = and(eq(user.active, Boolean.TRUE), eq(user.address.country.name, "Belgium"));
    
    Collection<User> activeUsersFromBelgium = userRepository.findAll(query);
    

    【讨论】:

      猜你喜欢
      • 2021-06-15
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      • 2019-10-12
      • 2016-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多