中文 / English
Java 中使用类似 C# 的 Linq 能力
C# Linq
可以通过最少的代码对数据源进行关联、筛选、排序和分组等操作。这些操作可以在单个查询中组合起来,以获得更复杂的结果,无需for循环与if分支操作数据,内置查询引擎性能卓越
- List 集合、Array 数组中的数据
- CSV、XML、JSON 文档数据集
- Stream、File 流
- Redis、SQL、MongoDB数据库结果集
- 分布式开发时 Feign / Dubbo / gRPC / WebService 等 RPC 结果的关联/筛选/聚合/分页
- 语义化对象转换与映射,团队协作代码更清晰敏捷
- 异构系统数据的内存计算
- 使用代码组织 SQL 结果数据
- 跨数据源的联邦访问
From
Select
Distinct
、Join
、Where
、Group By
、Order By
、Limit
、Offset
、...
<!--包内零外部依赖,体积仅仅50kb-->
<dependency>
<groupId>xyz.erupt</groupId>
<artifactId>linq.j</artifactId>
<version>0.0.5</version>
</dependency>
var strings = Linq.from("C", "A", "B", "B").gt(Th::is, "A").orderByDesc(Th::is).write(String.class);
// [C, B, B]
var integers = Linq.from(1, 2, 3, 7, 6, 5).orderBy(Th::is).write(Integer.class);
// [1, 2, 3, 5, 6, 7]
var name = Linq.from(data)
// left join
.innerJoin(target, Target::getId, Data::getId)
// where like
.like(Data::getName, "a")
// select name
.select(Data::getName)
// distinct
.distinct()
// order by
.orderBy(Data::getName)
.write(String.class);
public class ObjectQuery{
private final List<TestSource> source = http.get("https://gw.alipayobjects.com/os/antfincdn/v6MvZBUBsQ/column-data.json");
private final List<TestSourceExt> target = mongodb.query("db.target.find()");
/**
* select demo
*/
public void select(){
// select *
Linq.from(source).select(TestSource.class);
// select a, b, c
Linq.from(source)
.select(TestSource::getName, TestSource::getDate, TestSource::getTags)
.select(TestSource::getTags, "tag2") // alias
.select(Columns.ofx(TestSource::getId, id -> id + "xxx")); // value convert
// select count(*), sum(id), max(id)
Linq.from(source)
.select(Columns.count("count"))
.select(Columns.sum(TestSource::getId, "sum"))
.select(Columns.max(TestSource::getId, "max"));
}
/**
* join demo
*/
public void join(){
// left join
Linq.from(source).leftJoin(target, TestSourceExt::getId, TestSource::getId)
.select(TestSource.class)
.select(TestSourceExt::getName)
.select(TestSourceExt2::getValue);
// right join
Linq.from(source).rightJoin(target, TestSourceExt::getId, TestSource::getId);
// inner join
Linq.from(source).innerJoin(target, TestSourceExt::getId, TestSource::getId);
// full join
Linq.from(source).fullJoin(target, TestSourceExt::getId, TestSource::getId);
}
/**
* where demo
*/
public void where() {
// =
Linq.from(source).eq(TestSource::getName, "Thanos").select(Columns.count(countAlias)).writeOne(Integer.class);
// >=:lval and <=:rval
Linq.from(source).between(TestSource::getId, 1, 3);
// in (x,x,x)
Linq.from(source).in(TestSource::getId, 1, 2, 3);
// like '%x%'
Linq.from(source).like(TestSource::getName, "a");
// is null
Linq.from(source).isNull(TestSource::getId);
// customer single field where
Linq.from(source).where(TestSource::getId, id -> id >= 5);
// customer condition or multi field
Linq.from(source).where(data -> {
String name = data.get(TestSource::getName);
Integer age = (Integer)data.get(TestSource::getAge);
// name = 'xxx' or age > 10
return "xxx".equals(name) || age > 10;
});
}
/**
* group by demo
*/
public void groupBy(){
Linq.from(source)
.groupBy(TestSource::getName)
.select(
Columns.of(TestSource::getName, "name"),
Columns.min(TestSource::getDate, "min"),
Columns.avg(TestSource::getId, "avg"),
Columns.count("count"),
Columns.count(TestSource::getName, "countName"),
Columns.countDistinct(TestSource::getName, "countDistinct")
)
.having(row -> Integer.parseInt(row.get("avg").toString()) > 2)
.orderBy(TestSource::getAge);
}
/**
* result write demo
*/
public void write(){
// write List<Object>
List<TestSource> list = Linq.from(source).orderByAsc(TestSource::getDate).write(TestSource.class);
// write Object
TestSource obj = Linq.from(source).limit(3).writeOne(TestSource.class);
// write List<Map>
List<Map<String, Object>> map = Linq.from(source).writeMap();
// write Map
Map<String, Object> mapOne = Linq.from(source).writeMapOne();
}
}
- 支持多个查询结果集进行组合: UNION ALL、UNION、INTERSECT、EXCEPT、UNION BY NAME
- 支持窗口函数
- 支持 Nested loop join
- 支持 having
- 支持分组列格式化 group by date(created_at)