首页 > 数据库 >java实现的类似于sql join操作的工具类,通用递归,最低需要java8

java实现的类似于sql join操作的工具类,通用递归,最低需要java8

时间:2023-08-29 10:24:32浏览次数:37  
标签:t1JoinKey java t2 param t1 t2JoinKey sql join 主表

直接上代码,缺包的自行替换为自己项目中存在的

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hutool.core.util.ObjectUtil;

/**
 * @description:数据列表关联,类似于sql中的join
 * @author: Binz 
 * @time:2019-09-29 09:40
 */
public class Java8Util {

    private static final Logger logger = LoggerFactory.getLogger(Java8Util.class);

    /**
     * @description:关联到主表的基本类型属性去  一对多
     * @param: t1 主表
     * @param: t2 关联表
     * @param: t1JoinKey 主表的关联key
     * @param: t2JoinKey 关联表的关联key
     * @param: toT1ListProperty 需要赋值到t1的List属性
     * @return  
     * @author: Binz
     * @time:2019-09-29 09:44
     * <pre>
     * 例如:Java8Util.joinToList(users, roles, User::getId, Role::getUserId, User::setRoles);
     * </pre>
     */
    public static <P,C,JR> void joinToList(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,BiConsumer<P,List<C>> toT1ListProperty) {
        try {
            Map<Object,List<C>> valueMap = new HashMap<>();
            JR t2JoinValue;
            for (C c : t2) {
                t2JoinValue = t2JoinKey.apply(c);
                valueMap.putIfAbsent(t2JoinValue, new ArrayList<>());
                valueMap.get(t2JoinValue).add(c);
            }
            JR t1JoinValue;
            List<C> list;
            for (P p : t1) {
                t1JoinValue = t1JoinKey.apply(p);
                list = valueMap.get(t1JoinValue);
                toT1ListProperty.accept(p, list); 
            }
        } catch (Exception e) {
            logger.error( ExceptionUtils.getStackTrace(e));
        }
    }

    /**
     * @description:关联到主表的基本类型属性去  一对多
     * @param: t1 主表
     * @param: t2 关联表
     * @param: t1JoinKey 主表的关联key
     * @param: t2JoinKey 关联表的关联key
     * @param: getT2PropertyKey 获取t2指定属性
     * @param: toT1ListProperty 需要赋值到t1的List属性
     * @return  
     * @author: Binz
     * @time:2019-09-29 09:44
     * <pre>
     * 例如:Java8Util.joinToListProperty(users, roles, User::getId, Role::getUserId, Role::Id ,Role::getName , User::setRoleNames);
     * </pre>
     */
    public static <P,C,JR,SR> void joinToListProperty(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,Function<C, SR> getT2PropertyKey ,BiConsumer<P,List<SR>> toT1PropertyKey) {
        try {
            Map<Object,List<SR>> valueMap = new HashMap<>();
            JR t2JoinValue;
            for (C c : t2) {
                t2JoinValue = t2JoinKey.apply(c);
                valueMap.putIfAbsent(t2JoinValue, new ArrayList<>());
                valueMap.get(t2JoinValue).add(getT2PropertyKey.apply(c));
            }
            JR t1JoinValue;
            List<SR> list;
            for (P p : t1) {
                t1JoinValue = t1JoinKey.apply(p);
                list = valueMap.get(t1JoinValue);
                toT1PropertyKey.accept(p,list); 
            }
        } catch (Exception e) {
            logger.error( ExceptionUtils.getStackTrace(e));
        }
    }
    
    public static <P,C,JR,SR> void joinToSetProperty(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,Function<C, SR> getT2PropertyKey ,BiConsumer<P,Set<SR>> toT1PropertyKey) {
        try {
            Map<Object,Set<SR>> valueMap = new HashMap<>();
            JR t2JoinValue;
            for (C c : t2) {
                t2JoinValue = t2JoinKey.apply(c);
                valueMap.putIfAbsent(t2JoinValue, new HashSet<>());
                valueMap.get(t2JoinValue).add(getT2PropertyKey.apply(c));
            }
            JR t1JoinValue;
            Set<SR> list;
            for (P p : t1) {
                t1JoinValue = t1JoinKey.apply(p);
                list = valueMap.get(t1JoinValue);
                toT1PropertyKey.accept(p,list); 
            }
        } catch (Exception e) {
            logger.error( ExceptionUtils.getStackTrace(e));
        }
    }


