关于Hibernate中的FetchType.EAGER

1.先定义两个model:Question和Answer,每个Question对应多个Answer;

Question.java

package lan.study.hibernate.model;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;


@Entity
public class Question {

    private Integer id;
    private String question;
    private Set<Answer> answers;

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getQuestion() {
        return question;
    }

    public void setQuestion(String question) {
        this.question = question;
    }

    @OneToMany(mappedBy="question", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    public Set<Answer> getAnswers() {
        return answers;
    }

    public void setAnswers(Set<Answer> answers) {
        this.answers = answers;
    }

}

 

Answer.java

package lan.study.hibernate.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class Answer {

    private Integer id;
    private String answer;
    private Question question;

    @Id
    @GeneratedValue
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAnswer() {
        return answer;
    }

    public void setAnswer(String answer) {
        this.answer = answer;
    }

    @ManyToOne
    @JoinColumn(name = "question_id")
    public Question getQuestion() {
        return question;
    }

    public void setQuestion(Question question) {
        this.question = question;
    }

}

 

2.当OneToMany中加上 fetch=FetchType.EAGER时,查询时会把关联的对象全部加载到内存中,即使使用setFetchMode,也不起作用,而去掉fetch=FetchType.EAGER时,setFetchMode才起作用。

    @OneToMany(mappedBy="question", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    public Set<Answer> getAnswers() {
        return answers;
    }

3.测试代码

 

package lan.study.hibernate.model;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import lan.study.hibernate.util.HibernateUtil;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.CriteriaSpecification;
import org.junit.Test;

public class QuestionTestCase {

    @Test
    public void testSaveQuestion(){
        Question question = new Question();
        question.setQuestion("question.");
        Answer answerA = new Answer();
        answerA.setAnswer("answerA");
        answerA.setQuestion(question);
        Answer answerB = new Answer();
        answerB.setAnswer("answerB");
        answerB.setQuestion(question);
        Answer answerC = new Answer();
        answerC.setAnswer("answerC");
        answerC.setQuestion(question);
        Set<Answer> answers = new HashSet<Answer>();
        answers.add(answerA);
        answers.add(answerB);
        answers.add(answerC);
        question.setAnswers(answers);
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        session.save(question);
        session.getTransaction().commit();
        session.close();
    }
    
    @Test
    public void getQuestionByCriteria(){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        Criteria c = session.createCriteria(Question.class);
        c.setFetchMode("answers", FetchMode.JOIN);
        c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
        @SuppressWarnings("unchecked")
        List<Question> questions = c.list();
        session.getTransaction().commit();
        System.out.println(questions.size());
        for (Question question : questions) {
            for(Answer answer : question.getAnswers()){
                System.out.println(answer.getAnswer());
            }
        }
    }
    
    @Test
    public void getQuestionByHQL(){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        String hql = "select distinct(q) from Question q inner join fetch q.answers where q.id=1";
        Query q = session.createQuery(hql);
        @SuppressWarnings("unchecked")
        List<Question> questions = q.list();
        session.getTransaction().commit();
        System.out.println(questions.size());
        for (Question question : questions) {
            for(Answer answer : question.getAnswers()){
                System.out.println(answer.getAnswer());
            }
        }
    }
    
}

 

  HibernateUtil.java

package lan.study.hibernate.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            return  new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FetchType.LAZY是Hibernate的一种加载策略。当使用懒加载策略时,加载一个实体时,定义为懒加载的属性并不会立即从数据库加载,而是在需要访问这些属性时才会去数据库查询加载。 这种策略的好处是可以减少不必要的数据库查询,提高性能。比如在一个用户类,用户的地址属性在大多数情况下并不需要立即显示出来,只有在需要查看用户资料时才会去查询数据库加载地址信息。而用户名属性则需要在用户登录时立即显示出来,因此需要使用急加载策略。 在Hibernate,可以通过在实体类的属性上使用注解来设置延迟检索策略。例如,可以使用@OneToMany注解来设置一对多关系的延迟加载策略。通过设置fetch属性为FetchType.LAZY,可以显式地指定该属性的延迟加载策略。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [hibernate fetch=FetchType.LAZY 懒加载失败处理方法](https://download.csdn.net/download/weixin_38682242/12771863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [HibernateFetchType.LAZY和FetchType.EAGER什么区别?](https://blog.csdn.net/B_evan/article/details/53868520)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [孙卫琴的《精通JPA与Hibernate》的读书笔记:FetchType.LAZY延迟检索策略](https://blog.csdn.net/csdnuserlala/article/details/116403315)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值