【问题标题】:When use a JoinType in Criteria ? Hibernate mapping何时在 Criteria 中使用 JoinType ?休眠映射
【发布时间】:2018-03-29 12:38:27
【问题描述】:

我对何时将连接与标准一起使用有点困惑。我在说什么的例子:

.createAlias("cars", "c", JoinType.LEFT_OUTER_JOIN)

以下是不同的 JoinType:

LEFT_OUTER_JOIN
INNER_JOIN
LEFT_OUTER_JOIN
NONE
RIGHT_OUTER_JOIN

当我们用 Hibernate 映射实体时,已经自动有了一个“JoinType”(那是一个 INNER_JOIN 吗?)。

带有用户的简单示例 - 汽车:

用户类(表名USERS)

class User {
   @Id
   @Column(name="ID_USER")
   private int idUser;

   @Column(name="NAME")
   private String name;

   @OneToMany
   @JoinColumn(name="ID_USER")
   private Set<Car> cars;
}

和汽车类(表名CARS):

class Car{
   @Id
   @Column(name="ID_CAR")
   private int idCar;

   @Column(name="MODEL)
   private String model;

   @Column(name="ID_USER")
   private int idUser;
}

如果我有一个用户 u 并且我输入 u.getCars() 默认映射哪个 Join ?

如果我想要以下结果:

SELECT * FROM Users u LEFT JOIN Cars c on u.id_user = c.id_user

那么使用它是否正确:

Criteria c = getSession().createCriteria(User.class);
c.createAlias("cars", "c", JoinType.LEFT_OUTER_JOIN);
return c.list();

(然后我在 User 和 Car 上循环搜索我要查找的内容)。

如果我正在寻找那个:

SELECT * FROM Users u INNER JOIN Cars c on u.id_user = c.id_user

我是否正确地说我不需要创建 JoinType.INNER_JOIN ? 如果我是,当我已经拥有地图实体时,JoinType.INNER_JOIN 就没用了吗?

我必须使用大量的连接来映射很多复杂的表,我有点糊涂了!

【问题讨论】:

    标签: java hibernate join criteria


    【解决方案1】:

    当我们用 Hibernate 映射实体时,已经自动有了一个“JoinType”(那是一个 INNER_JOIN 吗?)。

    假设您已将oneToMany 关联标记为Fetch.EAGER。在这种情况下,当您通过hibernate criteria 加载User 对象时,它默认使用LEFT OUTER JOIN,除非您在Criteria 中覆盖它。如果您没有将其标记为FetchType.EAGER,它将是惰性的,因此默认情况下不会加入,除非您在Criteria 中覆盖它。

    如果我有一个用户 u 并且我输入 u.getCars() 默认映射哪个 Join ?

    有关 EAGER 加载,请参阅上文。如果懒惰并且它在您调用 u.getCars 的同一会话中,它将触发一个新的 SELECT 以根据 userId 加载汽车,因此不加入。

    我是否正确地说我不需要创建 JoinType.INNER_JOIN ?如果我是,当我已经拥有地图实体时,JoinType.INNER_JOIN 就没用了吗?

    参考上面,如果它是 EAGER 则默认为 LEFT OUTER JOIN,除非在 Criteria 中被覆盖。

    根据建议,-最好通过enable show_sql property 使用不同的FetchTypesCriteria JOIN Types 查看休眠实际上在后台触发的SQL,因为根据您的实体映射,SQL 的计数/复杂性查询可能不同。

    【讨论】:

    • 现在不那么困惑了,谢谢!如果这是一个懒惰的获取,我调用 u.getCars();也不是左外连接吗?
    • 如果关联是 LAZY,默认为 NO JOIN。所以,你用 LAZY 打电话给u.getCars,它会触发new SELECT to load cars based on the userId,所以没有加入。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 2011-06-11
    相关资源
    最近更新 更多