只需面对N 1查询问题与这样的Spring数据存储库
public interface ToDoRepository extends CrudRepository<ToDo, Long> {
@Query("select new com.package.repr.ToDoRepr(t) from ToDo t " +
"where t.user.id = :userId")
List<ToDoRepr> findToDosByUserId(@Param("userId") Long userId);
}
我在日志中看到这样一个查询
Hibernate:选择todo0\u0。id为col_0_0_从todos todo0_其中todo0_。用户标识=?]
和N个这样的查询
Hibernate:选择todo0\u0。id为id1\u 0\u 0\u,todo0\u。描述为描述2\u 0\u 0\u,todo0\u。目标日期为目标日期第3天、第0天、第0天。用户标识为用户标识4、用户标识0、用户标识1。id为id1_1_1_,user1_。密码为password2\u 1\u 1\u,user1\u。用户名为username3\u 1\u 1\u来自todos todo0\u左外部加入用户todo0\u上的user1。用户id=用户1。id todo0\u0的位置。id=?
ToDoRepr是一个简单的POJO。使用接受ToDo实体作为参数的构造函数。
下面是我在这个查询中使用的两个JPA实体
@Entity
@Table(name = "todos")
public class ToDo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String description;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@Column
private LocalDate targetDate;
// geters, setters, etc.
}
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true, nullable = false)
private String username;
@Column(nullable = false)
private String password;
@OneToMany(
mappedBy = "user",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<ToDo> todos;
// geters, setters, etc.
}
UPD。通过该查询可以解决问题,但为什么它不使用接受实体作为参数的构造函数呢?
public interface ToDoRepository extends CrudRepository<ToDo, Long> {
@Query("select new com.package.repr.ToDoRepr(t.id, t.description, t.user.username, t.targetDate) " +
"from ToDo t " +
"where t.user.id = :userId")
List<ToDoRepr> findToDosByUserId(@Param("userId") Long userId);
}
我想在这里收集一些关于这个我自己的问题的解决方法。有一个没有显式JPQL查询的简单解决方案。SpringDataJPA可以将任何具有适当getter和setter的POJO视为投影。
这对我来说很合适
public interface ToDoRepository extends CrudRepository<ToDo, Long> {
List<ToDoRepr> findToDosByUser_Id(Long userId);
}
这是一个非常常见的问题,因此我创建了一篇文章,详细介绍了解决方案
Hibernate的最佳实践是将所有关联定义为惰性,以避免在不需要时获取它。更多原因,请查看Vlad Mihalcea的文章https://vladmihalcea.com/eager-fetching-is-a-code-smell/
为了解决您的问题,在类ToDo中,您应该将manyTone定义为Lazy:
@Entity
@Table(name = "todos")
public class ToDo {
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
...
// geters, setters, etc.
}
如果您需要访问ToDoRepr中的用户,默认情况下不会加载该用户,因此您需要将其添加到查询中:
public interface ToDoRepository extends CrudRepository<ToDo, Long> {
@Query("select new com.package.repr.ToDoRepr(t) " +
"from ToDo t " +
"inner join fetch t.user " +
"where t.user.id = :userId")
List<ToDoRepr> findToDosByUserId(@Param("userId") Long userId);
}
public interface ToDoRepository extends CrudRepository<ToDo, Long> {
@EntityGraph(attributePaths = {"user"})
List<ToDoRepr> findToDosByUser_Id(Long userId);
}
问题内容: 我对Hibernate的 预测 和 标准 感到困惑。何时使用投影以及何时使用标准? 问题答案: 它们不是互斥的,您可以同时使用两者。投影通常在某些条件下使用。 简而言之,使用Hibernate Projections来仅查询要使用Criteria查询的一个实体或一组实体的属性的子集。您还可以使用预测指定条款和聚合函数一样,等等。这就像指 其 数据你抓取。就像修改SQL查询中的子句一样。
本文向大家介绍使用HTML5画布进行投影,包括了使用HTML5画布进行投影的使用技巧和注意事项,需要的朋友参考一下 HTML5 canvas提供了在图纸周围创建漂亮阴影的功能。所有绘图操作均受四个全局阴影属性影响。 序号 属性和说明 1 shadowColor [=值] 此属性返回当前阴影颜色,可以对其进行设置以更改阴影颜色。 2 shadowOffsetX [=值] 此属性返回当前阴影偏移量X,
嗨,我想写一个查询使用条件:以下查询必须使用条件创建: “从S2中选择不同的(s2Taxper),其中s2Tc='601'和s2Txcd!=”” 提前谢谢
问题内容: 您好,我想按查询排除某些字段。我正在使用nodejs 但在结果集中,我一直在获取密码字段。 问题答案: 投影不适用于新的nodejs mongodb驱动程序…相反,您将不得不在 此处使用游标方法
问题内容: 简而言之:hibernate状态不支持投影和示例查询吗?我发现了这篇文章: 代码是这样的: 就像其他张贴者所说的那样,生成的sql始终具有一个where类,仅 引用y0_ =? 而不是this_.city。 我已经尝试了几种方法,并搜索了问题跟踪器,但对此一无所获。 我什至尝试使用Projection别名和Transformers,但是它不起作用: 有没有人通过示例使用投影和查询? 问
首先,我将列出我在查询中使用的三个模型 产品实体: 合作伙伴实体: 和StockProductInfoEntity: 我想从数据库产品中获取所有股票的合作伙伴计算计数。为了方便起见,我创建了一个简单的DTO: 并在JPA存储库中编写JPQL查询: 但我的应用程序甚至没有启动,因为查询验证有问题。我收到以下消息: 原因:组织。冬眠QueryException:查询指定了联接提取,但提取的关联的所有者