我正在使用QueryDslPredicateExecutorSpring Data JPA项目,我正面临着渴望获取懒惰关系的需要.我知道我可以在Repository接口中使用本机JPA-QL查询,或者甚至使用来自Query DSL的JPAQLQuery,但如果可能的话,我很感兴趣,以便于构建查询以满足未来需求.
QueryDsl 3.3.4
Hibernate 3.6.10-Final我有两个实体:
public class Document {
private Confirmation confirmation;
}
public class Confirmation {
...
}
Run Code Online (Sandbox Code Playgroud)
我需要这样的查询:
SELECT count(d.id), CASE WHEN d.confirmation_id IS NULL then 'NOT_CONFIRMED' else 'CONFIRMED' END as confirmed FROM document d GROUP BY confirmed;
Run Code Online (Sandbox Code Playgroud)
所以它应该按照上面的case表达式的结果进行分组.
现在,将案例部分翻译为querydsl:
StringExpression confirmExp = new CaseBuilder()
.when(Expressions.booleanTemplate("confirmation_id is null"))
.then(Expressions.stringTemplate("NOT_CONFIRMED"))
.otherwise(Expressions.stringTemplate("CONFIRMED"));
Run Code Online (Sandbox Code Playgroud)
我正在使用.when(Expressions.booleanTemplate("confirmation_id is null"))以避免加入confirmation桌面.使用这样的表达式运行查询我在下面得到一个例外.
这是另一个hibernate错误或这种情况需要不同吗?
java.lang.IllegalStateException:没有节点的数据类型:> org.hibernate.hql.ast.tree.CaseNode + - [CASE] CaseNode:'case'| + - [WHEN] SqlNode:'when'| | + - [IS_NULL] IsNullLogicOperatorNode:'为null'| | | - [IDENT] IdentNode:'confirmation_id'{originalText = …
我有一个IncidenciaCHAR(1字节)列的表visiblemovil.此列有两个可能的值:"S"或"N"(是/否,西班牙语为si/no)我想要转换为boolean使用@Convert注释.这是我的代码:
转换器:
@Converter
public class SiNoToBooleanConverter implements AttributeConverter<Boolean, String> {
@Override
public String convertToDatabaseColumn(Boolean aBoolean) {
return aBoolean ? "S" : "N";
}
@Override
public Boolean convertToEntityAttribute(String s) {
return "S".equals(s);
}
}
Run Code Online (Sandbox Code Playgroud)
实体:
@FilterDef(name = "PREGINCIDENCIA_FILTRO_FECHA", parameters = @ParamDef(name = "ultimaFechaSinc", type = "date"))
@Entity
public class Incidencia {
private List<Incidenciapreguntas> preguntasList;
private Integer codincidencia;
private String descripcion;
private Double horasfinalizacion;
@Convert(converter = SiNoToBooleanConverter.class)
private Boolean visiblemovil;
private boolean tieneDocumentacion;
@Id …Run Code Online (Sandbox Code Playgroud) Mysema Querydsl使用的一些在线示例依赖于该JPAQuery#list()方法,例如,此stackoverflow答案包含GROUP BY/COUNT聚合示例.在官方文件中也提到了它.
但是,我没有在JPAQuery课堂上看到这种方法.它没有出现在IDE的自动完成中,并且它不存在于Maven下载的JAR文件中.
我已将这些依赖项添加到我的Maven项目中:
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>4.0.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>4.0.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
为什么这种JPAQuery#list()方法不存在?
如何QueryDsl在查询JPA中使用此功能
SUBSTRING_INDEX(str,delim,count)
Run Code Online (Sandbox Code Playgroud)
str在count出现分隔符之前从字符串返回子字符串delim.
更新1: 尝试@MaciejDobrowolski之后的解决方案:
QAcheteur ach = new QAcheteur("ach");
new JPAQuery(entityManager).from(ach)
.list( Expressions.stringTemplate("SUBSTRING_INDEX({0},',',1)", ach.ancestors) );
Run Code Online (Sandbox Code Playgroud)
我收到了这个错误:
java.lang.IllegalStateException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: '('
+-[METHOD_NAME] IdentNode: 'SUBSTRING_INDEX' {originalText=SUBSTRING_INDEX}
\-[EXPR_LIST] SqlNode: 'exprList'
+-[DOT] DotNode: 'acheteur1_.ancestors' {propertyName=ancestors,dereferenceType=PRIMITIVE,getPropertyPath=ancestors,path=ach.ancestors,tableAlias=acheteur1_,className=persistence.Acheteur,classAlias=ach}
| +-[ALIAS_REF] IdentNode: 'acheteur1_.ID_ACHETEUR' {alias=ach, className=persistence.Acheteur, tableAlias=acheteur1_}
| \-[IDENT] IdentNode: 'ancestors' {originalText=ancestors}
+-[QUOTED_STRING] LiteralNode: '',''
\-[NUM_INT] LiteralNode: '3'
Run Code Online (Sandbox Code Playgroud)
更新2 :(解决方案)
关注@DraganBozanovic的回答我创建我的自定义方言来获取No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode因为SUBSTRING_INDEX未知JPA因此我们使用自己的方言使其工作.
package dialect;
import …Run Code Online (Sandbox Code Playgroud) 在官方文档之后,@EnableSpringDataWebSupport在我的Spring配置中添加注释允许Predicate在查询中自动注入一个类:
@RequestMapping(method = RequestMethod.GET, path="/find")
public ResponseEntity<PagedResources<FooResource>> find(Pageable pageable, PagedResourcesAssembler<Foo> assembler, @QuerydslPredicate(root = Foo.class) Predicate predicate) {
Page<Foo> foos = fooRepository.findAll(predicate, pageable)
final ResourceAssemblerSupport<Foo, FooResource> fooResourceAssembler = new ....;
final PagedResources<FooResource> pagedResources = assembler.toResource(foos, fooResourceAssembler);
return new ResponseEntity<>(pagedResources, HttpStatus.OK);
}
Run Code Online (Sandbox Code Playgroud)
然后我可以在执行GET请求时轻松搜索:
GET /foo/name?=bob&name=alice&age=20
Run Code Online (Sandbox Code Playgroud)
这很好用.但是我想知道如何实现更高级的搜索条件:
><>=<=通常,我想将这些运算符应用于数据模型中的数字和日期字段.Querydsl支持这些标准.
我尝试添加> (%3E)我的查询参数,但它无法解析(例如,对于数字字段,如年龄,它抱怨它不能解析>10为数字.
是否可以在查询中直接使用此运算符?
(如果重要的话我正在使用Spring Data Mongodb)
在将项目升级到spring boot 1.5.9(spring 4.3和tomcat 8.5.24)之后,使用queryDSL的服务在运行时失败,因为它无法从jdk lib(tools.jar)中找到类.
/Q_742623943_01321512155_128635432.java:1: warning: Can't initialize javac processor due to (most likely) a class loader problem: java.lang.NoClassDefFoundError: com/sun/tools/javac/processing/JavacProcessingEnvironment
public class Q_742623943_01321512155_128635432 {
^
at lombok.javac.apt.LombokProcessor.init(LombokProcessor.java:83)
at lombok.core.AnnotationProcessor$JavacDescriptor.want(AnnotationProcessor.java:87)
at lombok.core.AnnotationProcessor.init(AnnotationProcessor.java:140)
at lombok.launch.AnnotationProcessorHider$AnnotationProcessor.init(AnnotationProcessor.java:69)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$ProcessorState.<init>(JavacProcessingEnvironment.java:500)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors$ProcessorStateIterator.next(JavacProcessingEnvironment.java:597)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:690)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
at com.mysema.codegen.JDKEvaluatorFactory.compile(JDKEvaluatorFactory.java:90)
at com.mysema.codegen.AbstractEvaluatorFactory.createEvaluator(AbstractEvaluatorFactory.java:76)
at com.mysema.codegen.AbstractEvaluatorFactory.createEvaluator(AbstractEvaluatorFactory.java:45)
at com.mysema.query.collections.DefaultEvaluatorFactory.create(DefaultEvaluatorFactory.java:120)
at com.mysema.query.collections.DefaultQueryEngine.project(DefaultQueryEngine.java:218)
at com.mysema.query.collections.DefaultQueryEngine.evaluateSingleSource(DefaultQueryEngine.java:190)
at com.mysema.query.collections.DefaultQueryEngine.list(DefaultQueryEngine.java:82)
at com.mysema.query.collections.AbstractColQuery.list(AbstractColQuery.java:149)
Run Code Online (Sandbox Code Playgroud)
当我将tools.jar作为gradle依赖项添加时,它可以工作,但这不是一个解决方案,因为jdk库不应该打包在项目中.
compile files(org.gradle.internal.jvm.Jvm.current().toolsJar)
Run Code Online (Sandbox Code Playgroud)
我们使用的是旧版本的queryDSL(2.7.3),项目将生成的代码提交给repo(这是一个旧项目,我宁愿在编译时生成).
更新: 降级到tomcat后回到v7.0.*它再次开始工作.
知道tomcat …
我一直在阅读文档并试图实现通过多个字段和列过滤结果的解决方案,但是我不断收到错误;格式错误的查询。
我想用完全相等的值过滤结果,例如:
is_active: true
category_id: [1,2,3,4]
brand: "addidas"
gender: "male"
Run Code Online (Sandbox Code Playgroud)
为了更清楚地说明我打算做什么,如果它用 SQL 编写,这就是我希望它运行的方式:
SELECT .... WHERE
is_active= 1 AND category_id IN(1,2,3,4)
AND brand='addidas' AND gender='male'
Run Code Online (Sandbox Code Playgroud)
我在 DSL 中的查询如下:
{
"body": {
"query": {
"nested": {
"query": {
"bool": {
"must": {
"terms": {
"category_id": [
1,
2,
3
]
},
"term": {
"is_active": true
},
"term": {
"brand": "addidas"
}
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何在 elasticsearch 中按照所述过滤多个字段和值?
如果您需要我提供回答问题所需的额外信息,请发表评论。如果您添加指向文档的链接,还请提供一个示例(带有查询 dsl),说明应如何解决我的当前或类似情况。
一年多以来,我们已经提交了QueryDSL。 https://github.com/querydsl/querydsl 我们应该认为这个项目已经死了还是正在搬到一个新的小组?我想老团队已经没有维护它的计划了。新的JDK每6个月到货,我想这个项目将比我们预期的要早过时。有什么新闻或兼容的替代品吗?
我正在尝试从 spring boot gradle 项目创建对 mongo 数据库的动态查询。我的gradle版本:5.6.1
这是我的 build.gradle 文件:
plugins {
id 'org.springframework.boot' version '2.2.2.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'com.onssoftware'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
// https://mvnrepository.com/artifact/com.querydsl/querydsl-mongodb
compile group: 'com.querydsl', name: 'querydsl-mongodb', version: '4.2.2'
// https://mvnrepository.com/artifact/com.querydsl/querydsl-apt
compile group: 'com.querydsl', name: 'querydsl-apt', version: '4.2.2'
//annotationProcessor group: 'com.querydsl', name: 'querydsl-apt', version: '4.2.2'
annotationProcessor "com.querydsl:querydsl-apt:4.2.2"
//annotationProcessor("org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor")
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test …Run Code Online (Sandbox Code Playgroud)