JPA生成全属性条件查询通用Specification 素颜马尾好姑娘i 2022-11-08 11:49 255阅读 0赞 ## 1、使用Specification+JPA不作封装的时候每次都要挨个判断属性,很是麻烦 ## **以下对生成Specification做一个封装** /** * 生成全属性条件查询通用Specification * * @param tableMap 属性参数 * @param clazz 要查询的实体类或vo类 * @param excludeAttr 不使用模糊搜索的字符串属性 * @param map 外键关联查询 * @param <S> * @return */ public <S> Specification<S> createSpecification(Map<String, String> tableMap, Class clazz, List<String> excludeAttr, Map map) { Specification<S> specification = (root, query, cb) -> { List<Predicate> predicates = new ArrayList<>(); //未删除的数据 try { clazz.getDeclaredField(Constants.VALID); if (!StringUtils.isEmpty(tableMap.get(Constants.VALID))) { predicates.add(cb.equal(root.get(Constants.VALID), Integer.valueOf(tableMap.get(Constants.VALID)))); } else { predicates.add(cb.equal(root.get(Constants.VALID), 1)); } } catch (NoSuchFieldException e) { logger.warn("没有找到 {valid} 属性"); } Field[] declaredFields = clazz.getDeclaredFields(); if (tableMap != null) { for (Field field : declaredFields) { String fieldName = field.getName(); if (!StringUtils.isEmpty(tableMap.get(fieldName))) { String typeName = field.getGenericType().getTypeName(); Class<?> aClass = null; try { aClass = Class.forName(typeName); } catch (ClassNotFoundException e) { e.printStackTrace(); } //属性不包含特定的属性并且是字符串采用模糊搜索 if (aClass == String.class && (CollectionUtils.isEmpty(excludeAttr) || !excludeAttr.contains(fieldName))) { String queryFieldName = "%" + tableMap.get(fieldName).replace("/", "\\/") .replaceAll("_", "\\\\_").replaceAll("%", "\\\\%") + "%"; predicates.add(cb.like(root.get(fieldName), queryFieldName)); } else { predicates.add(cb.equal(root.get(fieldName), tableMap.get(fieldName))); } } } if (!CollectionUtils.isEmpty(map)) { Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { String sourceKey = iterator.next().toString(); Map mapping = (Map) map.get(sourceKey); Join join = root.join(sourceKey, JoinType.INNER); Iterator mappingItr = mapping.keySet().iterator(); while (mappingItr.hasNext()) { String joinKey = mappingItr.next().toString(); String joinAttr = mapping.get(joinKey).toString(); if (!StringUtils.isEmpty(tableMap.get(joinKey))) { predicates.add(cb.equal(join.get(joinAttr), tableMap.get(joinKey))); } } } } } Predicate[] pre = new Predicate[predicates.size()]; Predicate preAnd = cb.and(predicates.toArray(pre)); return query.where(preAnd).getRestriction(); }; return specification; } ## 2、使用方式 ## Map<String, Map<String, String>> joinAttr = new HashMap(4); //mapping为请求参数与实体属性名之间的映射关系 Map mapping = new HashMap(4); mapping.put("tankAreaId", "id"); mapping.put("tankAreaCode", "tankAreaCode"); //joinAttr为当前实体关联字段名称 joinAttr.put("tankArea", mapping); Specification<TankMovementEntity> specification = reflectUtil.createSpecification(tableMap, TankMovementVo.class, null, createJoinField()); ## 3、很方便,不需要再一个一个去判断 ## ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5ODk4MTkx_size_16_color_FFFFFF_t_70] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5ODk4MTkx_size_16_color_FFFFFF_t_70]: /images/20221023/a112a74d6bfd4b3caef5bb834b6555cc.png
还没有评论,来说两句吧...