未验证 提交 18ed58c5 编写于 作者: E elunez 提交者: GitHub

Merge pull request #88 from d15801543974/master

修改分页实现方式
package me.zhengjie.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @描述 : 为生成{@link javax.persistence.criteria.Predicate }提供的注解
* @作者 : Dong ZhaoYang
* @日期 : 2017/08/07
* @时间 : 16:25
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PredicateInfo {
/** Dong ZhaoYang 2017/8/7 基本对象的属性名 */
String propName() default "";
/** Dong ZhaoYang 2017/8/7 查询方式 */
QueryType queryType() default QueryType.BASIC;
enum QueryType {
/** Dong ZhaoYang 2017/8/7 基本 */
BASIC
/** Dong ZhaoYang 2017/8/7 大于等于 */
, GREATER_THAN
/** Dong ZhaoYang 2017/8/7 小于等于 */
, LESS_THAN
/** Dong ZhaoYang 2017/8/7 中模糊查询 */
, INNER_LIKE
/** Dong ZhaoYang 2017/8/7 左模糊查询 */
, LEFT_LIKE
/** Dong ZhaoYang 2017/8/7 右模糊查询 */
, RIGHT_LIKE
/** Dong ZhaoYang 2017/8/7 小于 */
, LESS_THAN_NQ
}
}
package me.zhengjie.utils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import me.zhengjie.aop.limit.PredicateInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
/**
* @描述 : JavaBean 帮助
* @作者 : Dong ZhaoYang
* @日期 : 2016/12/01
* @时间 : 09:54
*/
@SuppressWarnings("unused")
public class BeanHelp {
private final static ObjectMapper objectMapper = new ObjectMapper();
private static final Logger logger = LoggerFactory.getLogger(BeanHelp.class);
static {
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
/**
* @param <C> 泛型
* @param object 对象
* @return 属性集合
* @描述 : 获取对象的JSON属性Map对象集合
* @作者 : Dong ZhaoYang
* @日期 : 2017/02/24
* @时间 : 11:12
*/
@SuppressWarnings("unchecked")
public static <C> Map<String, C> getBeanJSONPropertyMap(Object object, Class<C> clazz) {
Map<String, C> result = new LinkedHashMap<>();
try {
JavaType javaType = objectMapper.getTypeFactory()
.constructParametrizedType(Map.class, Map.class, String.class, clazz);
result = objectMapper.readValue(objectMapper.writeValueAsString(object), javaType);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return result;
}
/**
* @param <C> 泛型
* @param propName 属性名
* @param object 对象
* @param clazz 返回类型
* @return 对象的属性名
* @描述 : 获取请求对象的JSON属性的Map集合
* @作者 : Dong ZhaoYang
* @日期 : 2017/03/20
* @时间 : 12:47
*/
@SuppressWarnings("unchecked")
private static <C> Map<String, C> getBeanJSONPropertyMap(String propName, Object object, Class<C> clazz) {
Map<String, C> result = new LinkedHashMap<>();
try {
Class<?> oClass = object.getClass();
Field[] fields = oClass.getDeclaredFields();
fieldLoop:
for (Field field : fields) {
String name = field.getName();
JsonIgnore ignore = oClass.getDeclaredField(name).getAnnotation(JsonIgnore.class);
if (ignore != null) {
continue;
}
JsonProperty property = oClass.getDeclaredField(name).getAnnotation(JsonProperty.class);
if (property != null) {
name = property.value();
}
name = propName == null ? name : propName + "." + name;
field.setAccessible(true);
Object prop = field.get(object);
if (prop == null) {
continue;
}
if (PropertyType.isBasicClazz(field.getType()) || prop instanceof Class
|| prop instanceof Collection) {
result.put(name, (C) prop);
} else if (prop instanceof Enum) {
Method[] methods = prop.getClass().getDeclaredMethods();
for (Method method : methods) {
JsonValue jsonValue = method.getAnnotation(JsonValue.class);
if (jsonValue != null) {
Object enumVal = method.invoke(prop);
result.putAll(getBeanJSONPropertyMap(name, enumVal, clazz));
continue fieldLoop;
}
}
} else {
result.putAll(getBeanJSONPropertyMap(name, prop, clazz));
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return result;
}
/**
* @param <T> 泛型
* @param json json字符串
* @param parentClass 最外层的父类
* @param childrenClasses 属性类
* @return 反序列化后的对象
* @描述 : 从JSON中获取对象
* @作者 : Dong ZhaoYang
* @日期 : 2017/02/24
* @时间 : 11:45
*/
public static <T> T getBeanFromJson(String json,
Class<?> parentClass, Class<?>... childrenClasses) {
JavaType javaType = objectMapper.getTypeFactory()
.constructParametrizedType(parentClass, parentClass, childrenClasses);
T o = null;
try {
o = objectMapper.readValue(json, javaType);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return o;
}
/**
* @param clazz 需要实例化的字节码对象
* @param <T> 对象类型
* @return 对象实例
* @描述 : 获取clazz的初始化对象,所有支持的属性 {@link PropertyType}将设为
* 对应的非null默认值
* @作者 : Dong ZhaoYang
* @日期 : 2017/3/6
* @时间 : 15:07
*/
public static <T> T getNoEmptyPropertyInstance(Class<T> clazz) {
T instance = null;
try {
instance = clazz.newInstance();
PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
Method writeMethod = propertyDescriptor.getWriteMethod();
if (writeMethod != null) {
writeMethod.invoke(instance,
PropertyType.fromClazz(propertyDescriptor.getPropertyType()).getDefaultValue());
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return instance;
}
/**
* @param origin 原始对象数据
* @param update 更新对象数据
* @param <T> 对象类型
* @return 待更新的对象
* @描述 : 如果update的属性不为空,则更新对象origin的属性
* @作者 : Dong ZhaoYang
* @日期 : 2017/8/7
* @时间 : 15:48
*/
@SuppressWarnings("unchecked")
public static <T> T updateEntityExceptEmptyProps(T origin, T update) {
T instance = null;
try {
Class<T> clazz = (Class<T>) origin.getClass();
instance = clazz.newInstance();
PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
Method readMethod = propertyDescriptor.getReadMethod();
Method writeMethod = propertyDescriptor.getWriteMethod();
if (readMethod != null && writeMethod != null) {
Object originProperty = readMethod.invoke(origin);
Object updateProperty = readMethod.invoke(update);
writeMethod.invoke(instance, NullHelp.isNull(updateProperty) ? originProperty : updateProperty);
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return instance;
}
/**
* @描述 : 转换为Predicate
* @作者 : Dong ZhaoYang
* @日期 : 2017/8/7
* @时间 : 17:25
*/
@SuppressWarnings("unchecked")
public static <R, Q> Predicate getPredicate(Root<R> root, Q query, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<>();
if(query == null){
return cb.and(list.toArray(new Predicate[list.size()]));
}
try {
List<Field> fields = getAllFields(query.getClass(), new ArrayList<>());
for (Field field : fields) {
boolean accessible = field.isAccessible();
field.setAccessible(true);
PredicateInfo predicateInfo = field.getAnnotation(PredicateInfo.class);
if (predicateInfo != null) {
String propName = predicateInfo.propName();
String attributeName = isBlank(propName) ? field.getName() : propName;
Class<?> fieldType = field.getType();
Object val = field.get(query);
if (NullHelp.isNull(val)) {
continue;
}
switch (predicateInfo.queryType()) {
case BASIC:
list.add(cb.equal(root.get(attributeName).as(fieldType), val));
break;
case GREATER_THAN:
list.add(cb.greaterThanOrEqualTo(root.get(attributeName)
.as((Class<? extends Comparable>) fieldType), (Comparable) val));
break;
case LESS_THAN:
list.add(cb.lessThanOrEqualTo(root.get(attributeName)
.as((Class<? extends Comparable>) fieldType), (Comparable) val));
break;
case LESS_THAN_NQ:
list.add(cb.lessThan(root.get(attributeName)
.as((Class<? extends Comparable>) fieldType), (Comparable) val));
break;
case INNER_LIKE:
list.add(cb.like(root.get(attributeName)
.as(String.class), "%" + val.toString() + "%"));
break;
case LEFT_LIKE:
list.add(cb.like(root.get(attributeName)
.as(String.class), "%" + val.toString()));
break;
case RIGHT_LIKE:
list.add(cb.like(root.get(attributeName)
.as(String.class), val.toString() + "%"));
break;
}
}
field.setAccessible(accessible);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return cb.and(list.toArray(new Predicate[list.size()]));
}
private static List<Field> getAllFields(Class clazz, List<Field> fields) {
if (clazz != null) {
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
getAllFields(clazz.getSuperclass(), fields);
}
return fields;
}
/**
* @param propName 属性名
* @param object 目标实例对象
* @param <T> 对象类型
* @return 属性值
* @描述 : 获取object对象的propName的属性值
* @作者 : Dong ZhaoYang
* @日期 : 2017/3/6
* @时间 : 15:08
*/
public static <T> Object getProperty(String propName, T object) {
Object result = null;
try {
Method readMethod = new PropertyDescriptor(propName, object.getClass()).getReadMethod();
if (readMethod != null) {
result = readMethod.invoke(object);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return result;
}
/**
* @描述 : check 属性是否为空,有一个为空则返回false
* @作者 : lww
* @日期 : 2017/3/23
* @时间 : 16:14
*/
public static <T> boolean checkProperties(T object) {
T instance = null;
try {
PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
Method readMethod = propertyDescriptor.getReadMethod();
Object result = readMethod.invoke(object);
if (result == null) {
return false;
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return true;
}
/**
* @param object 目标实例对象
* @param <T> 对象类型
* @param <C> 属性类型
* @return 属性值
* @描述 : 获取object对象的propertyClazz的属性值
* @作者 : Dong ZhaoYang
* @日期 : 2017/3/6
* @时间 : 15:08
*/
@SuppressWarnings("unchecked")
public static <T, C> C getProperty(T object, Class<C> propertyClazz) {
C result = null;
try {
PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
if (propertyDescriptor.getPropertyType().equals(propertyClazz)) {
Method readMethod = propertyDescriptor.getReadMethod();
if (readMethod != null) {
result = (C) readMethod.invoke(object);
}
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return result;
}
/**
* @param clazz 拥有将获取属性的类
* @param propertyClazz 属性的类
* @return 属性的名称
* @描述 : 获取属性名
* @作者 : Dong ZhaoYang
* @日期 : 2017/03/14
* @时间 : 13:33
*/
public static String getPropertyName(Class clazz, Class propertyClazz) {
String result = null;
try {
PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
if (propertyDescriptor.getPropertyType().equals(propertyClazz)) {
result = propertyDescriptor.getName();
}
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return result;
}
/**
* @描述 : Bean属性的字节码类型及其对应的默认值
* @作者 : Dong ZhaoYang
* @日期 : 2017/3/6
* @时间 : 15:08
*/
public enum PropertyType {
BOX_BOOLEAN(Boolean.class, Boolean.FALSE),
BOX_BYTE(Byte.class, 0),
BOX_SHORT(Short.class, 0),
BOX_CHARACTER(Character.class, '\u0000'),
BOX_INTEGER(Integer.class, 0),
BOX_LONG(Long.class, 0L),
BOX_FLOAT(Float.class, 0.00F),
BOX_DOUBLE(Double.class, 0.00D),
STRING(String.class, ""),
BIG_DECIMAL(BigDecimal.class, BigDecimal.ZERO),
BIG_INTEGER(BigInteger.class, BigInteger.ZERO),
DATE(Date.class, new Date()),
NULL(PropertyType.class, null);
private Class clazz;
private Object defaultValue;
PropertyType(Class clazz, Object defaultValue) {
this.clazz = clazz;
this.defaultValue = defaultValue;
}
public static boolean isBoxPrimitive(Class clazz) {
switch (clazz.getName()) {
case "java.lang.Boolean":
case "java.lang.Byte":
case "java.lang.Short":
case "java.lang.Character":
case "java.lang.Integer":
case "java.lang.Long":
case "java.lang.Float":
case "java.lang.Double":
case "java.lang.String":
return true;
default:
return false;
}
}
public static boolean isBasicClazz(Class clazz) {
switch (clazz.getName()) {
case "java.lang.Boolean":
case "java.lang.Byte":
case "java.lang.Short":
case "java.lang.Character":
case "java.lang.Integer":
case "java.lang.Long":
case "java.lang.Float":
case "java.lang.Double":
case "java.lang.String":
case "java.math.BigDecimal":
case "java.math.BigInteger":
case "java.util.Date":
return true;
default:
return false;
}
}
public static PropertyType fromClazz(Class clazz) {
switch (clazz.getName()) {
case "java.lang.Boolean":
return BOX_BOOLEAN;
case "java.lang.Byte":
return BOX_BYTE;
case "java.lang.Short":
return BOX_SHORT;
case "java.lang.Character":
return BOX_CHARACTER;
case "java.lang.Integer":
return BOX_INTEGER;
case "java.lang.Long":
return BOX_LONG;
case "java.lang.Float":
return BOX_FLOAT;
case "java.lang.Double":
return BOX_DOUBLE;
case "java.lang.String":
return STRING;
case "java.math.BigDecimal":
return BIG_DECIMAL;
case "java.math.BigInteger":
return BIG_INTEGER;
case "java.util.Date":
return DATE;
default:
return NULL;
}
}
public Class getClazz() {
return clazz;
}
public Object getDefaultValue() {
return defaultValue;
}
@Override
public String toString() {
return "PropertyType{" +
"clazz=" + clazz +
", defaultValue=" + defaultValue +
"} " + super.toString();
}
}
public static List<Field> getParentField(Class pc) {
List<Field> list = null;
while (pc != null) {
if (list == null) {
list = new ArrayList<>();
}
list.addAll(Arrays.asList(pc.getDeclaredFields()));
pc = pc.getSuperclass();
}
return list;
}
public static List<Field> getParentField(Object o) {
List<Field> list = null;
Class pc = o.getClass();
return BeanHelp.getParentField(pc);
}
public static boolean isBlank(final CharSequence cs) {
int strLen;
if (cs == null || (strLen = cs.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if (Character.isWhitespace(cs.charAt(i)) == false) {
return false;
}
}
return true;
}
}
package me.zhengjie.utils;
import java.util.Collection;
/**
* @描述 : 用于空对象处理
* @作者 : Dong ZhaoYang
* @日期 : 2017/01/19
* @时间 : 09:52
*/
public class NullHelp {
public static boolean isNull(Object obj) {
return obj == null ||
(obj instanceof String && isNullStr((String) obj)) ||
(obj instanceof Collection && ((Collection) obj).isEmpty());
}
public static boolean isNullStr(String str) {
str = str.trim();
return str.isEmpty()/* || str.equalsIgnoreCase("null")
|| str.equalsIgnoreCase("undefined")*/;
}
public static void check(Object... obj) throws Exception {
if (obj == null) {
throw new RuntimeException("数组参数不能为空");
}
for (int i = 0; i < obj.length; i++) {
Object o = obj[i];
if (o == null) {
throw new RuntimeException("obj[" + i + "]不能为空");
}
}
}
}
package me.zhengjie.modules.system.service.dto;
import lombok.Data;
import me.zhengjie.annotation.PredicateInfo;
import java.io.Serializable;
/**
......@@ -15,10 +17,12 @@ public class DictDTO implements Serializable {
/**
* 字典名称
*/
@PredicateInfo(queryType = PredicateInfo.QueryType.INNER_LIKE)
private String name;
/**
* 描述
*/
@PredicateInfo(queryType = PredicateInfo.QueryType.INNER_LIKE)
private String remark;
}
\ No newline at end of file
}
package me.zhengjie.modules.system.service.query;
import me.zhengjie.utils.BeanHelp;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.modules.system.domain.Dict;
import me.zhengjie.modules.system.service.dto.DictDTO;
......@@ -42,7 +43,9 @@ public class DictQueryService {
*/
@Cacheable(keyGenerator = "keyGenerator")
public Object queryAll(DictDTO dict, Pageable pageable){
Page<Dict> page = dictRepository.findAll(new Spec(dict),pageable);
//Page<Dict> page = dictRepository.findAll(new Spec(dict),pageable);
/** Dong ZhaoYang 2019/6/3 修改分页查询方法 */
Page<Dict> page = dictRepository.findAll((root, query, cb) -> BeanHelp.getPredicate(root, dict, cb), pageable);
return PageUtil.toPage(page.map(dictMapper::toDto));
}
......@@ -51,7 +54,9 @@ public class DictQueryService {
*/
@Cacheable(keyGenerator = "keyGenerator")
public Object queryAll(DictDTO dict){
return dictMapper.toDto(dictRepository.findAll(new Spec(dict)));
//return dictMapper.toDto(dictRepository.findAll(new Spec(dict)));
/** Dong ZhaoYang 2019/6/3 不分页 同理 */
return dictMapper.toDto(dictRepository.findAll((root, query, cb) -> BeanHelp.getPredicate(root, dict, cb)));
}
class Spec implements Specification<Dict> {
......@@ -83,4 +88,4 @@ public class DictQueryService {
return cb.and(list.toArray(p));
}
}
}
\ No newline at end of file
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册