Java 能否在性能良好的JPA实体中使用lambda表达式?

Java 能否在性能良好的JPA实体中使用lambda表达式?,java,jpa,lambda,Java,Jpa,Lambda,因此,我的一个实体中有一段“一夫一妻”的关系: @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH }, fetch = FetchType.LAZY) @OrderBy("priority") private List<Result> results 我希望根据以下条件获取这些结果中包含的对象: Stream<Item> itemsToReturn = results.stream()

因此,我的一个实体中有一段“一夫一妻”的关系:

@OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH }, fetch = FetchType.LAZY)
@OrderBy("priority")
    private List<Result> results
我希望根据以下条件获取这些结果中包含的对象:

Stream<Item> itemsToReturn = results.stream().filter(result -> result.getPriority() > 5)
                .map(Result::getItem)
                .filter(/*some filtering logic*/)
                .limit(numberOfItems);
尽管如此,它似乎不是很有效,因为我猜在进行任何筛选之前,所有项目都将加载到内存中,尽管存在筛选和限制

我的假设正确吗?如果是这样的话,我可以做些什么以便在这个实体中使用lambda,或者我应该编写一个JPA查询来获取这些项目吗


lambdas可以与JPA一起使用吗?

它是否好取决于您的结果集有多大。但是,当您执行代码时,有必要知道会发生什么

将在db表上执行完整扫描 整个表格数据将通过网络传输 整个结果集将加载到JVM主存中 在流上执行文件服务器时,将对整个结果执行线性扫描
上面的代码与旧的for循环没有任何区别。

它是否好取决于结果集有多大。但是,当您执行代码时,有必要知道会发生什么

将在db表上执行完整扫描 整个表格数据将通过网络传输 整个结果集将加载到JVM主存中 在流上执行文件服务器时,将对整个结果执行线性扫描
上面的代码与旧的for循环没有任何不同。

JPA实体应该是POJO类,包含普通字段、集合、get/set方法等等。我建议将所有逻辑移到类中


回答你的问题:JPA已经有了足够快的过滤系统。在大多数情况下,不需要使用lambdas进行过滤。

JPA实体应该是POJO类,包含普通字段、集合、get/set方法等等。我建议将所有逻辑移到类中

回答你的问题:JPA已经有了足够快的过滤系统。在大多数情况下,不需要使用lambdas进行过滤。

在Java和JPA中,使用lambdas进行查询并获得良好的数据库性能是可能的

Jinq与C中的Linq类似,因此lambda查询被转换为SQL JPQL,并像其他查询一样由数据库执行——它们不是由Java执行的*

在Jinq中,与您的示例稍有相似之处的快速示例如下所示:

List<Item> items = jinq.users()
    .where(user -> user.getId() == someId)
    .selectAllList(user -> user.getItems())        // <- a very simple type of join
    .where(item -> item.getPriority() > 5)
    .where(item -> /*some more filtering logic*/) 
    .limit(numberOfItems)
    .toList();                                     // <- this fetches the result from the DB
*请注意,这显然也意味着对lambda中的内容有限制-例如,不能调用任意java方法,因为数据库引擎无法执行这些方法。只允许有限的一组方法-实体关系getter方法是此类允许方法的一个示例。

使用,可以使用lambdas进行查询,并在Java和JPA中获得良好的数据库性能

Jinq与C中的Linq类似,因此lambda查询被转换为SQL JPQL,并像其他查询一样由数据库执行——它们不是由Java执行的*

在Jinq中,与您的示例稍有相似之处的快速示例如下所示:

List<Item> items = jinq.users()
    .where(user -> user.getId() == someId)
    .selectAllList(user -> user.getItems())        // <- a very simple type of join
    .where(item -> item.getPriority() > 5)
    .where(item -> /*some more filtering logic*/) 
    .limit(numberOfItems)
    .toList();                                     // <- this fetches the result from the DB

*请注意,这显然也意味着对lambda中的内容有限制-例如,不能调用任意java方法,因为数据库引擎无法执行这些方法。只允许有限的一组方法—实体关系getter方法是此类允许方法的一个示例。

正如@Sleiman所指出的,这很可能是一个非常昂贵的操作。为什么要用简单的线性搜索替换部分构建为do where子句的数据库?如果由我来审查的话,我会拒绝这个代码。正如@Sleiman所指出的,这很可能是一个非常昂贵的操作。为什么要用简单的线性搜索替换部分构建为do where子句的数据库?如果由我来审查的话,我会拒绝这个代码。