Hibernate 查询1+N问题分析
发布时间:2021-11-24 17:14:21 所属栏目:PHP教程 来源:互联网
导读:1、1+N简单来说就是,Person和Phone是一对多关系,现在我看看所有手机的信息,对于其属于哪个人不感兴趣,但把lazy设为false(lazy=false),这样就会发出1(查询手机的sql)+N(和所有查询的这些手机相关的Person的查询sql),这样会造成很大的性能开销。 首先
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; Person.hbm.xml按照常规配置即可 Phone: [java] private int id; private String type; private String description; private Person person; //关联一个用户 Phone.hbm.xml: [html] <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加载 [html] <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> 2、在lazy=false的情况下,在hql中使用join fetch进行查询(session.createCriteria就是采用连接查询的方式),如: [java] @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(); } 3、对于在Person中设置batch-size应该不算是一种解决方案,对于海量的数据,设置的一些batch-size对于大体来说是无关痛痒的。 ok,这就是小弟看视频对于1+N问题的一点理解,有理解更为深刻的大虾不吝赐教。。 ![]() (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |