前言

最近在工作中遇到一个需求:

从两个数据库表中读取出数据,然后按照指定的方式将两个数据库表中查询到的数据合并到一个List集合中,并提供一个excle表供用户下载。

前提条件:数据库表是可以配置的,很有可能不在一个库中,甚至是两台不同的mysql服务器。

所以不能够通过拼接sql语句到数据库中直接执行,只能先查出两表数据,在应用层进行组装。

需求描述:
image.png

难点

  1. 数据库表是可以配置的,很有可能不在一个库中,甚至是两台不同的mysql服务器,所以不能够通过拼接sql语句到数据库中直接执行,只能先查出两表数据,在应用层进行组装。
  2. 查询出的数据是不固定的,所以只能用List<Map<String,Object>> 接收。
  3. 因为关联字段对应的数据库表字段可能不同,所以两个List 不是通过Map的key来进行组装,而是通过Value,这也是最主要的问题。

实现

搜索引擎上基本都是通过key 进行计算,没找到根据value 来计算的。
所以也算是一个记录,给有缘人 _

  1. 使用Jdbc获取两表数据,这里就不做过多讲解,大家应该都会。
  2. 查询出两个List<Map<String,Object>> 的数据集
  3. 进行处理,直接上代码
public class TestUtil {

    public static void main(String[] args) {
        // 创建数据
        test();
        // 并集
        // test1(LEFT_TABLE_DATA,RIGHT_TABLE_DATA);
        // 交集
        // test2(LEFT_TABLE_DATA,RIGHT_TABLE_DATA);
        // 左连接
        // test3(LEFT_TABLE_DATA,RIGHT_TABLE_DATA);
        // 右连接
        // test4(LEFT_TABLE_DATA,RIGHT_TABLE_DATA);
    }
    // 左表关联字段
    private static final String LEFT_FIELD = "student_id";
    // 右表关联字段
    private static final String RIGHT_FIELD = "student_code";

    // 左表数据
    private static List<Map<String, Object>> LEFT_TABLE_DATA = new ArrayList<>();
    // 右表数据
    private static List<Map<String, Object>> RIGHT_TABLE_DATA = new ArrayList<>();

    public static void test() {
        // 创建数据
        // 左表
        Map<String, Object> baseMap1 = new HashMap<>(2);
        baseMap1.put("student_id", "张三");
        baseMap1.put("english", "90");
        Map<String, Object> baseMa2 = new HashMap<>(2);
        baseMa2.put("student_id", "王五");
        baseMa2.put("english", "60");
        Map<String, Object> baseMa3 = new HashMap<>(2);
        baseMa3.put("student_id", "李四");
        baseMa3.put("english", "70");

        LEFT_TABLE_DATA.add(baseMap1);
        LEFT_TABLE_DATA.add(baseMa2);
        LEFT_TABLE_DATA.add(baseMa3);
        System.out.println("左表:");
        LEFT_TABLE_DATA.forEach(System.out::println);

        // 右表
        Map<String, Object> extendMap1 = new HashMap<>(2);
        extendMap1.put("student_code", "张三");
        extendMap1.put("math", "70");
        Map<String, Object> extendMap2 = new HashMap<>(2);
        extendMap2.put("student_code", "王五");
        extendMap2.put("math", "40");
        Map<String, Object> extendMap3 = new HashMap<>(2);
        extendMap3.put("student_code", "赵六");
        extendMap3.put("math", "50");

        RIGHT_TABLE_DATA.add(extendMap1);
        RIGHT_TABLE_DATA.add(extendMap2);
        RIGHT_TABLE_DATA.add(extendMap3);
        System.out.println("右表:");
        RIGHT_TABLE_DATA.forEach(System.out::println);
    }

    private static void test1(List<Map<String, Object>> leftTableData, List<Map<String, Object>> rightTableData) {
        for (Map<String, Object> base : leftTableData) {
            for (Map<String, Object> extend : rightTableData) {
                if (extend.containsValue(base.get(LEFT_FIELD))) {
                    base.putAll(extend);
                } else {
                    base.put(RIGHT_FIELD,base.get(LEFT_FIELD));
                }
            }
        }
        for (Map<String, Object> extend : rightTableData) {
            for (Map<String, Object> base : leftTableData) {
                if (base.containsValue(extend.get(RIGHT_FIELD))) {
                    extend.putAll(base);
                } else {
                    extend.put(LEFT_FIELD,extend.get(RIGHT_FIELD));
                }
            }
        }
        System.out.println("并集:");
        leftTableData.addAll(rightTableData);
        // 去重
        List<Map<String, Object>> list = leftTableData.stream().distinct().collect(Collectors.toList());
        list.forEach(System.out::println);
    }

    private static void test2(List<Map<String, Object>> leftTableData, List<Map<String, Object>> rightTableData) {
        List<Map<String, Object>> list1 = new ArrayList<>();
        for (Map<String, Object> base : leftTableData) {
            for (Map<String, Object> extend : rightTableData) {
                if (base.containsValue(extend.get(RIGHT_FIELD))) {
                    base.putAll(extend);
                    list1.add(base);
                    break;
                }
            }
        }
        System.out.println("交集:");
        list1.forEach(System.out::println);
    }

    private static void test3(List<Map<String, Object>> leftTableData, List<Map<String, Object>> rightTableData) {
        for (Map<String, Object> base : leftTableData) {
            for (Map<String, Object> extend : rightTableData) {
                if (extend.containsValue(base.get(LEFT_FIELD))) {
                    base.putAll(extend);
                } else {
                    base.put(RIGHT_FIELD,base.get(LEFT_FIELD));
                }
            }
        }
        System.out.println("左连接:");
        leftTableData.forEach(System.out::println);
    }

    private static void test4(List<Map<String, Object>> leftTableData, List<Map<String, Object>> rightTableData) {
        for (Map<String, Object> extend : rightTableData) {
            for (Map<String, Object> base : leftTableData) {
                if (base.containsValue(extend.get(RIGHT_FIELD))) {
                    extend.putAll(base);
                } else {
                    extend.put(LEFT_FIELD,extend.get(RIGHT_FIELD));
                }
            }
        }
        System.out.println("右连接:");
        rightTableData.forEach(System.out::println);
    }
}

左表:
{english=90, student_id=张三}
{english=60, student_id=王五}
{english=70, student_id=李四}
右表:
{student_code=张三, math=70}
{student_code=王五, math=40}
{student_code=赵六, math=50}
并集:
{english=90, student_id=张三, student_code=张三, math=70}
{english=60, student_id=王五, student_code=王五, math=40}
{english=70, student_id=李四, student_code=李四}
{student_id=赵六, student_code=赵六, math=50}
 交集:
{english=90, student_id=张三, student_code=张三, math=70}
{english=60, student_id=王五, student_code=王五, math=40}
左连接:
{english=90, student_id=张三, student_code=张三, math=70}
{english=60, student_id=王五, student_code=王五, math=40}
{english=70, student_id=李四, student_code=李四}
右连接:
{english=90, student_id=张三, student_code=张三, math=70}
{english=60, student_id=王五, student_code=王五, math=40}
{student_id=赵六, student_code=赵六, math=50}

注意

以上仅是测试使用,正式使用需要进行进一步封装或拆解
测试时不同情况虚放开对应的注释。

以上。