我打算通过querydsl生成SQL查询以进行动态字符串构建。我当前未使用spring数据jpa,我生成了一个Q表,但是我不想通过实例化Q对象来构建字符串,我的要求是通过采用表名/ q bean来动态构建查询。用户在运行时选择的Q bean属性中定义的变量名称。
Oracle表架构:
Create table VW_OUT.AWARDS_VW
(
GIVER_LAST_NAME varchar2(50),
GIVER_FIRST_NAME varchar2(50)
);
Maven部门
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-sql</artifactId>
<version>4.1.3</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-sql-spring</artifactId>
<version>4.1.3</version>
</dependency>
给出Spring Query DSL配置
@Configuration
public class QueryDSLConfig {
@Autowired
public DataSource dataSource;
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public com.querydsl.sql.Configuration querydslConfiguration() {
SQLTemplates templates = OracleTemplates.builder()
.printSchema()
.quote()
.build();
com.querydsl.sql.Configuration configuration = new com.querydsl.sql.Configuration(templates);
configuration.setUseLiterals(true);
configuration.setExceptionTranslator(new SpringExceptionTranslator());
return configuration;
}
@Bean
public SQLQueryFactory queryFactory() {
Provider<Connection> provider = new SpringConnectionProvider(dataSource);
return new SQLQueryFactory(querydslConfiguration(), provider);
}
}
和Q类型之一:
@Generated("com.querydsl.sql.codegen.MetaDataSerializer")
public class QAwardsVw extends com.querydsl.sql.RelationalPathBase<QAwardsVw> {
private static final long serialVersionUID = 519295604;
public static final QAwardsVw awardsVw = new QAwardsVw("AWARDS_VW");
public final StringPath giverFirstName = createString("giverFirstName");
public final StringPath giverLastName = createString("giverLastName");
public QAwardsVw(String variable) {
super(QAwardsVw.class, forVariable(variable), "VW_OUT", "AWARDS_VW");
addMetadata();
}
public QAwardsVw(String variable, String schema, String table) {
super(QAwardsVw.class, forVariable(variable), schema, table);
addMetadata();
}
public QAwardsVw(Path<? extends QAwardsVw> path) {
super(path.getType(), path.getMetadata(), "VW_OUT", "AWARDS_VW");
addMetadata();
}
public QAwardsVw(PathMetadata metadata) {
super(QAwardsVw.class, metadata, "VW_OUT", "AWARDS_VW");
addMetadata();
}
addMetadata(giverFirstName, ColumnMetadata.named("GIVER_FIRST_NAME").withIndex(8).ofType(Types.VARCHAR).withSize(50));
addMetadata(giverLastName, ColumnMetadata.named("GIVER_LAST_NAME").withIndex(7).ofType(Types.VARCHAR).withSize(50));
}
}
我的测试,尝试以通用方式而不是直接从Q bean构建from路径
@RunWith(SpringRunner.class)
@SpringBootTest
public class QuerydslApplicationTests {
@Autowired
SQLQueryFactory queryFactory;
@Test
public void contextLoads() {
PathBuilder<Object> fromPath = new PathBuilder<Object>(Object.class, "AWARDS_VW");
StringPath lnamePath = Expressions.stringPath(fromPath, "giverLastName");
StringPath fnamePath = Expressions.stringPath(fromPath, "giverFirstName");
String s = queryFactory.select(fnamePath ).from(fromPath).where(lnamePath .eq("MC")).getSQL().getSQL();
System.out.println(s);
}
}
这让我明白了,列名不是数据库列名,似乎是bean属性变量名,并且架构名称也没有打印为VW_OUT.Awards_Vw
select Awards_Vw.giverFirstName
from Awards_Vw
where Awards_Vw.giverLastName= 'MC'
我想要的是
select AWARDS_VW.giver_First_Name
from AWARDS_VW
where AWARDS_VW.giver_Last_Name= 'MC'
但是,如果我直接使用Q bean,它将满足我想要的结果,但是我不想像这样通过实例化Q bean构建路径
QWsPersonAwardsVw p = new QWsPersonAwardsVw("p");
String s = queryFactory.select(p.giverFirstName).from(p).where(p.giverLastName.eq("MC")).getSQL().getSQL();
产量:
select "p"."GIVER_FIRST_NAME"
from "ODS_OUT"."AWARDS_VW" "p"
where "p"."GIVER_LAST_NAME" = 'MC'
任何人都有见解或如何正确获取元数据?还是使用spring jpa使这更容易?我们的目标是在运行时生成字符串,以便事先不知道用户提供的表名/ Q变量名。
谢谢。