LINQ的Java等效项是什么? [关闭]

探讨了Java中与LINQ相似的库和API,包括Java8的StreamAPI,Querydsl,JINQ,以及Scala和Clojure等功能性语言在处理集合时的优势。这些工具和语言提供了类似LINQ的查询功能,支持类型安全和函数式编程。

LINQ的Java等效项是什么?


#1楼

听起来每个人都在谈论的Linq只是LinqToObjects。 我认为,这些功能仅提供了Java现在已经可以完成的功能,但是语法却非常丑陋。

我看到的.net中Linq的真正功能是可以在需要委托或表达式的上下文中使用lambda表达式,然后将其编译成适当的形式。 这就是使LinqToSql之类的东西(或LinqToObjects之外的其他东西)能够工作的原因,并使它们具有与LinqToObjects相同的语法。

看起来上面提到的所有项目都仅提供LinqToObjects的功能。 这让我感到,LinqToSql类型的功能对于Java而言并不是遥不可及的。


#2楼

对于LINQ(对象的LINQ),Java 8将具有等效功能,请参阅Project Lambda

它具有Enumerable的LINQ to Objects扩展(stuffs) 。 但是对于诸如Expression和ExpressionTree之类的更复杂的LINQ(如果LINQ to SQL和其他LINQ提供程序想要提供优化和真实的功能,这些是LINQ所必需的),目前还没有任何等效的方法,但是也许将来我们会看到:)

但是我不认为将来会有类似Java的声明式查询之类的事情。


#3楼

没有像LINQ for Java这样的软件。

...

编辑

现在使用Java 8向我们介绍了Stream API ,这在处理集合时是一种类似的事情,但与Linq不太一样。

如果它是您正在寻找的ORM,例如Entity Framework,那么您可以尝试使用Hibernate

:-)


#4楼

有一个名为quaere的项目。

这是一个Java框架,它增加了查询集合的功能。

注意:根据作者的说法,该项目不再维护。


#5楼

一位匿名用户提到了另一个Diting

Diting是一个类库,它通过可链接的方法和.NET中的Linq等匿名接口提供对集合的查询功能。 与大多数其他使用静态方法的集合库不同,这些静态库需要迭代整个集合,Diting提供了一个核心的Enumerable类,其中包含有延迟的可链接方法以对集合或数组执行查询。

支持的方法:任何,强制转换,联系,包含,计数,不同,elementAt,除了first,firstOrDefault,groupBy,interset,join,last,lastOrDefault,ofType,orderBy,orderByDescending,反向,select,selectMany,单,singleOrDefault,跳过,skipWhile,take,takeWhile,toArray,toArrayList,union,


#6楼

Java中没有这样的功能。 通过使用其他API,您将获得此功能。 像假设我们有一个包含名称和ID的动物对象。 我们有具有动物对象的列表对象。 现在,如果要从列表对象中获取所有包含“ o”的动物名。 我们可以编写以下查询

from(animals).where("getName", contains("o")).all();

上面的Query语句将列出名称中包含“ o”字母的动物。 更多信息请浏览以下博客。 http://javaworldwide.blogspot.in/2012/09/linq-in-java.html


#7楼

对于基本功能集合,Java 8内置了它,大多数主要的非Java JVM语言都内置了它(Scala,Clojure等),并且您可以在早期Java版本上添加库。

为了对SQL数据库进行完整的语言集成访问,Scala(在JVM上运行)具有Slick


#8楼

我尝试了来自谷歌的番石榴图书馆 。 它具有FluentIterable ,我认为它接近LINQ。 另请参见FunctionalExplained

List<String> parts = new ArrayList<String>();  // add parts to the collection.    
FluentIterable<Integer> partsStartingA = 
    FluentIterable.from(parts).filter(new Predicate<String>() {
        @Override
        public boolean apply(final String input) {
            return input.startsWith("a");
        }
    }).transform(new Function<String, Integer>() {
        @Override
        public Integer apply(final String input) {
            return input.length();
        }
    });

似乎是Java的扩展库。 当然不如LINQ简洁,但看起来很有趣。


#9楼

Java有许多LINQ等效项,请参见此处进行比较。

对于类型安全的Quaere / LINQ样式框架,请考虑使用Querydsl 。 Querydsl支持JPA /休眠,JDO,SQL和Java集合。

我是Querydsl的维护者,所以这个答案有偏见。


#10楼

您可以使用lambdaj库以更易读的方式选择集合(以及更多)中的项目

