关于jpa的Specification自定义函数,实现oracle的decode;以及如何在静态方法中调用注入的service
中秋佳节,多想吟诗一首:明月几时有,把酒问青天,不知天上宫。。。,行啦,不扯淡啦,中秋佳节也不能影响我学习的热情,说一说今天遇到问题
如何在静态方法中调用注入的service
Public class ClassA{
public static ClassA classA;
@Resource
private Service service;
//原理时在工程启动时加载,在静态方法前加载,这样就可以在静态方法中调用注入的方法啦 @PostConstruct public void init() { classA = this;
classA.service=service; }
}
关于jpa的Specification自定义函数
这个时自定义方法的源码,有注释,不多说啦
1 /** 2 * Create an expression for the execution of a database 3 * function. 4 * @param name function name 5 * @param type expected result type 6 * @param args function arguments 7 * @return expression 8 */ 9 <T> Expression<T> function(String name, Class<T> type, 10 Expression<?>... args);
咱说说这个类,也就是
ParameterizedFunctionExpression,是如何实现动态组合排序条件,实现decode
<T> Expression<T> function(String name, Class<T> type,
Expression<?>... args);
//这是function实现实际调用的方法;他调用的就是这个类ParameterizedFunctionExpression的构造方法
@Override
public <T> Expression<T> function(String name, Class<T> returnType, Expression<?>... arguments) {
return new ParameterizedFunctionExpression<T>( this, returnType, name, arguments );
}
//ParameterizedFunctionExpression的构造方法
public ParameterizedFunctionExpression(
CriteriaBuilderImpl criteriaBuilder,
Class<X> javaType,
String functionName,
Expression<?>... argumentExpressions) {
super( criteriaBuilder, javaType, functionName );
this.argumentExpressions = Arrays.asList( argumentExpressions );
this.isStandardJpaFunction = STANDARD_JPA_FUNCTION_NAMES.contains( functionName.toUpperCase(Locale.ROOT) );
}
//实现
Expression<Integer> expression = null;
//存储排序条件
List<Expression<?>> argumentExpressions = new ArrayList<Expression<?>>();
//排序字段
argumentExpressions.add(cb.literal("grade");
//排序的顺序
argumentExpressions.add(cb.literal(1));
expression = new ParameterizedFunctionExpression<Integer>((CriteriaBuilderImpl) cb, Integer.class, "decode",
argumentExpressions);
@SuppressWarnings("all") public Specification<CT> findByCondition(List<Filter> filter, List<Reorder> reOrders) { return new Specification<CT>() { @Override public Predicate toPredicate(Root<CT> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> predicates = new ArrayList<Predicate>(); List<Order> orders = new ArrayList<Order>(); if (!CollectionUtils.isEmpty(filter)) { filter.stream().forEach(filter -> { ParameterizedType pt = (ParameterizedType) this.getClass().getGenericInterfaces()[0]; Class<CT> clazz = (Class<CT>) pt.getActualTypeArguments()[0]; CT ct = null; try { ct = clazz.newInstance(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } String type = JudgeParamType.getObjectValue(ct, null, filter.getField()); if (type == null) { String str[] = filter.getField().split(","); type = JudgeParamType.getObjectValue(ct, null, str[1]); } Path<Object> queryPath = obtainParamPath(root, filter.getField()); switch (filter.getFilter()) { case "equal": { if ("Integer".equalsIgnoreCase(type)) { predicates.add(cb.equal(queryPath.as(Integer.class), SieStringUtils.getIntvalueByStr(filter.getParam().trim()))); break; } if ("Date".equalsIgnoreCase(type)) { predicates.add(cb.equal(queryPath.as(Date.class), SieStringUtils.getDatevalueByStr(filter.getParam().trim()))); break; } predicates.add(cb.equal(queryPath.as(String.class), filter.getParam().trim())); break; } case "like": { predicates.add(cb.like(cb.upper(queryPath.as(String.class)), "%" + filter.getParam().trim().toUpperCase() + "%")); break; } case "range": { List<String> str = Arrays.asList(filter.getParam().trim().split(",")); if ("Integer".equalsIgnoreCase(type)) { predicates.add(cb.greaterThanOrEqualTo(queryPath.as(Integer.class), SieStringUtils.getIntvalueByStr(str.get(0)))); predicates.add(cb.lessThanOrEqualTo(queryPath.as(Integer.class), SieStringUtils.getIntvalueByStr(str.get(1)))); break; } if ("Double".equalsIgnoreCase(type)) { predicates.add(cb.greaterThanOrEqualTo(queryPath.as(Double.class), SieStringUtils.getDoublevalueByStr(str.get(0)))); predicates.add(cb.lessThanOrEqualTo(queryPath.as(Double.class), SieStringUtils.getDoublevalueByStr(str.get(1)))); break; } if ("Date".equalsIgnoreCase(type)) { predicates.add(cb.greaterThanOrEqualTo(queryPath.as(Date.class), SieStringUtils.getDatevalueByStr(str.get(0)))); predicates.add(cb.lessThanOrEqualTo(queryPath.as(Date.class), SieStringUtils.getDatevalueByStr(str.get(1)))); break; } predicates.add(cb.greaterThanOrEqualTo(queryPath.as(String.class), str.get(0))); predicates.add(cb.lessThanOrEqualTo(queryPath.as(String.class), str.get(1))); break; } case "gt": { if ("Integer".equalsIgnoreCase(type)) { predicates.add(cb.greaterThanOrEqualTo(queryPath.as(Integer.class), SieStringUtils.getIntvalueByStr(filter.getParam().trim()))); break; } if ("Double".equalsIgnoreCase(type)) { predicates.add(cb.greaterThanOrEqualTo(queryPath.as(Double.class), SieStringUtils.getDoublevalueByStr(filter.getParam().trim()))); break; } if ("Date".equalsIgnoreCase(type)) { predicates.add(cb.greaterThanOrEqualTo(queryPath.as(Date.class), SieStringUtils.getDatevalueByStr(filter.getParam().trim()))); break; } predicates .add(cb.greaterThanOrEqualTo(queryPath.as(String.class), filter.getParam().trim())); break; } case "lt": { if ("Integer".equalsIgnoreCase(type)) { predicates.add(cb.lessThanOrEqualTo(queryPath.as(Integer.class), SieStringUtils.getIntvalueByStr(filter.getParam().trim()))); break; } if ("Double".equalsIgnoreCase(type)) { predicates.add(cb.lessThanOrEqualTo(queryPath.as(Double.class), SieStringUtils.getDoublevalueByStr(filter.getParam().trim()))); break; } if ("Date".equalsIgnoreCase(type)) { predicates.add(cb.lessThanOrEqualTo(queryPath.as(Date.class), SieStringUtils.getDatevalueByStr(filter.getParam().trim()))); break; } predicates.add(cb.lessThanOrEqualTo(queryPath.as(String.class), filter.getParam().trim())); break; } case "in": { List<String> inStr = Arrays.asList(filter.getParam().trim().split(",")); List<Predicate> predicatesOr = new ArrayList<Predicate>(); inStr.forEach(param -> { if ("null".equalsIgnoreCase(param)) { predicatesOr.add(cb.isNull(queryPath)); } else { predicatesOr.add(cb.equal(queryPath, param)); } }); Predicate[] predicateOr = predicatesOr.toArray(new Predicate[predicatesOr.size()]); predicates.add(cb.or(predicateOr)); break; } case "notnull": { predicates.add(cb.isNotNull(queryPath)); cb.literal("e"); } default: break; } }); } if (!CollectionUtils.isEmpty(reOrders)) { reOrders.stream().forEach(sort -> { Path<Object> sortPath = obtainParamPath(root, sort.getField()); orders.add(getDecodeOrders(root, cb, sort.getField(), sort.getDirection())); }); } Predicate predicate = cb.and(predicates.toArray(new Predicate[predicates.size()])); if (!CollectionUtils.isEmpty(orders)) { query.orderBy(orders); } return query.getRestriction(); } }; }
public static class Filter { @ApiModelProperty(required = true) private String filter;// where @ApiModelProperty(required = true) private String field; @ApiModelProperty(required = true) private String param; public String getFilter() { return filter; } public void setFilter(String filter) { this.filter = filter; } public String getField() { return field; } public void setField(String field) { this.field = field; } public String getParam() { return param; } public void setParam(String param) { this.param = param; } }
public static class Reorder { @ApiModelProperty(required = true) private String direction; @ApiModelProperty(required = true) private String field; public String getDirection() { return direction; } public void setDirection(String direction) { this.direction = direction; } public String getField() { return field; } public void setField(String field) { this.field = field; } }