我正在努力为Scala创建一个SQL DSL.DSL是Querydsl的扩展,Querydsl是一种流行的Java查询抽象层.
我现在正在努力解决以下非常简单的表达方式
user.firstName == "Bob" || user.firstName == "Ann"
Run Code Online (Sandbox Code Playgroud)
由于Querydsl已经支持可以在这里使用的表达式模型,因此我决定提供从Proxy对象到Querydsl表达式的转换.为了使用代理,我创建了一个这样的实例
import com.mysema.query.alias.Alias._
var user = alias(classOf[User])
Run Code Online (Sandbox Code Playgroud)
通过以下隐式转换,我可以将代理实例和代理属性调用链转换为Querydsl表达式
import com.mysema.query.alias.Alias._
import com.mysema.query.types.expr._
import com.mysema.query.types.path._
object Conversions {
def not(b: EBoolean): EBoolean = b.not()
implicit def booleanPath(b: Boolean): PBoolean = $(b);
implicit def stringPath(s: String): PString = $(s);
implicit def datePath(d: java.sql.Date): PDate[java.sql.Date] = $(d);
implicit def dateTimePath(d: java.util.Date): PDateTime[java.util.Date] = $(d);
implicit def timePath(t: java.sql.Time): PTime[java.sql.Time] = $(t);
implicit def comparablePath(c: Comparable[_]): PComparable[_] = $(c);
implicit …Run Code Online (Sandbox Code Playgroud) 编辑:事实证明JPA无法表达这一点.解决方案是在SQL中重写.
我正在使用QueryDSL对JPA数据集执行聚合查询以进行报告.我没有问题提取报告数据.例如:
...
query = query.groupBy(QVehicle.vehicle.make, QVehicle.vehicle.model);
return query.listDistinct(new QMakeModelReportData(
QVehicle.vehicle.make, QVehicle.vehicle.model,
QVehicle.vehicle.make.count()));
Run Code Online (Sandbox Code Playgroud)
这将生成我的DTO对象列表,每个对象都包含车辆制造,车辆模型以及制作模型的车辆数量.像这样:
Ford, Focus, 14
Ford, Mondeo, 4
Vauxhall, Astra, 4
Run Code Online (Sandbox Code Playgroud)
但在实际执行查询之前,我无法计算出计算行数的语法.我想象的语法是这样的,它不存在:
return query.countDistinct(QVehicle.vehicle.make, QVehicle.vehicle.model);
Run Code Online (Sandbox Code Playgroud)
我最终选择了一个相当低效的选项:
return query
.listDistinct(QVehicle.vehicle.make, QVehicle.vehicle.model)
.size();
Run Code Online (Sandbox Code Playgroud)
有更好的吗?
在其中一个项目中,我们使用的是Spring Data.现在查询变得越来越复杂,我们考虑添加Spring Data Specification或QueryDSL.
但是,不确定前进的最佳方式.我认为他们都有同样的目的.是否推荐任何一个?
谢谢
我正在使用spring数据jpa和querydsl并且被困在如何编写简单的好查询到左连接两个表.假设我有一个Project实体和一个在Project中定义了OneToMany关系的Task实体,我想做的事情如下:
select * from project p left join task t on p.id = t.project_id where p.id = searchTerm
select * from project p left join task t on p.id = t.project_id where t.taskname = searchTerm
Run Code Online (Sandbox Code Playgroud)
在JPQL,它应该是:
select distinct p from Project p left join p.tasks t where t.projectID = searthTerm
select distinct p from Project p left join p.tasks t where t.taskName = searthTerm
Run Code Online (Sandbox Code Playgroud)
我有一个ProjectRepository接口,它扩展了JpaRepository和QueryDslPredicateExecutor.这让我可以访问方法:
Page<T> findAll(com.mysema.query.types.Predicate predicate, Pageable pageable)
Run Code Online (Sandbox Code Playgroud)
我知道,左连接可以通过创建一个新的JPAQuery(EntityManager的)可以轻松实现.但我没有实体管理器与弹簧数据的JPA明确注入.有没有建立一个谓词左加入很好的和简单的方法?希望有人在这里经历了这一点,并能够给我一个例子.谢谢.
弗雷.
当我尝试运行这样的查询时:
QA A = QA.a;
QB B = QB.b;
...
from(A)
.leftJoin(B).with(B.name.eq(A.nameSomething));
Run Code Online (Sandbox Code Playgroud)
(A和B实体不相关)我总是收到此错误:
Caused by: org.hibernate.hql.ast.QuerySyntaxException: Path expected for join!
Run Code Online (Sandbox Code Playgroud)
我希望能够使用querydsl离开加入不相关的实体.有可能吗?或者唯一的方法是编写本机Oracle查询?
比方说,我有两个表Task和Company.Company有列id和name.Task有两列customerId,providerId并链接回id列Company.
使用Querydsl我如何在Company桌面上加入两次,这样我就可以获得name由customerIdand 指定的每个公司providerId?
代码可能更好地解释了我正在尝试的内容:
Configuration configuration = new Configuration(templates);
JPASQLQuery query = new JPASQLQuery(this.entityManager, configuration);
QTask task = QTask.task;
QCompany customer = QCompany.company;
QCompany provider = QCompany.company;
JPASQLQuery sql = query.from(task).join(customer).on(customer.id.eq(task.customerId))
.join(provider).on(provider.id.eq(task.providerId));
return sql.list(task.id, customer.name.as("customerName"), provider.name.as("providerName"));
Run Code Online (Sandbox Code Playgroud)
哪个生成SQL:
select task.id, company.name as customerName, company.name as providerName from task join company on company.id = …Run Code Online (Sandbox Code Playgroud) 如何使用窗口函数编写查询并选择QueryDSL中的所有字段?在文档中有一个这样的例子:
query.from(employee)
.list(SQLExpressions.rowNumber()
.over()
.partitionBy(employee.name)
.orderBy(employee.id));
Run Code Online (Sandbox Code Playgroud)
但我需要生成一个类似的查询:
SELECT * FROM
(SELECT employee.name, employee.id, row_number()
over(partition BY employee.name
ORDER BY employee.id)
FROM employee) AS sub
WHERE row_number = 1
Run Code Online (Sandbox Code Playgroud)
是否可以使用JPAQuery来实现?
我使用gradle 2.3和QueryDSL 4.1.3在IntelliJ 15中有一个Spring-boot 1.4项目,因为我的实体没有被Querydsl构建到Q类中.我有以下内容:
buildscript {
ext {
springBootVersion = '1.4.0.BUILD-SNAPSHOT'
querydslVersion = '4.1.3'
}
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
maven {url "https://plugins.gradle.org/m2/"}
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath "gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.7"
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'eclipse'
apply plugin: 'spring-boot'
apply plugin: 'jacoco'
apply plugin: 'groovy'
apply plugin: "com.ewerk.gradle.plugins.querydsl"
jar {
baseName = 'billing'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
jcenter() …Run Code Online (Sandbox Code Playgroud) 我有一个简单的实体,有一对多的关系
@Entity // and other @ stuff
public class Member {
@Id
private Long id;
private String name;
private List<Program> programs;
...
}
@Entity
public class Program {
@Id
private Long id;
private Long programName;
private ProgramType programType;
private Long programCost;
...
}
Run Code Online (Sandbox Code Playgroud)
现在使用QueryDSL,我想查询'所有注册程序的成员,程序类型="FULLTIME"和programCost> $ 1000'
我使用了以下谓词
Predicate predicate = QMember.member.programs.any()
.programType.eq(ProgramType.FULLTIME)
.and(QMember.member.programs.any().programCost.gt(1000));
Run Code Online (Sandbox Code Playgroud)
使用JPARepository
memberRepository.findAll(predicate);
Run Code Online (Sandbox Code Playgroud)
现在的问题是这两个查询是独立的.它返回al成员至少有一个类型为'FULLTIME'的程序或至少一个成本大于1000的程序.
期望的结果:如果他至少有一个类型为FULLTIME并且成本> 1000的程序,则返回成员.
当使用Lombok注释注释方法或变量时,maven插件将通过处理JPA的源代码来进行投诉.
我在控制台日志中遇到这种情况:
symbol: class __
location: class ServiceBaseMessage
C:\workspaces\[...]\service\ServiceBaseMessage.java:44: error: cannot find symbol
@Getter(onMethod = @__({ @JsonProperty("TYPE") }))
Run Code Online (Sandbox Code Playgroud)
如何使用JPA注释的apt-maven-plugin和queryDSL处理器与lombok注释一起工作?