https://code.google.com/archive/p/lambdaj/

它比Quaere库具有一些优势,因为它不使用任何魔术字符串,它是完全类型安全的,而且我认为它提供了更具可读性的DSL。


#11楼

没有等效于LINQ for Java的产品。 但是,有一些是外部API看起来像LINQ如https://github.com/nicholas22/jpropel-lighthttps://code.google.com/p/jaque/


#12楼

Scala.Now我开始阅读它,发现它像linq一样,但更简单,更不可读。 但是scala可以在linux上运行,是吗? csharp需要单声道。


#13楼

Java LINQ to SQL实现。 与.NET LINQ相比,提供了完整的语言集成和更大的功能集。


#14楼

LINQ to Objects -JAVA 8添加了Stream API,该API增加了对值流上的函数式操作的支持:

软件包java.util.stream

Java 8解释:将Lambdas应用于Java集合

LINQ to SQL / NHibernate /等 (数据库查询) -一种选择是使用JINQ,它也使用新的JAVA 8功能,并于2014年2月26日在Github上发布: https : //github.com/my2iu/Jinq

Jinq为开发人员提供了一种简单自然的方式来用Java编写数据库查询。 您可以将数据库数据像存储在集合中的普通Java对象一样对待。 您可以遍历它们并使用普通的Java命令对其进行过滤,所有代码将自动转换为优化的数据库查询。 最后,LINQ风格的查询可用于Java!

JINQ项目站点: http : //www.jinq.org/


#15楼

您可以尝试以下库: https : //code.google.com/p/qood/

使用它的一些原因:

  1. 轻量级:仅9个公共界面/课程可供学习。
  2. 像SQL这样的查询:支持分组方式,排序方式,左联接,公式等。
  3. 对于大数据:使用File(QFS)而不是堆内存。
  4. 尝试解决对象关系阻抗不匹配的问题

#16楼

您可以尝试我的库CollectionsQuery 。 它允许对对象集合运行类似LINQ的查询。 就像在LINQ中一样,您必须传递谓词。 如果使用的是Java6 / 7,则必须对接口使用旧语法:

List<String> names = Queryable.from(people)
                                    .filter(new Predicate<Person>() {
                                                public boolean filter(Person p) {
                                                    return p.age>20;
                                                }
                                            })
                                    .map   (new Converter<Person,String>() {
                                                public Integer convert(Person p) {
                                                    return p.name;
                                                }
                                            })
                                    .toList();

您还可以在Java8中使用它,或者在带有RetroLambdagradle插件的旧Java中使用它,那么您将拥有新的精美语法:

List<String> names = Queryable.from(people)
                                    .filter(p->p.age>20)
                                    .map   (p->p.name)
                                    .toList();

如果您需要运行数据库查询,则可以如上所述查看JINQ,但是RetroLambda不能将其反向移植,只能使用序列化的lambda。


#17楼

就像2014年一样,我可以说Java 8中终于有了LINQ,因此不再需要寻找LINQ的替代产品。


#18楼

参见SBQL4J 。 它是与Java集成的类型安全的强查询语言。 允许编写复杂和多重嵌套的查询。 运算符很多,可以在查询中调用Java方法作为构造函数。 查询被转换为纯Java代码(运行时无反射),因此执行速度非常快。

编辑:嗯,到目前为止,SBQL4J是Java语言的唯一扩展,它提供了类似于LINQ的查询功能。 有一些有趣的项目,例如Quaere和JaQue,但它们只是API的,而不是在编译时具有强大类型安全性的语法/语义扩展。


#19楼

https://code.google.com/p/joquery/

支持各种可能性,

给定集合,

Collection<Dto> testList = new ArrayList<>();

类型的

class Dto
{
    private int id;
    private String text;

    public int getId()
    {
        return id;
    }

    public int getText()
    {
        return text;
    }
}

过滤

Java 7

Filter<Dto> query = CQ.<Dto>filter(testList)
    .where()
    .property("id").eq().value(1);
Collection<Dto> filtered = query.list();

Java 8

Filter<Dto> query = CQ.<Dto>filter(testList)
    .where()
    .property(Dto::getId)
    .eq().value(1);
Collection<Dto> filtered = query.list();

也,

Filter<Dto> query = CQ.<Dto>filter()
        .from(testList)
        .where()
        .property(Dto::getId).between().value(1).value(2)
        .and()
        .property(Dto::grtText).in().value(new string[]{"a","b"});

排序 (也适用于Java 7)

