Hibernate_抓取策略_Annotation
2016-05-22 17:35
375 查看
package org.com.test.model; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; @Entity @Table(name="t_special") public class Special { private int id; private String name; private String type; private Set<Classroom> classrooms; public String getType() { return type; } public void setType(String type) { this.type = type; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @OneToMany(mappedBy="special") @LazyCollection(LazyCollectionOption.EXTRA) public Set<Classroom> getClassrooms() { return classrooms; } public void setClassrooms(Set<Classroom> classrooms) { this.classrooms = classrooms; } }
package org.com.test.model; import java.util.Set; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; import org.hibernate.annotations.BatchSize; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; @Entity @Table(name="t_classroom") @BatchSize(size=20) public class Classroom { private int id; private String name; private int grade; private Set<Student> students; private Special special; public int getGrade() { return grade; } public void setGrade(int grade) { this.grade = grade; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @OneToMany(mappedBy="classroom")//给Student中的属性classroom维护关系 @LazyCollection(LazyCollectionOption.EXTRA)//用Classroom查询收集学生的时候,默认EXTRA(自动关联);使收集Student时有延迟加载 @Fetch(FetchMode.SUBSELECT)//使收集Student时,使用关联子查询;让查询每个班的学生的时候不用每个班都发一条sql public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } @ManyToOne(fetch=FetchType.LAZY)//默认是EAGER自动关联到Special,使用LAZY可以恢复延迟加载 @JoinColumn(name="s_id")//Special在Classroom的表的列名 public Special getSpecial() { return special; } public void setSpecial(Special special) { this.special = special; } }
package org.com.test.model; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name="t_student") public class Student { private int id; private String name; private String sex; private Classroom classroom; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="c_id") public Classroom getClassroom() { return classroom; } public void setClassroom(Classroom classroom) { this.classroom = classroom; } }
package org.com.test.test; import java.util.List; import org.com.test.model.Classroom; import org.com.test.model.Student; import org.com.test.util.HibernateUtil; import org.hibernate.Session; import org.junit.Test; /** * * @author asus_n56 基于Annotation配置的Demo * */ public class TestFetch { @Test public void test01(){ Session session = null; try { /** * 对于Annotation的配置而言,默认就是基于join的抓取的,所以只会发一条sql. */ session = HibernateUtil.getSession(); session.beginTransaction(); Student s = (Student)session.load(Student.class, 1); System.out.println(s.getName()+":"+s.getClassroom().getName()+":"+s.getClassroom().getSpecial().getName()); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtil.closeSession(session); } } @SuppressWarnings("unchecked") @Test public void test02(){ Session session = null; try { /** * 对于Annotation的配置没有延迟加载,此时会把所有的关联对象查询上来,发大量的sql语句 * 解决办法是:在Student的@ManyToOne(fetch=FetchType.LAZY)中这么设置;但是这样子,test01就发两条sql了。 */ session = HibernateUtil.getSession(); session.beginTransaction(); List<Student> stus = session.createQuery("from Student").list(); for (Student stu : stus) { //System.out.println(stu.getName()); System.out.println(stu.getName()+";"+stu.getClassroom());//这个查询每个班都发一条sql } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtil.closeSession(session); } } @SuppressWarnings("unchecked") @Test public void test03(){ Session session = null; try { /** * 在xml中配置的fetch=join仅仅是对load的对象有用,对HQL查询的对象没有用。所以会发出查询班级的sql。 * 解决这种问题有两种方案:一种是设置对象的抓取的batch-size * 另一种方案:在HQL中使用fetch来指定抓取 */ session = HibernateUtil.getSession(); session.beginTransaction(); List<Student> stus = session.createQuery("from Student").list(); for (Student stu : stus) { //System.out.println(stu.getName()); System.out.println(stu.getName()+";"+stu.getClassroom()); } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtil.closeSession(session); } } @SuppressWarnings("unchecked") @Test public void test04(){ Session session = null; try { /** * 在xml中配置的fetch=join仅仅是对load的对象有用,对HQL查询的对象没有用。所以会发出查询班级的sql。 * 解决这种问题有两种方案:一种是设置对象的抓取的batch-size * 另一种方案:在HQL中使用fetch来指定抓取 * 特别注意:使用了join fetch 就不能使用count(*) * * 基于Annotation由于默认的many to one 的抓取策略是EAGER的,所以在抓取classroom的时候会自动去抓取special * 会发出大量的sql。此时可以继续发join fetch继续对关联的抓取; * 或者直接将关联对象的fetch设置为lazy,但是使用lazy所带来的问题是在查询关联对象的时候会发出想用sql,影响效率 */ session = HibernateUtil.getSession(); session.beginTransaction(); List<Student> stus = session.createQuery("select stu from Student stu " + "join fetch stu.classroom cla join fetch cla.special").list(); for (Student stu : stus) { System.out.println(stu.getName()+";"+stu.getClassroom()); } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtil.closeSession(session); } } /* * ************************************************基于1的一方查询************************************************** */ @SuppressWarnings("unchecked") @Test public void test05(){ Session session = null; try { /** * 对于通过HQL取班级列表并且获取相应的学生列表时,fecth=join就无效了 * 第一种方案可以设置set的batch-size来完成批量的抓取 * 第二中方案可以设置fetch=subselect,使用subselect会完成根据查询出来的班级进行一次对学生对象的子查询 * @OneToMany(mappedBy="classroom") * @LazyCollection(LazyCollectionOption.EXTRA) * @Fetch(FetchMode.SUBSELECT) * public Set<Student> getStudents() { * return students; * } */ session = HibernateUtil.getSession(); session.beginTransaction(); List<Classroom> clas = session.createQuery("from Classroom").list(); for (Classroom cla : clas) { System.out.println(cla.getName()); for (Student stu : cla.getStudents()) { System.out.println(stu.getName()); } } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtil.closeSession(session); } } }
相关文章推荐
- Hibernate Oracle sequence的使用技巧
- jsp Hibernate批量更新和批量删除处理代码
- jsp hibernate的分页代码第1/3页
- Struts2+Hibernate实现数据分页的方法
- Hibernate环境搭建与配置方法(Hello world配置文件版)
- JAVA+Hibernate 无限级分类
- SSH整合中 hibernate托管给Spring得到SessionFactory
- jsp hibernate 数据保存操作的原理
- hibernate中的增删改查实现代码
- 解决hibernate+mysql写入数据库乱码
- java优化hibernate性能的几点建议
- java Hibernate延迟加载
- hibernate 常用方法介绍
- 详解Java的Hibernate框架中的注解与缓存
- 浅析Java的Hibernate框架中的继承关系设计
- Hibernate实现批量添加数据的方法
- JQuery+Ajax+Struts2+Hibernate框架整合实现完整的登录注册
- 深入理解Hibernate中的flush机制
- 简要分析Java的Hibernate框架中的自定义类型
- 简单的手工hibernate程序示例