Hibernate 查询1+N问题详解
Hibernate 查询1+N问题详解
1、1+N简单来说就是,Person和Phone是一对多关系,现在我看看所有手机的信息,对于其属于哪个人不感兴趣,但把lazy设为false(lazy=false),这样就会发出1(查询手机的sql)+N(和所有查询的这些手机相关的Person的查询sql),这样会造成很大的性能开销。
首先列一下会产生1+N问题的代码
Person:
[java]- private int id;
- private String name;
- private int age;
Phone:
[java]- private int id;
- private String type;
- private String description;
- private Person person; //关联一个用户
- <hibernate-mapping>
- <class name="com.akwolf.n_1.Phone" table="PHONE">
- <id name="id" type="int">
- <column name="ID" />
- <generator class="native" />
- </id>
- <property name="type" type="java.lang.String">
- <column name="TYPE" />
- </property>
- <property name="description" type="java.lang.String">
- <column name="DESCRIPTION" />
- </property>
- <!-- lazy=false -->
- <many-to-one name="person" class="com.akwolf.n_1.Person" fetch="join" lazy="false">
- <column name="PERSON_ID" />
- </many-to-one>
- </class>
- </hibernate-mapping>
为了使效果明显一点,假定一个手机对应一个不同的用户,现在想数据库中添加一些数据:
[java]
- @Test
- public void testSave1() {
- Session session = HibernateUtil.getSessionFactory().getCurrentSession();
- session.beginTransaction();
- Person person;
- Phone phone;
- for (int i = 0; i < 10; i++) {
- person = new Person(0, "zhangsan" + i, 21 + i);
- phone = new Phone(0, "glay" + i, "Android智能手机", person);
- session.save(person);
- session.save(phone);
- }
- session.getTransaction().commit();
- }
进行一下下面的查询会看到,控制台输出大量的sql [java]
- @Test
- public void testQuery1() {
- Session session = HibernateUtil.getSessionFactory().getCurrentSession();
- session.beginTransaction();
- List<Phone> list = (List<Phone>) session.createQuery("from Phone")
- .list();
- for (Phone phone : list) {
- System.out.println(phone.getId()); //对关联的Person并不感兴趣
- // System.out.println(phone.getId()+"---"+phone.getPerson().getName());
- }
- session.getTransaction().commit();
- }
解决方案
1、还是在Phone.hbm.xml中把对于Person关联的映射属性不进行lazy属性的设置,默认为lazy加载
- <hibernate-mapping>
- <class name="com.akwolf.n_1.Phone" table="PHONE">
- <id name="id" type="int">
- <column name="ID" />
- <generator class="native" />
- </id>
- <property name="type" type="java.lang.String">
- <column name="TYPE" />
- </property>
- <property name="description" type="java.lang.String">
- <column name="DESCRIPTION" />
- </property>
- <!-- lazy=true -->
- <many-to-one name="person" class="com.akwolf.n_1.Person" fetch="join">
- <column name="PERSON_ID" />
- </many-to-one>
- </class>
- </hibernate-mapping>
- @Test
- public void testQuery2() {
- Session session = HibernateUtil.getSessionFactory().getCurrentSession();
- session.beginTransaction();
- List<Phone> list = (List<Phone>) session.createQuery(
- "from Phone p left join fetch p.person per").list();
- for (Phone phone : list) {
- // System.out.println(phone.getId());
- System.out.println(phone.getId() + "---"
- + phone.getPerson().getName());
- }
- session.getTransaction().commit();
- }
ok,这就是小弟看视频对于1+N问题的一点理解,有理解更为深刻的大虾不吝赐教。。
评论暂时关闭