    /**
     * @description:关联到主表的基本类型属性去  一对一
     * @param: t1 主表
     * @param: t2 关联表
     * @param: t1JoinKey 主表的关联key
     * @param: t2JoinKey 关联表的关联key
     * @param: toT1PropertyKey 把t2 设置到 t1指定的属性
     * @return  
     * @author: Binz
     * @time:2019-09-29 09:44
     * <pre>
     * 例如:joinToEntity(users, accountss, User::getId, Account::getUserId,  User::setAccount);
     * </pre>
     */
    public static <P,C,JR> void joinToEntity(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,BiConsumer<P,C> toT1EntityProperty) {
        try {
            Map<Object,List<P>> m1 = new HashMap<>(t1.size());
            Object t1KeyValue;
            for (P p : t1) {
                t1KeyValue = t1JoinKey.apply(p);
                m1.putIfAbsent(t1KeyValue, new ArrayList<>());
                m1.get(t1KeyValue).add(p);
            }
            Object t2JoinKeyValue;
            List<P> ps;
            for (C c : t2) {
                t2JoinKeyValue = t2JoinKey.apply(c);
                ps = m1.get(t2JoinKeyValue);
                if(ps != null) {
                    for (P p : ps) {
                        toT1EntityProperty.accept(p, c);
                    }
                }
            }
        } catch (Exception e) {
            logger.error( ExceptionUtils.getStackTrace(e));
        }
    }

