N+1问题,
many-to-oneHibenrate,懒加载的意思,加载一个实体时,定义懒加载的属性不会马上从数据库中加载。只有我们需要的时候,,比如group.getPersons().size()Hibernate检测你需要之后,才会发SQL请求!
ok,上面说了1+N问题出现的原理,那下面用程序来证明:
@Entity@Table(name=”t_group”)publicclassGroup{privateIntegerid;privateStringname;privateSet<Person>persons=newHashSet<Person>();@OneToManypublicSet<Person>getPersons(){returnpersons;}publicvoidsetPersons(Set<Person>persons){this.persons=persons;}@Id@GeneratedValuepublicIntegergetId(){returnid;}publicvoidsetId(Integerid){this.id=id;}@Column(name=”g_name”)publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}}@Entity@Table(name=”p_person”)publicclassPerson{privateIntegerid;privateStringname;privateIntegerage;privateGroupgroup;@ManyToOne@JoinColumn(name=”group_id”)publicGroupgetGroup(){returngroup;}publicvoidsetGroup(Groupgroup){this.group=group;}@Id@GeneratedValuepublicIntegergetId(){returnid;}publicvoidsetId(Integerid){this.id=id;}@Column(name=”p_name”)publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}@Column(name=”p_age”)publicIntegergetAge(){returnage;}publicvoidsetAge(Integerage){this.age=age;}}
现在我们查询Person,看它发送的SQL语句
//我们发现,在查询Person的时候,发送的SQL语句@TestpublicvoidfindTest1(){Sessions=sessionFactory.getCurrentSession();s.beginTransaction();List<Person>persons=s.createQuery(“fromPerson”).list();for(Personperson:persons){System.out.println(person.getName()+”—-“+person.getId());}s.getTransaction().commit();}
查看SQL语句
(除了第一条是查询Person的语句,后面10条都是查询Group的语句)
11:02:13,036DEBUGSQL:111-selectperson0_.idasid1_,person0_.p_ageasp2_1_,person0_.group_idasgroup4_1_,person0_.p_nameasp3_1_fromp_personperson0_11:02:13,078DEBUGSQL:111-selectgroup0_.idasid0_0_,group0_.g_nameasg2_0_0_fromt_groupgroup0_wheregroup0_.id=?11:02:13,096DEBUGSQL:111-selectgroup0_.idasid0_0_,group0_.g_nameasg2_0_0_fromt_groupgroup0_wheregroup0_.id=?11:02:13,100DEBUGSQL:111-selectgroup0_.idasid0_0_,group0_.g_nameasg2_0_0_fromt_groupgroup0_wheregroup0_.id=?11:02:13,102DEBUGSQL:111-selectgroup0_.idasid0_0_,group0_.g_nameasg2_0_0_fromt_groupgroup0_wheregroup0_.id=?11:02:13,103DEBUGSQL:111-selectgroup0_.idasid0_0_,group0_.g_nameasg2_0_0_fromt_groupgroup0_wheregroup0_.id=?11:02:13,105DEBUGSQL:111-selectgroup0_.idasid0_0_,group0_.g_nameasg2_0_0_fromt_groupgroup0_wheregroup0_.id=?11:02:13,107DEBUGSQL:111-selectgroup0_.idasid0_0_,group0_.g_nameasg2_0_0_fromt_groupgroup0_wheregroup0_.id=?11:02:13,110DEBUGSQL:111-selectgroup0_.idasid0_0_,group0_.g_nameasg2_0_0_fromt_groupgroup0_wheregroup0_.id=?11:02:13,113DEBUGSQL:111-selectgroup0_.idasid0_0_,group0_.g_nameasg2_0_0_fromt_groupgroup0_wheregroup0_.id=?11:02:13,115DEBUGSQL:111-selectgroup0_.idasid0_0_,group0_.g_nameasg2_0_0_fromt_groupgroup0_wheregroup0_.id=?张三0—-1张三1—-2张三2—-3张三3—-4张三4—-5张三5—-6张三6—-7张三7—-8张三8—-9张三9—-10
这里我只需要查询的是Person的信息,只需要一条SQL语句就够了,但是现在多发了10条查询Group的语句,所以在这里我称之1+N问题。OK?
自信是一个人的胆,有了这个胆,你就会所向披靡!