CodeGym/Java 课程/All lectures for ZH purposes/映射集合时的延迟加载

映射集合时的延迟加载

可用

2.1 获取选项

Hibernate 的开发人员很早就知道加载子实体的问题。所以他们做的第一件事就是在注释中添加一个特殊的提取@OneToMany参数,@ManyToMany

该参数可以取两个值:

  • 渴望的
  • 懒惰的

例子:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")

如果fetch 参数等于 EAGER,那么当加载父实体时,它的所有子实体也将被加载。此外,Hibernate 将尝试在一个 SQL 查询中执行此操作,生成大量查询并一次获取所有数据。

如果fetch 参数取值为 LAZY,那么在加载父实体时,不会加载子实体。相反,将创建一个代理对象。

借助这个代理对象,Hibernate 会跟踪对这个子实体的访问,并在第一次访问时将其加载到内存中。

如果我们回顾我们的情况并发表评论:

@Entity
@Table(name="user")
class User {
   @Column(name="id")
   public Integer id;

   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   @JoinColumn(name = "user_id")
   public List<Comment> comments;
}

然后你有一个“别致的选择”:

如果fetch = FetchType.EAGER,那么 Hibernate 将在第一行代码加载所有注释:

User user = session.get(User.class, 1);		//load all comments here
List<Comment> comments = user.getComments();

如果fetch = FetchType.LAZY,那么 Hibernate 将在第 2 行代码加载所有注释:

User user = session.get(User.class, 1);
List<Comment> comments = user.getComments(); //load all comments here

正如您已经猜到的那样,当它没有加载所有评论时,您别无选择 :)

2.2 默认值

如果您没有为@ManyTo... 注释指定提取选项,那么 Hibernate 将使用默认值。

对于不同的注释类型,它们略有不同。对于注解@OneToOne@ManyToOneEAGER,对于注解@OneToMany@ManyToManyLAZY。很容易记住——如果我们引用一个对象,那么它将被完全加载。如果我们引用一个集合,那么它将在第一次访问时加载。

2.3 @LazyCollection注解

正如您已经看到的,fetch 参数在处理集合时没有多大帮助。Hibernate 的创建者试图通过添加一个特殊的注解来解决这个问题@LazyCollection。通常是这样写的:

@LazyCollection(LazyCollectionOption.TRUE)

映射集合字段时需要指定:

@Entity
@Table(name="user")
class User {
   @Column(name="id")
   public Integer id;

   @OneToMany(cascade = CascadeType.ALL)
   @LazyCollection(LazyCollectionOption.TRUE)
   public List<Comment> comments;
}

此注解有一个值参数,可以采用以下三个值之一:

  • 惰性集合选项。真的
  • 惰性集合选项。错误的
  • 惰性集合选项。额外的

前两个选项与 fetch 选项非常相似。

如果参数设置为LazyCollectionOption.TRUE,则表示在加载父User对象时,不会从数据库中加载comments字段的值。Comment 类型的对象将在第一次访问 comments 字段时加载。其实这个相当于参数FetchType.LAZY

如果参数设置为LazyCollectionOption.FALSE,则表示comments字段的值在加载父User对象时从数据库中加载。Comment 类型的对象将在第一次访问 comments 字段时加载。事实上,这相当于FetchType.EAGER.

评论
  • 受欢迎
你必须先登录才能发表评论
此页面还没有任何评论