    /**
     * @description:关联到主表的基本类型属性去  一对一
     * @param: t1 主表
     * @param: t2 关联表
     * @param: t1JoinKey 主表的关联key
     * @param: t2JoinKey 关联表的关联key
     * @param: getT2PropertyKey 从t2获取某一个值
     * @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
     * @return  
     * @author: Binz
     * @time:2019-09-29 09:44
     * <pre>
     * 例如:joinToEntity(users, accountss, User::getId, Account::getUserId,  User::setAccount);
     * </pre>
     */
    public static <P,C,JR> void joinToEntityByFilter(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,Predicate<P> t1Filter,Predicate<C> t2Filter,BiConsumer<P,C> toT1EntityProperty) {
        try {
            Map<Object,List<P>> m1 = new HashMap<>(t1.size());
            Object t1KeyValue;
            for (P p : t1) {
                if(t1Filter == null || t1Filter.test(p)) {
                    t1KeyValue = t1JoinKey.apply(p);
                    m1.putIfAbsent(t1KeyValue, new ArrayList<>());
                    m1.get(t1KeyValue).add(p);
                }
            }
            Object t2JoinKeyValue;
            List<P> ps;
            for (C c : t2) {
                if(t2Filter == null || t2Filter.test(c)) {
                    t2JoinKeyValue = t2JoinKey.apply(c);
                    ps = m1.get(t2JoinKeyValue);
                    if(ps != null) {
                        for (P p : ps) {
                            toT1EntityProperty.accept(p, c);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error( ExceptionUtils.getStackTrace(e));
        }
    }



    /**
     * @description:关联到主表的基本类型属性去  一对一
     * @param: t1 主表
     * @param: t2 关联表
     * @param: t1JoinKey 主表的关联key
     * @param: t2JoinKey 关联表的关联key
     * @param: getT2PropertyKey 从t2获取某一个值
     * @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
     * @return  
     * @author: Binz
     * @time:2019-09-29 09:44
     * <pre>
     * 例如:joinToProperty(users, persons, User::getId, Person::getUserId, Person::getRealName User::setRealName);
     * </pre>
     */
    public static <P,C,JR,SR> void joinToProperty(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,Function<C, SR> getT2PropertyKey ,BiConsumer<P,SR> toT1PropertyKey) {
        try {
            Map<Object,List<P>> m1 = new HashMap<>(t1.size());
            Object t1KeyValue;
            for (P p : t1) {
                t1KeyValue = t1JoinKey.apply(p);
                m1.putIfAbsent(t1KeyValue, new ArrayList<>());
                m1.get(t1KeyValue).add(p);
            }
            Object t2JoinKeyValue;
            List<P> ps;
            for (C c : t2) {
                t2JoinKeyValue = t2JoinKey.apply(c);
                ps = m1.get(t2JoinKeyValue);
                if(ps != null) {
                    for (P p : ps) {
                        toT1PropertyKey.accept(p, getT2PropertyKey.apply(c));
                    }
                }
            }
        } catch (Exception e) {
            logger.error( ExceptionUtils.getStackTrace(e));
        }
    }

    /**
     * @description:关联到主表的基本类型属性去  一对一
     * @param: t1 主表
     * @param: t2 关联表
     * @param: t1JoinKey 主表的关联key
     * @param: t2JoinKey 关联表的关联key
     * @param: t1Filter 表一过滤 可为空
     * @param: t2Filter 表二过滤 可为空
     * @param: getT2PropertyKey 从t2获取某一个值
     * @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
     * @return  
     * @author: Binz
     * @time:2019-09-29 09:44
     * <pre>
     * 例如:
     *  joinToPropertyByFilter(users, persons, User::getPersonId, Person::getId, e -> {
            return  e.getId() != null && e.getId() > 3;
        },null, Person::getRealName, User::setRealName);
     * </pre>
     */
    public static <P,C,JR,SR> void joinToPropertyByFilter(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,Predicate<P> t1Filter,Predicate<C> t2Filter,Function<C, SR> getT2PropertyKey ,BiConsumer<P,SR> toT1PropertyKey) {
        try {
            Map<Object,List<P>> m1 = new HashMap<>(t1.size());
            Object t1KeyValue;
            for (P p : t1) {
                if(t1Filter == null || t1Filter.test(p)) {
                    t1KeyValue = t1JoinKey.apply(p);
                    m1.putIfAbsent(t1KeyValue, new ArrayList<>());
                    m1.get(t1KeyValue).add(p);
                }
            }
            Object t2JoinKeyValue;
            List<P> ps;
            for (C c : t2) {
                if(t2Filter == null || t2Filter.test(c)) {
                    t2JoinKeyValue = t2JoinKey.apply(c);
                    ps = m1.get(t2JoinKeyValue);
                    if(ps != null) {
                        for (P p : ps) {
                            toT1PropertyKey.accept(p, getT2PropertyKey.apply(c));
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error( ExceptionUtils.getStackTrace(e));
        }
    }

    /**
     * @description:关联到主表的基本类型属性去  一对一
     * @param: t1 主表
     * @param: t2 关联表
     * @param: t1JoinKey 主表的关联key
     * @param: t2JoinKey 关联表的关联key
     * @param: getT2PropertyKey 从t2获取某一个值
     * @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
     * @return  
     * @author: Binz
     * @time:2019-09-29 09:44
     * <pre>
     * 例如:
     * joinToPropertys(users, persons, User::getPersonId, Person::getId, (user,person)->{
     *      user.setRealName("乱设置的"+person.getId());
     *      user.setAge(person.getAge());
     * });
     * </pre>
     */
    public static <P,C,JR,SR> void joinToPropertys(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey,BiConsumer<P,C> toT1Propertys) {
        try {
            Map<Object,List<P>> m1 = new HashMap<>(t1.size());
            Object t1KeyValue;
            for (P p : t1) {
                t1KeyValue = t1JoinKey.apply(p);
                m1.putIfAbsent(t1KeyValue, new ArrayList<>());
                m1.get(t1KeyValue).add(p);
            }
            Object t2JoinKeyValue;
            List<P> ps;
            for (C c : t2) {
                t2JoinKeyValue = t2JoinKey.apply(c);
                ps = m1.get(t2JoinKeyValue);
                if(ps != null) {
                    for (P p : ps) {
                        toT1Propertys.accept(p, c);
                    }
                }
            }
        } catch (Exception e) {
            logger.error( ExceptionUtils.getStackTrace(e));
        }
    }


    /**
     * @description:关联到主表的基本类型属性去  一对一
     * @param: t1 主表
     * @param: t2 关联表
     * @param: t1JoinKey 主表的关联key
     * @param: t2JoinKey 关联表的关联key
     * @param: getT2PropertyKey 从t2获取某一个值
     * @param: toT1PropertyKey 把t2获取到的值设置到 t1指定的属性
     * @return  
     * @author: Binz
     * @time:2019-09-29 09:44
     * <pre>
     * 例如:
     * joinToPropertysByFilter(users, persons, User::getPersonId, Person::getId , e -> {
            return  e.getId() != null && e.getId() > 3;
        }, (t1,t2)->{
            t1.setRealName("有过滤的乱设置的"+t2.getId());
            t2.setAge(1);
        });
     * </pre>
     */
    public static <P,C,JR,SR> void joinToPropertysByFilter(Collection<P> t1, Collection<C> t2,Function<P, JR> t1JoinKey ,Function<C,JR> t2JoinKey , Predicate<P> t1Filter,BiConsumer<P,C> toT1Propertys) {
        try {
            Map<Object,List<P>> m1 = new HashMap<>(t1.size());
            Object t1KeyValue;
            for (P p : t1) {
                if(t1Filter.test(p)) {
                    t1KeyValue = t1JoinKey.apply(p);
                    m1.putIfAbsent(t1KeyValue, new ArrayList<>());
                    m1.get(t1KeyValue).add(p);
                }
            }
            Object t2JoinKeyValue;
            List<P> ps;
            for (C c : t2) {
                t2JoinKeyValue = t2JoinKey.apply(c);
                ps = m1.get(t2JoinKeyValue);
                if(ps != null) {
                    for (P p : ps) {
                        toT1Propertys.accept(p, c);
                    }
                }
            }
        } catch (Exception e) {
            logger.error( ExceptionUtils.getStackTrace(e));
        }
    }

    /**
     * 通用递归,使用示例
     * <br/>List<DepartmentTreeVo> list = new ArrayList<>();
     * <br/>Java8Util.recursion(departmentTree, DepartmentTreeVo::getChildren, t -> {
     * <br/>      list.add(t);
     * <br/>});
     * @param ts
     * @param childsFn   
     * @param then
     */
    public static <T> void  recursion(List<T> ts, Function<T, List<T>> childsFn , Consumer<T> then) {
        for(T t : ts) {
            then.accept(t);
        }
        for(T t : ts) {
            List<T> childs = childsFn.apply(t);
            if(ObjectUtil.isNotEmpty(childs)) {
                recursion(childs, childsFn, then);
            }
        }
    }
}

 

标签:t1JoinKey,java,t2,param,t1,t2JoinKey,sql,join,主表
From: https://www.cnblogs.com/binz/p/17664073.html

相关文章

  • JAVA编译准备
    1.JAVA语言特点1.Java语言是面向对象的(oop)2.Java语言是健壮的。Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证3.Java语言是跨平台性的。[一个编译好的.class文件可以在多个系统下运行]4.Java语言是解释型语言解释型语言:java、javascript、P......
  • MySq之一条mysql语句来更新(插入)查询结果
    想起之前没问人家自己那213的做法,想起来都想怎么笑(记录之前困惑的问题解决了的)非常的简单要插入teble1表中的id>100的字段name,address 到table2表insertintotable2(name,address)(selectname,addressfromtable1whereid>100)要查询teble1表中的name=阿呜......
  • Java底层起步
    <h3style="text-align:center;">Java底层起步</h3>Java介绍什么是面向对象?例如:小戴正在做饭时,发现没酱油了,对着外面的朋友小张说,小张你去买瓶酱油,然后小张给楼下超市的小王打电话,让送了一瓶酱油上来。在上述的过程中,从面向对象的角度来讲,其强调的是谁来做这个事,而不是这个事......
  • MySql之 replace 用法
    mysqlreplace实例说明: UPDATEtb1SETf1=REPLACE(f1,'abc','def'); REPLACE(str,from_str,to_str) 在字符串str中所有出现的字符串from_str均被to_str替换,然后返回这个字符串 这个函数用来批量替换数据中的非法关键字是很有用的!如下例子: 例1:UPDATEBBSTo......
  • MYSQL如何从文件中把数据复制进数据库表中
    。至少有两种修正方法:·编辑文件“mysql.txt”改正错误,然后使用DELETE和LOADDATA清空并重新装载表:·mysql>DELETEFROMpet;·mysql>LOADDATALOCALINFILE'pet.txt'INTOTABLEpet;注:‘***’->是你的文件路径地址然而,如果这样操做,......
  • Mysql之数据库设计
    一、三大范式1、第一范式:消除一个字段包含多个数据库值,消除一个记录包含重复的组(单独的一列包含多个项目),即可满足1NF。2、第二范式:消除部分依赖性即可转化为2NF。部分依赖性表示一个记录中包括的字段只依赖于主键的一部分。解决部分依赖性的最简单方法是将复合主键分成两部分,每......
  • Java的部分八股(随便记着玩)
    Java的部分八股1.Hashmap和Hashtable的区别1.安全性hashtable是线程安全的,hashmap是非线程安全的但是hashmap的性能高于hashtable多线程下使用hashmap需要使用一个线程安全的集合2.容量部分Hashmap的初始容量为16,hashtable的初始容量为11,填充因子默认都是0.75Hashmap扩容......
  • MySQL借助ibd文件恢复数据技巧?
    还记得我们之前写过的《只需一招,让失控的研发爱上你》吗?前文提到过我们日常使用的比较多的两种数据库恢复方法是:以上两种方法都可以实现实时性的回档,但是你会认为有了这两种技能就够了吗?不….!在线上这种错综复杂的架构中,其实还有很多未知的原因,我们是没法预知的。例如以下这......
  • 大华智慧园区综合管理平台searchJson SQL注⼊漏洞
    漏洞简介大华智慧园区综合管理平台是一款综合管理平台,具备园区运营、资源调配和智能服务等功能。平台意在协助优化园区资源分配,满足多元化的管理需求,同时通过提供智能服务,增强使用体验。由于该平台未对用户输入数据做限制,攻击者可以直接将恶意代码拼接进SQL查询语句中,导致系统出......
  • SQL刷题小计
    SQL刷题小计确定哪些订单购买了prod_id为BR01的产品(2)这个题可以采用子查询和联合查询子查询#先在第一张表当中查询出id为BRO1的数据然后再将这个数据放在第二张表当中查询selectorder_numfromorderitemswhereprod_id='BR01';selectcust_id,order_datefromOrd......