Filter<Dto> query = CQ.<Dto>filter(testList)
        .orderBy()
        .property(Dto::getId)
        .property(Dto::getName)
    Collection<Dto> sorted = query.list();

分组 (也可用于Java 7)

GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
        .group()
        .groupBy(Dto::getId)
    Collection<Grouping<Integer,Dto>> grouped = query.list();

联接 (也可用于Java 7)

鉴于

class LeftDto
{
    private int id;
    private String text;

    public int getId()
    {
        return id;
    }

    public int getText()
    {
        return text;
    }
}

class RightDto
{
    private int id;
    private int leftId;
    private String text;

    public int getId()
    {
        return id;
    }

    public int getLeftId()
        {
            return leftId;
        }

    public int getText()
    {
        return text;
    }
}

class JoinedDto
{
    private int leftId;
    private int rightId;
    private String text;

    public JoinedDto(int leftId,int rightId,String text)
    {
        this.leftId = leftId;
        this.rightId = rightId;
        this.text = text;
    }

    public int getLeftId()
    {
        return leftId;
    }

    public int getRightId()
        {
            return rightId;
        }

    public int getText()
    {
        return text;
    }
}

Collection<LeftDto> leftList = new ArrayList<>();

Collection<RightDto> rightList = new ArrayList<>();

可以像这样加入

Collection<JoinedDto> results = CQ.<LeftDto, LeftDto>query().from(leftList)
                .<RightDto, JoinedDto>innerJoin(CQ.<RightDto, RightDto>query().from(rightList))
                .on(LeftFyo::getId, RightDto::getLeftId)
                .transformDirect(selection ->  new JoinedDto(selection.getLeft().getText()
                                                     , selection.getLeft().getId()
                                                     , selection.getRight().getId())
                                 )
                .list();

表达方式

Filter<Dto> query = CQ.<Dto>filter()
    .from(testList)
    .where()
    .exec(s -> s.getId() + 1).eq().value(2);

#20楼

既然Java 8支持lambda,则可以创建与LINQ非常相似的Java API。

Jinq是这些新的Java LINQ样式库之一。

我是这个图书馆的开发商。 它基于使用字节码分析将Java转换为数据库查询的五年研究成果。 与C#的D-LINQ是位于实体框架之上的查询层类似,Jinq能够充当位于JPA或jOOQ之上的查询层。 它支持聚合,组和子查询。 甚至Erik Meijer(LINQ的创建者)也承认Jinq


#21楼

还有一个替代解决方案Coollection

Coolection并没有伪装成新的lambda,但是我们被旧的旧Java项目所包围,这个lib可以为您提供帮助。 它的使用和扩展非常简单,仅覆盖集合中最常用的迭代操作,如下所示:

from(people).where("name", eq("Arthur")).first();
from(people).where("age", lessThan(20)).all();
from(people).where("name", not(contains("Francine"))).all();

#22楼

只是添加了另一种选择:Java 6确实使用javax.persistence.criteria包提供了一种用于类型安全的数据库查询的解决方案。

尽管我必须说这不是真正的LINQ,因为使用LINQ可以查询任何IEnumerable。


#23楼

除非使用javacc创建自己的等效项,否则您将找不到LINQ的等效项。

直到有人找到可行的方法的那一天,还有一些不错的选择,例如


#24楼

JaQu是LINQ的Java等效项。 尽管它是为H2数据库开发的,但由于它使用JDBC,因此它适用于任何数据库。


#25楼

