Linq.J条件查询:Like/In/Between用法
还在为Java内存数据查询而烦恼?面对复杂的数据筛选需求,传统的循环和条件判断让代码变得臃肿难懂?Linq.J作为基于JVM的LINQ(Language Integrated Query)库,提供了类似SQL的优雅查询语法,让内存数据操作变得简单直观。本文将深入解析Linq.J中最常用的三个条件查询方法:Like、In、Between,帮助你掌握高效的数据筛选技巧。
📋 读完本文你能得到
- ✅ Like模糊查询的完整用法和实战案例
- ✅ In范围查询的多参数和集合参数处理
- ✅ Between区间查询的边界值处理技巧
- ✅ 三种查询方法的性能对比和最佳实践
- ✅ 复杂条件组合查询的实现方案
🚀 快速开始:环境配置
首先确保项目中已添加Linq.J依赖:
<dependency>
<groupId>xyz.erupt</groupId>
<artifactId>linq.j</artifactId>
<version>0.0.5</version>
</dependency>
创建测试数据模型:
@Data
public class User {
private Integer id;
private String name;
private String email;
private Integer age;
private Date createTime;
}
// 测试数据
List<User> users = Arrays.asList(
new User(1, "张三", "zhangsan@example.com", 25, new Date()),
new User(2, "李四", "lisi@test.com", 30, new Date()),
new User(3, "王五", "wangwu@demo.org", 28, new Date()),
new User(4, "赵六", "zhaoliu@example.com", 35, new Date()),
new User(5, "孙七", "sunqi@test.com", 22, new Date())
);
🔍 Like模糊查询
Like方法用于实现SQL中的LIKE '%value%'模糊匹配,支持字符串包含查询。
基础用法
// 查询姓名中包含"三"的用户
List<User> result = Linq.from(users)
.like(User::getName, "三")
.write(User.class);
// 结果: [User(id=1, name=张三, ...)]
多字段模糊查询
// 查询姓名或邮箱中包含"test"的用户
List<User> result = Linq.from(users)
.where(user ->
user.getName().contains("test") ||
user.getEmail().contains("test")
)
.write(User.class);
// 结果: [User(id=2, name=李四, email=lisi@test.com,...), User(id=5,...)]
Like查询原理
Linq.J的Like方法底层实现基于字符串的contains方法:
default <R> Linq like(SFunction<R, ?> column, Object value) {
return where(column, f -> f != null && value != null && f.toString().contains(value.toString()));
}
📊 In范围查询
In方法用于查询字段值在指定范围内的记录,相当于SQL中的IN (value1, value2, ...)。
基础用法:多参数形式
// 查询ID为1、3、5的用户
List<User> result = Linq.from(users)
.in(User::getId, 1, 3, 5)
.write(User.class);
// 结果: [User(id=1), User(id=3), User(id=5)]
集合参数形式
List<Integer> targetIds = Arrays.asList(2, 4);
List<User> result = Linq.from(users)
.in(User::getId, targetIds)
.write(User.class);
// 结果: [User(id=2), User(id=4)]
NotIn反向查询
// 查询ID不在1、3、5范围内的用户
List<User> result = Linq.from(users)
.notIn(User::getId, 1, 3, 5)
.write(User.class);
// 结果: [User(id=2), User(id=4)]
In查询原理
In方法底层使用Stream API进行匹配:
default <R> Linq in(SFunction<R, ?> column, Object... value) {
return where(column, f -> f != null && Arrays.stream(value).anyMatch(it -> null != it && it.equals(f)));
}
📈 Between区间查询
Between方法用于查询字段值在某个区间范围内的记录,相当于SQL中的BETWEEN start AND end。
基础用法
// 查询年龄在25到30岁之间的用户(包含边界)
List<User> result = Linq.from(users)
.between(User::getAge, 25, 30)
.write(User.class);
// 结果: [User(id=1, age=25), User(id=2, age=30), User(id=3, age=28)]
日期区间查询
Date startDate = // 开始日期
Date endDate = // 结束日期
List<User> result = Linq.from(users)
.between(User::getCreateTime, startDate, endDate)
.write(User.class);
Between查询原理
Between方法使用CompareUtil进行边界比较:
default <R> Linq between(SFunction<R, ?> column, Object start, Object end) {
return where(column, row -> CompareUtil.compare(row, start, CompareSymbol.GTE) &&
CompareUtil.compare(row, end, CompareSymbol.LTE));
}
🎯 综合实战案例
场景:用户管理系统查询
public class UserService {
private final List<User> users = // 初始化用户数据
// 综合查询:姓名包含"张"、年龄在20-30岁、ID在特定范围内的用户
public List<User> searchUsers(String keyword, Integer minAge, Integer maxAge, List<Integer> ids) {
return Linq.from(users)
.like(User::getName, keyword)
.between(User::getAge, minAge, maxAge)
.in(User::getId, ids)
.orderBy(User::getAge)
.write(User.class);
}
// 复杂条件组合查询
public List<User> advancedSearch(SearchCriteria criteria) {
return Linq.from(users)
.where(user -> {
boolean match = true;
if (criteria.getKeyword() != null) {
match = match && user.getName().contains(criteria.getKeyword());
}
if (criteria.getMinAge() != null && criteria.getMaxAge() != null) {
match = match && user.getAge() >= criteria.getMinAge()
&& user.getAge() <= criteria.getMaxAge();
}
if (criteria.getEmailDomain() != null) {
match = match && user.getEmail().endsWith("@" + criteria.getEmailDomain());
}
return match;
})
.write(User.class);
}
}
⚡ 性能优化建议
1. 查询顺序优化
// 推荐:先过滤数据量小的条件
Linq.from(users)
.in(User::getId, rareIds) // 数据量小的条件在前
.like(User::getName, commonWord) // 数据量大的条件在后
.write(User.class);
2. 避免重复查询
// 不推荐:多次查询相同数据
List<User> result1 = Linq.from(users).like(User::getName, "张").write(User.class);
List<User> result2 = Linq.from(users).in(User::getId, 1,2,3).write(User.class);
// 推荐:一次查询多个条件
List<User> result = Linq.from(users)
.like(User::getName, "张")
.in(User::getId, 1,2,3)
.write(User.class);
3. 使用合适的查询方法
🔄 方法对比总结
| 方法 | 等效SQL | 适用场景 | 性能特点 |
|---|---|---|---|
like() | LIKE '%value%' | 模糊匹配、文本搜索 | 相对较慢,需要遍历所有字符串 |
in() | IN (v1, v2, v3) | 离散值匹配、多选查询 | 较快,使用HashSet优化 |
between() | BETWEEN start AND end | 区间范围查询 | 很快,利用索引和比较操作 |
notIn() | NOT IN (v1, v2, v3) | 排除特定值 | 与in()性能相当 |
🛠️ 常见问题排查
1. Null值处理
// Like查询时处理null值
Linq.from(users)
.where(user -> user.getName() != null && user.getName().contains("keyword"))
.write(User.class);
2. 大小写敏感问题
// 忽略大小写的Like查询
Linq.from(users)
.where(user -> user.getEmail() != null &&
user.getEmail().toLowerCase().contains("test"))
.write(User.class);
3. 边界值处理
// 安全的Between查询(处理null值)
Linq.from(users)
.where(user -> user.getAge() != null &&
user.getAge() >= minAge &&
user.getAge() <= maxAge)
.write(User.class);
🎉 总结
通过本文的学习,你已经掌握了Linq.J中三个核心条件查询方法的完整用法:
- Like查询:用于文本模糊匹配,支持
contains语义 - In查询:用于离散值匹配,支持多参数和集合参数
- Between查询:用于连续区间匹配,包含边界值
这些方法让Java内存数据查询变得异常简单,代码更加清晰易读。在实际项目中,合理组合使用这些查询方法,可以大幅提升开发效率和代码质量。
记住最佳实践:选择合适的查询方法、优化查询顺序、处理好边界情况,这样你就能写出既高效又健壮的数据查询代码。
现在就开始在你的项目中尝试使用Linq.J吧,让数据查询变得优雅而高效!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



