Apache Calcite Linq4j学习

Lin4j简介

Linq4j是Apache Calcite项目中的一个模块,它提供了类似于LINQ(Language-Integrated Query)的功能,用于在Java中进行数据查询和操作。Linq4j可以将逻辑查询转换为物理查询,支持对集合进行筛选、映射、分组等操作。

例如,通过Linq4j可以将类似于以下的逻辑查询语句转换为最终的在java集合上的查询操作:

java 复制代码
Enumerable<Employee> employees = ...; 
Enumerable<String> names = employees
    .where(emp -> emp.getSalary() > 50000)
    .select(emp -> emp.getName());

依赖

复制代码
<dependency>
  <groupId>org.apache.calcite</groupId>
  <artifactId>calcite-linq4j</artifactId>
  <version>1.36.0</version>
</dependency>

Linq4j核心类与接口

  • Linq4j:org.apache.calcite.linq4j.Linq4j,一个实用工具类,可将 java.util.Collection、java.lang.Iterable、java.util.List等集合对象转换为 org.apache.calcite.linq4j.Enumerable
  • Enumerable:接口的职责是定义了对集合进行查询和操作的方法,包括筛选、映射、分组等功能。接口继承了下列三个接口,支持集合的迭代、投影、过滤等操作
    • RawEnumerable (org.apache.calcite.linq4j):返回org.apache.calcite.linq4j.Enumerator,可对Enumerator实现进行迭代
    • Iterable (java.lang):返回java.lang.Iterable,可对Iterable的实现迭代
    • ExtendedEnumerable (org.apache.calcite.linq4j):定义了在集合对象上的操作 例如 select 投影、where 过滤、groupBy 分组 、hashJoin 连接
      因此通过Linq4j转换方法将输入集合转换为Enumerable,这样就可在原始数据上进行操作。

使用案例

使用过滤、投影、分组

  • 投影没有进行映射变换,按原值输出
  • 过滤筛选出大于3的数
  • 最后进行分组,分组后返回的是一个 Grouping 对象,使用sum函数对分组求和,最终输出求和后的结果
    整个操作使用分组后返回的是Grouping对象,因此后续操作基于此对象进行
java 复制代码
        List<Integer> idList = Lists.newArrayList(1,2,3,4,5,6);
        Enumerable<Integer> itEnumerable = Linq4j.asEnumerable(idList);

        Enumerable<Grouping<Boolean, Integer>> result =
        itEnumerable
            .select((a) -> a)
            .where((a) -> a > 3)
            .groupBy(a -> a%2 == 0);

        for (Grouping<Boolean, Integer> item: result) {

            int sum = item.sum(new IntegerFunction1<Integer>() {
                @Override
                public int apply(Integer v0) {
                    return v0;
                }
            });
            System.out.println(item.getKey() + " : " + sum);
        }

通过一个案例,可类推其它方法的使用。

Linq4j在Calcite中的应用

在使用Calcite实现适配多来源数据查询时,需要实现自定义的table,通常需要借助Linq4j提供的方法将集合转换为Enumerable实例,转换过程中依赖asEnumerable方法创建Enumerable实例实例,接着通过select进行对象类型转换。

java 复制代码
public class TableForList extends AbstractTable implements ScannableTable{

    private PersonList personList;

    public TableForList(PersonList personList) {
        this.personList = personList;
    }

    @Override
    public Enumerable<Object[]> scan(DataContext root) {
        return Linq4j.asEnumerable(personList.getPersonList())
            .select(emp -> new Object[]{emp.getId(), emp.getName(), emp.getAge()});
    }
相关推荐
程序员梅雨10 小时前
【从零开始学习数据仓库 | 第一篇】:维度建模理论
大数据·数据仓库·学习·阿里云·数据分析
keyipatience11 小时前
Git学习(4)Git分布式优势与实战配置全解析
git·学习
comyccccc14 小时前
STM32F407VET6核心板的部分电路绘制学习笔记
笔记·stm32·学习
叼烟扛炮14 小时前
Linux 学习笔记(三十六):并发进阶——读写锁 vs 自旋锁,到底怎么选?
linux·运维·服务器·笔记·学习
是隼人14 小时前
buuctf-pwn [极客大挑战 2019]Not Bad(orw+jmp)题解(学习过程持续更新)
学习·安全·pwn入门·ctf入门
weixin_1772972206914 小时前
二手旧物回收小程序先要解决的不是下单,是“上门之后价格变了怎么办“
小程序·apache
努力变的更好15 小时前
H5与小程序之间的回调
前端·小程序·apache
lazy H15 小时前
【计算机网络】第 12 篇:IPv6 详解——地址格式、地址类型与双栈网络
网络·经验分享·后端·学习·计算机网络·408
(●—●)橘子……15 小时前
力扣 第525场周赛 练习理解
数据结构·python·学习·算法·leetcode
一只QAQ15 小时前
python语法学习
linux·python·学习