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子句的数据库?如果由我来审查的话,我会拒绝这个代码。