Diboot mybatis plus辅助工具

diboot mybatis plus辅助工具
泛型

class Person(){
	private String no;
	private String name;
	private Integer age;
}

有一个List
{
{no:4104291989000,name:小红,age:20},
{no:4104291989001,name:小红,age:21},
{no:4104291989002,name:小明,age:23},
}

  Map<String,T> map= 
  BeanUtils.convertToStringKeyObjectMap(List<Person> persons,"no");

实现将List变成如下形式:

  {
   "4104291989000":{no:4104291989000,name:小红,age:20},
   "4104291989001":{no:4104291989001,name:小红,age:21},
   "4104291989002":{no:4104291989002,name:小明,age:23},
  }
  Map<String,List<T>> map= 
  BeanUtils.convertToStringKeyObjectListMap(List<Person> persons,"name";

变成如下形式

  {
   "小红":
   [{no:4104291989000,name:小红,age:20},{no:4104291989001,name:小红,age:21}]
   "小明":{no:4104291989002,name:小明,age:23}
  }

写了两个转换方法

public class MyListUtil<T, U> {
    public static <T, U> List<U> streamConvertToList(List<? extends T> list, Function<? super T, ? extends U> iConvert) {
        if (isNullOrEmpty(list)) {
            return Collections.EMPTY_LIST;
        }

        List<U> returnList = new ArrayList<>();

        if (!isNullOrEmpty(list)) {
            returnList = list.stream().map(iConvert).collect(Collectors.toList());
        }

        return returnList;
    }

    public static <T, U> List<U> cloneConvertToList(List<? extends T> list, Class<? extends U> clazz) {
        if (isNullOrEmpty(list)) {
            return Collections.EMPTY_LIST;
        }

        List<U> returnList = new ArrayList<>();

        if (!isNullOrEmpty(list)) {
            for (T t : list) {
                U u = null;

                try {
                    u = clazz.newInstance();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

                BeanUtils.copyProperties(t, u);
                returnList.add(u);
            }
        }

        return returnList;
    }
 }

可以这么用
将一个List的内容转成另一个类型的List。采用属性值拷贝的方法。

List<MaterialInfo> materialInfos = 
MyListUtil.cloneConvertToList(materialApplyOrder.getMaterials(), MaterialInfo.class);

取出一个List的某个字段的集合

  List<String> codes = MyListUtil.streamConvertToList(entities, MaterialInfo::getCode);

还可以这么用将一个List转成List

 List<Integer> standardItemIds = 
 MyListUtil.streamConvertToList(Arrays.asList(itemIds1), Integer::parseInt);

转换为field对应的类型

    /**
     * 转换为field对应的类型
     * @param value
     * @param field
     * @return
     */
    public static Object convertValueToFieldType(Object value, Field field){
        String type = field.getGenericType().getTypeName();
        if(value.getClass().getName().equals(type)){
            return value;
        }
        if(Integer.class.getName().equals(type)){
            return Integer.parseInt(S.valueOf(value));
        }
        else if(Long.class.getName().equals(type)){
            return Long.parseLong(S.valueOf(value));
        }
        else if(Double.class.getName().equals(type)){
            return Double.parseDouble(S.valueOf(value));
        }
        else if(BigDecimal.class.getName().equals(type)){
            return new BigDecimal(S.valueOf(value));
        }
        else if(Float.class.getName().equals(type)){
            return Float.parseFloat(S.valueOf(value));
        }
        else if(Boolean.class.getName().equals(type)){
            return V.isTrue(S.valueOf(value));
        }
        else if(type.contains(Date.class.getSimpleName())){
            return D.fuzzyConvert(S.valueOf(value));
        }
        return value;
    }

获取类所有属性(包含父类中属性)

   /**
     * 获取类所有属性(包含父类中属性)
     * @param clazz
     * @return
     */
    public static List<Field> extractAllFields(Class clazz){
        List<Field> fieldList = new ArrayList<>();
        Set<String> fieldNameSet = new HashSet<>();
        while (clazz != null) {
            Field[] fields = clazz.getDeclaredFields();
            if(V.notEmpty(fields)){ //被重写属性,以子类override的为准
                Arrays.stream(fields).forEach((field)->{
                    if(!fieldNameSet.contains(field.getName())){
                        fieldList.add(field);
                        fieldNameSet.add(field.getName());
                    }
                });
            }
            clazz = clazz.getSuperclass();
        }
        return fieldList;
    }

获取类所有枚举属性(包含父类中属性)

  /**
     * 获取类所有枚举属性(包含父类中属性)
     * @param clazz
     * @return
     */
    public static List<Field> extractFields(Class<?> clazz, Class<? extends Annotation> annotation){
        List<Field> fieldList = new ArrayList<>();
        Set<String> fieldNameSet = new HashSet<>();
        while (clazz != null) {
            Field[] fields = clazz.getDeclaredFields();
            if(V.notEmpty(fields)){ //被重写属性,以子类override的为准
                Arrays.stream(fields).forEach((field)->{
                    if(!fieldNameSet.contains(field.getName()) && field.getAnnotation(annotation) != null){
                        fieldList.add(field);
                        fieldNameSet.add(field.getName());
                    }
                });
            }
            clazz = clazz.getSuperclass();
        }
        return fieldList;
    }

根据指定Key对list去重,这个方法太牛逼了,将一个函数式接口转成另一个函数式接口Function<? super T, ?> -> Predicate

   /**
     * 根据指定Key对list去重
     * @param list
     * @param getterFn
     * @param <T>
     * @return 去重后的list
     */
    public static <T> List<T> distinctByKey(List<T> list, Function<? super T, ?> getterFn){
        return list.stream().filter(distinctPredicate(getterFn)).collect(Collectors.toList());
    }

    /**
     * 去重的辅助方法
     * @param getterFn
     * @param <T>
     * @return
     */
    private static <T> Predicate<T> distinctPredicate(Function<? super T, ?> getterFn) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(getterFn.apply(t));
    }

获取目标类

   /**
     * 获取目标类
     * @param instance
     * @return
     */
    public static Class getTargetClass(Object instance){
        Class targetClass = (instance instanceof Class)? (Class)instance : AopUtils.getTargetClass(instance);
        return targetClass;
    }

从实例中获取目标对象的泛型定义类class

  /**
     * 从实例中获取目标对象的泛型定义类class
     * @param instance 对象实例
     * @param index
     * @return
     */
    public static Class getGenericityClass(Object instance, int index){
        Class hostClass = getTargetClass(instance);
        ResolvableType resolvableType = ResolvableType.forClass(hostClass).getSuperType();
        ResolvableType[] types = resolvableType.getGenerics();
        if(V.isEmpty(types) || index >= types.length){
            types = resolvableType.getSuperType().getGenerics();
        }
        if(V.notEmpty(types) && types.length > index){
            return types[index].resolve();
        }
        log.debug("无法从 {} 类定义中获取泛型类{}", hostClass.getName(), index);
        return null;
    }

反射工具类

public class GenericsUtils{
    /**
     * 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends
     * GenricManager<Book>
     *
     * @param clazz The class to introspect
     * @return the first generic declaration, or <code>Object.class</code> if cannot be determined
     */
    public static Class getSuperClassGenricType(Class clazz) {
        return getSuperClassGenricType(clazz, 0);
    }

    /**
     * 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book>
     *
     * @param clazz clazz The class to introspect
     * @param index the Index of the generic ddeclaration,start from 0.
     */
    public static Class getSuperClassGenricType(Class clazz, int index)
            throws IndexOutOfBoundsException {
            // 获取父类类型,如果父类是带泛型的类那么返回ParameterizedType
            // 如果父类不是带泛型的类,那么返回父类Class
        Type genType = clazz.getGenericSuperclass();// 获取父类类型
        if (!(genType instanceof ParameterizedType)) {
            return Object.class;
        }
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        if (index >= params.length || index < 0) {
            return Object.class;
        }
        if (!(params[index] instanceof Class)) {
            return Object.class;
        }
        return (Class) params[index];
    }
}

Class的
getGenericSuperclass方法简解
定义一个含泛型父类Father
package com.mark.test;

public class Father {

}
定义一个继承了含泛型父类的子类Son
public class Son extends Father {

}
测试各种方法打印效果

public class ClassTest {
	
	@Test
	public void test(){
		Son son = new Son();
		Class clazz = son.getClass();
		System.out.println("---Son extends Father<Son>---");
		System.out.println("自己类:" + clazz);
		System.out.println("父类:" + clazz.getSuperclass());
		System.out.println("带有泛型的父类:" 
		+ clazz.getGenericSuperclass());
		
		//ParameterizedType参数化类型,即泛型 
		ParameterizedType  pt = 
		(ParameterizedType) clazz.getGenericSuperclass();
		Type type = pt.getActualTypeArguments()[0];
		System.out.println("强转类型后获得<T>类型:" + type);
	}
}

—Son extends Father—
自己类 :class com.mark.test.Son
父类 :class com.mark.test.Father
带有泛型的父类 :com.mark.test.Father<com.mark.test.Son>
强转类型后获得类型 :class com.mark.test.Son

getClass(自身类)
getSuperclass(父类)
getGenericSuperclass(带有泛型的父类,原返回值类型为Type,需要强转类型)

//ParameterizedType参数化类型,即泛型 
ParameterizedType  pt = (ParameterizedType) clazz.getGenericSuperclass();

// getActualTypeArguments(泛型类)
    Type type = pt.getActualTypeArguments()[0];
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Diboot是一个面向开发人员的低代码开发平台,将重复性的工作自动化,提高质量、效率、可维护性。 diboot主要有diboot-core和diboot-devtools组成,diboot-core又为springboot专门封装了diboot-core-spring-boot-starter组件,diboot-devtools也以starter提供。 diboot特点: 1、专门为springboot开发,引入依赖,配置好相对路径即可使用; 2、并且支持较为常用的五种数据库(MySQL,ORACLE,SQLServer,PostgreSQL,MariaDB); 3、代码自动生成到项目相应的目录下; 4、数据库表结构更改后,可以同步更改对应文件的代码,而不影响到你自己写的代码; 5、基础框架中依靠注解实现的数据关联(一对一、一对多、多对多、数据字典关联等),将关联问题简单化了; 6、对数据关联设置简单,代码生成与更新也可以自动支持一对一、一对多、多对多、数据字典关联; 7、支持开发以及维护过程中对数据库相关表的数据结构更改进行记录,并写入到对应的数据库更改日志文件中; 8、支持启用lombok的代码形式; 9、支持启用swagger的项目; 10、依赖少、简便轻量、灵活性高。   Diboot轻代码开发平台 更新日志: v2.2.1 新增: @BindQuery注解新增strategy参数,支持空值处理策略(默认忽略空字符串) 基于Spring的内存缓存实现(BaseCacheManager),并优化绑定缓存实现 SqlFileInitializer新增executeMultipleUpdateSqlsWithTransaction,支持事务的多SQL更新 BaseService新增IService的getMap(queryWrapper)等接口 @CollectThisApi注解,自动提取注解对应的rest接口 工具类 S.splitToList,D.formatDurationLabel等 优化: 关联绑定的实现中字段名列名的转换由规则转换改为精确转换 支持BindField&BindDict组合使用 BeanUtils.convertValueToFieldType支持LocalDateTime转换 修复: 修复@BindQuery查询不支持自定义逻辑删除字段的问题 升级依赖jar至最新(spring boot 2.4.5, mybatis-plus 3.4.2等)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值