从Criteria获取WHERE子句作为HQL字符串,或者在select中使用动态列获取动态WHERE子句

时间:2015-06-15 10:13:13

标签: java hibernate jpa spring-data criteria

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

我尝试使用带有规范的JPA存储库(来自Spring Data),并根据需要构建WHERE子句,但是我无法控制哪些列以及什么将Hibernate问题加入到数据库中。

我也尝试过使用Hibernate Criteria API和Projections。发出的Query是理想的,我可以完全控制所选的列和连接,以及WHERE子句,但是,结果转换证明对于解析嵌套对象来说太麻烦了(我尝试使用自定义结果转换器,但是没有用,对于单级对象,默认行为很好。)

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

当然,如果有更好的方法可以做到这一点,如果你分享,我会很感激。

1 个答案:

答案 0 :(得分: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步:在com.mysema.maven:apt-maven-plugin阶段运行process 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插件将为每个使用Q注释的类生成QueryEntity个类。然后,您可以使用这些类生成动态查询。例如:

QUser user = QUser.user;

BooleanExpression query = and(eq(user.active, Boolean.TRUE), eq(user.address.country.name, "Belgium"));

Collection<User> activeUsersFromBelgium = userRepository.findAll(query);