从 Criteria 获取 WHERE 子句作为 HQL 字符串或:select 中具有动态列的动态 WHERE 子句
Get WHERE clause as HQL string from Criteria or: Dynamic WHERE clause with dynamic columns in select
我想为我的应用程序构建过滤器搜索。但是,有一些限制。我必须能够动态添加条件以及动态修改我想要获取的列和连接。
我尝试使用带有规范的 JPA 存储库(来自 Spring 数据),它根据需要构建 WHERE 子句,但是我无法控制哪些列以及将 Hibernate 问题连接到数据库的内容。
我也尝试过将 Hibernate Criteria API 与投影一起使用。发出的 Query 符合要求,我完全控制了选定的列和连接,以及 WHERE 子句,但是结果转换被证明对于解析嵌套对象来说太麻烦了(我尝试使用自定义结果转换器,但是无济于事,对于单层对象,默认行为很好。
我现在的 "solution" 正在根据情况构建 HQL 字符串。但是,我已经编写了用于构建 WHERE 子句的代码,我想知道是否有重用它的方法(例如,从 Spring 规范的谓词或从 Hibernate 限制中获取 HQL 字符串)。
当然,如果有更好的方法,请分享。
您需要使用 QueryDSL.
第 1 步: 将 com.mysema.querydsl:querydsl-apt
、com.mysema.querydsl:querydsl-core
和 com.mysema.querydsl:querydsl-jpa
依赖项添加到您的项目。
第 2 步:向实体 class 添加 @QueryEntity
注释,您希望对其进行 运行 动态查询。如果查询将包含嵌套 classes,请将注释添加到嵌套实体 classes 中。下面的例子:
@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
Maven插件在process
阶段如下:
<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 数据 JPA 存储库接口以扩展 QueryDslPredicateExecutor
。
interface UserRepository extends JpaRepository<User, Long>, QueryDslPredicateExecutor<User> {}
通过此设置,APT 插件将为每个用 QueryEntity
注释的 class 生成 Q
classes。然后,您可以使用这些 classes 生成动态查询。例如:
QUser user = QUser.user;
BooleanExpression query = and(eq(user.active, Boolean.TRUE), eq(user.address.country.name, "Belgium"));
Collection<User> activeUsersFromBelgium = userRepository.findAll(query);
我想为我的应用程序构建过滤器搜索。但是,有一些限制。我必须能够动态添加条件以及动态修改我想要获取的列和连接。
我尝试使用带有规范的 JPA 存储库(来自 Spring 数据),它根据需要构建 WHERE 子句,但是我无法控制哪些列以及将 Hibernate 问题连接到数据库的内容。
我也尝试过将 Hibernate Criteria API 与投影一起使用。发出的 Query 符合要求,我完全控制了选定的列和连接,以及 WHERE 子句,但是结果转换被证明对于解析嵌套对象来说太麻烦了(我尝试使用自定义结果转换器,但是无济于事,对于单层对象,默认行为很好。
我现在的 "solution" 正在根据情况构建 HQL 字符串。但是,我已经编写了用于构建 WHERE 子句的代码,我想知道是否有重用它的方法(例如,从 Spring 规范的谓词或从 Hibernate 限制中获取 HQL 字符串)。
当然,如果有更好的方法,请分享。
您需要使用 QueryDSL.
第 1 步: 将 com.mysema.querydsl:querydsl-apt
、com.mysema.querydsl:querydsl-core
和 com.mysema.querydsl:querydsl-jpa
依赖项添加到您的项目。
第 2 步:向实体 class 添加 @QueryEntity
注释,您希望对其进行 运行 动态查询。如果查询将包含嵌套 classes,请将注释添加到嵌套实体 classes 中。下面的例子:
@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
Maven插件在process
阶段如下:
<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 数据 JPA 存储库接口以扩展 QueryDslPredicateExecutor
。
interface UserRepository extends JpaRepository<User, Long>, QueryDslPredicateExecutor<User> {}
通过此设置,APT 插件将为每个用 QueryEntity
注释的 class 生成 Q
classes。然后,您可以使用这些 classes 生成动态查询。例如:
QUser user = QUser.user;
BooleanExpression query = and(eq(user.active, Boolean.TRUE), eq(user.address.country.name, "Belgium"));
Collection<User> activeUsersFromBelgium = userRepository.findAll(query);