Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/erupts/linq.j

Linq.J - LINQ for Java, Object Query Language (LINQ) library based on the JVM → Lambda feature
https://github.com/erupts/linq.j

erupt lambda linq list

Last synced: 3 months ago
JSON representation

Linq.J - LINQ for Java, Object Query Language (LINQ) library based on the JVM → Lambda feature

Awesome Lists containing this project

README

        

# Linq.J 基于内存的对象查询语言
中文 / [English](./README.md)

`Java 中使用类似 C# 的 Linq 能力 ` [C# Linq](https://learn.microsoft.com/zh-cn/dotnet/csharp/linq/)


Erupt Framework
maven-central
jdk 8+
license Apache 2.0
GitEE star
GitHub stars

### Linq 是面向对象的 sql,linq实际上是对内存中数据的查询,使开发人员能够更容易地编写查询。这些查询表达式看起来很像SQL

> 可以通过最少的代码对数据源进行关联、筛选、排序和分组等操作。这些操作可以在单个查询中组合起来,以获得更复杂的结果,无需for循环与if分支操作数据,内置查询引擎性能卓越

#### 允许编写Java代码以查询数据库相同的方式操作内存数据,例如
- 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`、`...`

#### 使用提示
⚠️ 注意:操作的对象字段必须存在 get 方法便于 lambda 查找,建议配合 **Lombok** 的 @Getter 注解快速创建字段的 get 访问

#### 使用方法
```xml

xyz.erupt
linq.j
0.0.5

```

#### Example 1
```javascript
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);

```

#### Example 2
```java
public class ObjectQuery{

private final List source = http.get("https://gw.alipayobjects.com/os/antfincdn/v6MvZBUBsQ/column-data.json");

private final List 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
List list = Linq.from(source).orderByAsc(TestSource::getDate).write(TestSource.class);
// write Object
TestSource obj = Linq.from(source).limit(3).writeOne(TestSource.class);
// write List
List> map = Linq.from(source).writeMap();
// write Map
Map mapOne = Linq.from(source).writeMapOne();
}

}

```

#### 后续迭代计划

- [ ] 支持多个查询结果集进行组合: UNION ALL、UNION、INTERSECT、EXCEPT、UNION BY NAME
- [ ] 支持窗口函数
- [ ] 支持 Nested loop join
- [x] 支持 having
- [x] 支持分组列格式化 group by date(created_at)