前言
最近在工作中遇到一个需求:
从两个数据库表中读取出数据,然后按照指定的方式将两个数据库表中查询到的数据合并到一个List集合中,并提供一个excle表供用户下载。
前提条件:数据库表是可以配置的,很有可能不在一个库中,甚至是两台不同的mysql服务器。
所以不能够通过拼接sql语句到数据库中直接执行,只能先查出两表数据,在应用层进行组装。
需求描述:
难点
- 数据库表是可以配置的,很有可能不在一个库中,甚至是两台不同的mysql服务器,所以不能够通过拼接sql语句到数据库中直接执行,只能先查出两表数据,在应用层进行组装。
- 查询出的数据是不固定的,所以只能用List<Map<String,Object>> 接收。
- 因为关联字段对应的数据库表字段可能不同,所以两个List
实现
搜索引擎上基本都是通过key 进行计算,没找到根据value 来计算的。
所以也算是一个记录,给有缘人 _
- 使用Jdbc获取两表数据,这里就不做过多讲解,大家应该都会。
- 查询出两个List<Map<String,Object>> 的数据集
- 进行处理,直接上代码
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}
注意
以上仅是测试使用,正式使用需要进行进一步封装或拆解
测试时不同情况虚放开对应的注释。
以上。