Die*_*nso 7 java generics types class
虽然我的问题是关于Java泛型,但我已经提出了一些与JPA相关的代码来向您展示真实的上下文.
我正在使用JPA 2.0和基于Criteria API的查询.我的所有查询都遵循相同的模式(比较简单的属性;不需要路径导航),所以我试图编写一个泛型类来处理JPA,同时将业务逻辑保持在分离的类中.我的目标是有一个方法,给定一个实体类型和一个存储定义条件的对(字段名称 - >期望值)的Map,返回一个bean(或bean的集合),其中包含一些实体字段的值.
我的所有实体都实现了Persistible接口,而我的所有传输对象都继承自QueryBean.我认为这些类与问题无关,所以我正在跳过他们的代码.
以下代码是我的第一个方法的片段(请假设cb是有效的CriteriaBuilder实例):
protected <T extends QueryBean, TT extends Persistible> Collection<T> executeQueryEntity
(Class<T> type, Class<TT> rootType, QueryConfig queryConfig, Map<String, Object> parameters) {
// (...) Initialization goes here
CriteriaQuery<T> c = cb.createQuery(type);
// FROM CLAUSE
Root<TT> root = c.from(rootType);
// SELECT CLAUSE
List<String> constructorParams = queryConfig.getTargetAttributes();
Selection<?>[] selectArray = new Selection<?>[constructorParams.size()];
for (int i = 0; i < constructorParams.size(); i++) {
selectArray[i] = root.get(constructorParams.get(i));
}
c.select(cb.construct(type, selectArray));
// WHERE CLAUSE
for (String filter : parameters.keySet()) {
if (queryConfig.getFieldConfiguration().get(filter).compareUsingEquals()) {
// SOME PREDICATE
}
else {
// SOME OTHER PREDICATE
}
}
// (...) Rest of the code goes here
}
Run Code Online (Sandbox Code Playgroud)
我的QueryConfig界面如下:
public interface QueryConfig {
List<String> getTargetAttributes();
Map<String, FieldConfiguration> getFieldConfiguration();
}
Run Code Online (Sandbox Code Playgroud)
由于我已经使用了一个QueryConfig提供有关查询信息的类(例如QueryBean构造函数所需的参数或有关实体字段的信息),我认为从该类获取实体类型而不是将其作为一个Class参数.我从这个问题推断它不能直接完成,所以我尝试了以下解决方法:
像QueryConfig一样添加方法:
Class< ? extends Persistible> getTargetEntity();
Run Code Online (Sandbox Code Playgroud)
添加这样的中间方法:
public <T extends QueryBean> Collection<T> queryMany(Class<T> type, QueryConfig config, Map<String, Object> parameters) {
executeQueryEntity(type, config.getTargetEntity(), parameters);
}
Run Code Online (Sandbox Code Playgroud)
但它不会编译.我相信原因在这里解释:Class Generics的类型不匹配但我实际上不理解答案.我的问题是:有没有办法避免将Class< TT >参数传递给execute方法?这是处理问题的好方法还是我应该重构整个问题?对代码的任何改进也是受欢迎的!
我不太明白您认为您的方法可行的原因:
QueryConfig没有Class< ? extends Persistible> getTargetEntity();给出编译器可以引用的类型信息,以及为什么您认为编译器可以“猜测”您要返回的类型,并执行以下操作为你进行类型检查?
您可以做的一种方法是在 QueryConfig 中提供类型信息
public interface QueryConfig <T extends Persistable> {
Class<T> getTargetEntity();
List<String> getTargetAttributes();
Map<String, FieldConfiguration> getFieldConfiguration();
}
Run Code Online (Sandbox Code Playgroud)
你的 queryMany 方法可以是这样的:
public <T extends QueryBean, TT extends Persistible>
Collection<T> queryMany(Class<T> type,
QueryConfig<TT> config,
Map<String, Object> parameters) {
executeQueryEntity(type, config.getTargetEntity(), parameters);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2298 次 |
| 最近记录: |