sybn sybn-util 项目说明文档 - 基于java的跨数据库联合查询

DatasSqlJoinUtil 内存 join 工具

2019-11-08
sybn

简介

DatasJoinUtil 与 DatasSqlJoinUtil 支持 list / stream 互相 join 操作. 其语法和效果类似与 sql 的 join .

DatasJoinUtil 与 DatasSqlJoinUtil 语法一致, 但实现逻辑略有差异, 其中:

DatasJoinUtil 只需指定想左表插入右边中的哪些字段, 默认会返回左表中的所有字段.

DatasSqlJoinUtil 必须指定返回哪些字段, 左边中未指定的字段不会返回. 其效果更接近 sql.

以下是 DatasSqlJoinUtil 的使用介绍.

使用思路

本工具集支持 join 不同数据源的数据, 实现逻辑是将两张表的 join 操作拆分为两次 select 操作和一次 join 操作 , 比如:

-- 拆分前的 sql 语法
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
INNER JOIN Orders
ON Persons.Id_P=Orders.Id_P
ORDER BY Persons.LastName

-- 拆分后代码,由 SqlDdlDaoMultipleImpl 负责执行此代码
SELECT * FROM (
  SELECT Id_P, LastName, FirstName FROM Persons;
  SELECT Id_P, OrderNo FROM Orders;
  INNER JOIN select(LastName, FirstName, OrderNo) ON left.Id_P = right.Id_P;
) ORDER BY LastName

其中 INNER JOIN 这一行自 0.3.8 版开始由 DatasSqlJoinUtil 负责执行.

目前支持 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN 四种规则.

使用样例 (将 mongo 和 habse 表 join 在一起, 并写回 mongo)

  • 从数据库中查询2个list,并将其join为一个.
// dao线程安全。
SqlDdlStreamDao leftDao = new HbaseDaoStreamImpl("leftDao", "hbase://server_1:2121,server_2:2121/");
SqlDdlStreamDao rightDao = new MongoDaoStreamImpl("rightDao", "mongo://username:password@127.0.0.1:27017");

// left 有三个字段: id,a,b
List<Map<String, Object>> left = leftDao.sqlFindListMap("select id, a, b from left where a > 0");
// right 有三个字段: id,left_id,c
List<Map<String, Object>> right = rightDao.sqlFindListMap("select id, left_id, c from right where c > 0");
// join 后 left 有五个字段: id,a,b,right_id,c
List<Map<String, Object>> res = DatasLeftJoinUtil.join(left, right, "LEFT JOIN SELECT(id, a, b, left_id, c) ON left.id = right.left_id");

// 将处理后的数据持久化
rightDao.commonSaveAll("save_table_name", res)

注意: LEFT JOIN SELECT 前缀不区分大小写, 不区分空白符.

  • 从数据库中查询 stream 和 list,并将其join为一个 stream.
// TODO 此功能 DatasSqlJoinStreamUtil 暂未实现
  • 从数据库中查两个 stream ,并将其join为一个 stream.
// TODO 此功能 DatasSqlJoinStreamUtil 暂未实现

参数说明

DatasSqlJoinUtil.join(left, right, “LEFT JOIN SELECT(id as right_id, c) on left.id = right.left_id”)

  • left 被 join 的左表, 可以是 list 或者 stream, 可以是 Map 即将支持 java bean。

  • right 用于 join 的右表,可以是 list / stream / Map。

  • joinConfig = “LEFT JOIN SELECT(id as right_id, c) on left.id = right.left_id”

join 条件, 由 4 部分组成:

   LEFT JOIN SELECT(id as right_id, c) on left.id = right.left_id
-- JOIN_TYPE SELECT JOIN_FIELDS        JOIN_ON_CONFIG
JOIN_TYPE

join 方式目前支持 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN 四种规则.

SELECT

join 方式, 目前只支持 SELECT, 其他方式不赞成使用。

SELECT 方式表示 join 只返回 CCC 中提到的数据。

JOIN_FIELDS

join 字段, 支持 join 左右表的数据到左表, 支持 as, 支持 udf 函数。

优先查找左表, 左右表同名字段只会返回左表值, 暂不提供强制指定个别字段为右表数据。

JOIN_ON_CONFIG

join on 策略, 指定左表哪些字段与右表哪些字段匹配, 多个条件 AND 分开。 支持 using 关键字。

比如: on left.a = right.c AND left.b = right.b

注意: 如果左右表字段类型不一致, 比如: 左表是 int 右表是 String , 本工具类会尝试转换格式后再 join, 大多数情况可以得到正常的结果, 但是要消耗额外的性能。

提示: 某些情况下可能需要 join 数据做一些简单加工, 可以尝试 on left.id = right.trim(b), 但此特性不保证向后兼容, 未来计划改为: on left.id = trim(right.b)

未尽事宜: 咱不支持 join 中加常量比较, 未来会支持。 比如: on left.a = right.c AND right.b > 0

性能优化

某些场景下, DatasSqlJoinUtil 可以大幅优化性能,在这里提供优化方式。

  • 缓存右表

某些右表会反复被相同的左表 join, 此时可以使用 GroupCacheList 包装右表,提高 join 的性能。

List<Map<String, Object>> right = ... ;
// 开启右表 grup 缓存
List<Map<String, Object>> rightCache = new GroupCacheList<>(right)

未尽事宜

  • 暂不支持 join on 中添加比较条件, 近期计划支持.

  • 暂不支持标准 sql 的 join 语法, 短期内暂不实现.

近期更新

  • 2019-09-15 支持 straightJoin 将两个流 join 到一起

注意事项

  • 暂无

相关页面


上一篇 EsDao 介绍

Comments

暂不开放评论! 可微信联系