有编程语言Pizza(Java扩展),您应该看看它。 -它使用“流利接口”的概念以声明的方式查询数据,并且在原则上与不带查询表达式的LINQ(http://en.wikipedia.org/wiki/Pizza_programming_language)相同。 但是可惜的是,它并没有被人们追捧,但这将是将类似于LINQ的东西引入Java的一种方法。


#26楼

Lambdas现在可以在Java 8中以JSR-335的形式使用-JavaTM编程语言的Lambda表达式

更新JDK8现在已经发布 ,其中包含项目lambda。 值得一提的是,目前仍是MEAP的Java 8 in Action副本。

请阅读Brian Goetz的有关lambda的文章,以便对在JDK8中如何实现lambda有所体会,同时也了解流,内部迭代,短路和构造方法参考。此外,请查看上面的JSR以获取更多示例。 。

我已经写了一个博客,介绍了在JDK8中使用lambda的一些优点,称为“箭头的力量” ,而且NetBeans 8对将结构转换为JDK8也提供了强大的支持,我也写了博客介绍如何使用NetBeans迁移到JDK 8


#27楼

您可以使用一个非常好的库。

位于此处: https : //github.com/nicholas22/jpropel-light

Lambdas直到Java 8才可用,因此使用它有点不同,而且感觉也不自然。


#28楼

您可以使用scala,它的语法相似,并且实际上可能比linq更强大。


#29楼

也许不是您想要的答案,但是如果您的代码中的某些部分需要在集合上进行大量工作(搜索,排序,过滤,转换,分析),则可以考虑在ClojureScala中编写一些类。

由于其功能性,最擅长使用集合。 我没有使用Scala的丰富经验,但是使用Clojure可能会发现唾手可得的功能更强大的Linq,并且一旦编译,生成的类将与其余代码库无缝集成。


#30楼

查看tiny-q 。 (请注意,您当前无法下载。)

这是改编以上链接的示例:

首先,我们需要一些数据的集合,比如说一组字符串

String[] strings = { "bla", "mla", "bura", "bala", "mura", "buma" };

现在我们只选择以“ b”开头的字符串:

Query<String> stringsStartingWithB = new Query<String>(strings).where(
    new Query.Func<String, Boolean>(){
        public Boolean run(String in) {
            return in.startsWith("b");
        }
    }
);

没有实际的数据被移动复制或类似的操作,只要您开始迭代,它就会得到处理:

for(String string : stringsStartingWithB ) {
    System.out.println(string);
}
<think>好的,我现在需要帮助用户了解如何在ADO.NET和SQL Server中使用LINQ进行数据库查询的基本语法。用户之前已经询问过使用ADO.NET访问SQL Server的一般步骤,现在他们想进一步学习LINQ查询的语法。 首先,我需要回顾用户之前的对话,确保这次回答与之前的指导保持一致。之前我详细解释了使用SqlConnection、SqlCommand等对象进行数据库操作,并提到了DataReader和DataSet。现在用户提到LINQ,可能需要将之前的ADO.NET步骤与LINQ集成起来。 接下来,用户提供的引用内容提到了LINQ to ADO.NET的三个技术:LINQ to DataSet、LINQ to SQL和LINQ to Entities。根据引用[2],LINQ to SQL适用于快速开发,仅支持SQL Server,而Entity Framework(LINQ to Entities)更适用于企业级应用,支持多种数据库。用户的问题是关于基本语法的,因此可能需要涵盖这两种技术。 我需要确定用户具体指的是哪种LINQ技术。用户的问题中提到的是“ADO.NET SQL Server”,这可能意味着他们希望使用LINQ to SQL,因为这是专门针对SQL Server的。不过,也可能需要简要比较不同的LINQ技术,以帮助用户理解差异。 用户可能需要一个从基础开始的逐步指南,包括如何设置目、创建数据模型、执行查询以及注意事。例如,使用LINQ to SQL需要创建DataContext和实体类,而使用Entity Framework则需要DbContext和模型配置。 另外,用户可能对如何将之前的ADO.NET代码转换为LINQ查询感兴趣。比如,之前用SqlCommand执行的INSERT和SELECT操作,如何用LINQ实现。需要提供代码示例,展示两种不同方法的对比,突出LINQ的简洁性。 还要注意引用中的信息,如LINQ to SQL的1:1映射与Entity Framework的m:n映射,这可能影响数据模型的设计。用户可能需要知道如何定义实体类,以及如何配置映射关系。 此外,异常处理、性能优化(如延迟加载与立即加载)、事务处理等最佳实践也应该涵盖,以确保用户了解实际应用中的注意事。 需要确认用户是否了解LINQ的基础知识,比如查询语法和方法语法。如果不确定,可能需要简要解释LINQ的基本结构,如from、where、select等关键字的使用。 最后,生成的相关问题需要引导用户深入了解更多高级主题,比如连接查询、性能优化、事务处理等,以帮助他们进一步学习。</think>#### 一、LINQ查询SQL Server数据库的核心语法(基于ADO.NET) 通过分析引用[1][2]可知,**LINQ to SQL**是ADO.NET中专门用于SQL Server的LINQ技术。其基本语法分为两种形式: --- #### 二、两种基础语法形式 ##### 1. **查询表达式语法**(类似SQL语法) ```csharp var query = from user in dbContext.Users where user.Age > 18 orderby user.Name ascending select new { user.Name, user.Email }; ``` ##### 2. **方法链式语法**(Lambda表达式) ```csharp var query = dbContext.Users .Where(u => u.Age > 18) .OrderBy(u => u.Name) .Select(u => new { u.Name, u.Email }); ``` --- #### 三、完整开发流程(以LINQ to SQL为例) ##### 1. **创建数据模型** *步骤说明:* - 添加`LINQ to SQL Classes`(.dbml文件) - 从服务器资源管理器拖拽表到设计器 - 自动生成`DataContext`类和实体类 *示例模型结构:* ```csharp // 自动生成的DataContext public partial class MyDbContext : DataContext { public Table<User> Users; } // 自动生成的实体类 [Table(Name="dbo.Users")] public partial class User { [Column] public string Name { get; set; } [Column] public int Age { get; set; } } ``` ##### 2. **基本查询操作** | 操作类型 | LINQ语法示例 | |----------------|-----------------------------------------------------------------------------| | **过滤** | `Where(u => u.City == "北京")` | | **排序** | `OrderBy(u => u.BirthDate).ThenByDescending(u => u.Salary)` | | **投影** | `Select(u => new { u.ID, FullName = u.FirstName + u.LastName })` | | **分页** | `Skip(20).Take(10)` | | **聚合** | `Average(u => u.Score)` / `Count(u => u.IsActive)` | ##### 3. **执行查询** ```csharp using (var db = new MyDbContext(connectionString)) { // 延迟执行(实际访问数据库时执行) var activeUsers = db.Users.Where(u => u.IsActive); // 立即执行(强制立即获取数据) var list = activeUsers.ToList(); // 转换为List var array = activeUsers.ToArray();// 转换为数组 } ``` --- #### 四、与原生ADO.NET对比示例 **传统ADO.NET查询:** ```csharp using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users WHERE Age>@Age", conn)) { cmd.Parameters.AddWithValue("@Age", 18); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { // 手动映射字段... } } } ``` **LINQ等效实现:** ```csharp var users = db.Users.Where(u => u.Age > 18).ToList(); // 自动完成: // 1. 参数化查询生成 // 2. 对象关系映射(ORM) // 3. 类型安全验证 ``` --- #### 五、关键特性说明 1. **延迟执行机制** LINQ查询在调用`ToList()`/`FirstOrDefault()`等方法前不会实际访问数据库[^1] 2. **SQL转换原理** 通过表达式树(Expression Trees)将LINQ转换为标准SQL: $$ \text{LINQ表达式} \xrightarrow{\text{转换}} \text{SELECT * FROM Users WHERE Age > 18} $$ 3. **关联查询处理** ```csharp // 多表关联查询 var orders = from u in db.Users join o in db.Orders on u.UserID equals o.CustomerID select new { u.Name, o.OrderDate }; ``` 4. **存储过程调用** ```csharp // 映射存储过程 db.InsertUser("张三", 25); // 自动生成的方法 ``` --- #### 六、最佳实践建议 1. **性能优化** - 使用`.AsNoTracking()`禁用变更跟踪(只读场景) - 避免N+1查询问题(使用`Include()`预加载关联数据) 2. **异常处理** ```csharp try { db.SubmitChanges(); } catch (SqlException ex) { // 处理并发冲突等异常 } ``` 3. **事务控制** ```csharp using (var transaction = db.Connection.BeginTransaction()) { try { db.Transaction = transaction; // 多个操作... db.SubmitChanges(); transaction.Commit(); } catch { transaction.Rollback(); } } ``` --- #### 七、与Entity Framework对比(引用[2]) | 特性 | LINQ to SQL | Entity Framework | |---------------------|--------------------------|--------------------------| | **数据库支持** | 仅SQL Server | 多数据库(通过Provider) | | **映射复杂度** | 1:1表映射 | 支持复杂映射(m:n) | | **适用场景** | 快速开发小型目 | 企业级复杂系统 | | **查询语法兼容性** | 完全兼容LINQ标准 | 扩展更多高级功能 | --- #### 八、架构示意图 $$ \text{LINQ to SQL数据流} = \underbrace{\text{DataContext}}_{\text{数据库入口}} \leftarrow \text{实体类} \xrightarrow{\text{映射}} \text{SQL Server表} $$ --- --相关问题--: 1. 如何优化LINQ to SQL的查询性能? 2. LINQ中的延迟加载和立即加载有何区别? 3. 如何处理LINQ to SQL的并发更新冲突? 4. Entity Framework Core与LINQ to SQL的核心区别是什么?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值