浏览 2433 次
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-05-22
批量加载分为延迟加载和立即加载,先说立即加在 首先建立测试数据库 CREATE TABLE certificate ( id varchar(100) NOT NULL default '', description varchar(100) default '', PRIMARY KEY (id) ); CREATE TABLE student ( team_id varchar(100) default '', id varchar(100) NOT NULL default '', name varchar(20) default '', cardId varchar(20) NOT NULL default '', age int(11) default '0', PRIMARY KEY (id) ); CREATE TABLE team ( id varchar(100) NOT NULL default '', teamName varchar(100) default '', PRIMARY KEY (id) ); INSERT INTO student VALUES ('5','1','spark','200211332',13), ('4','2','jerry','200233332',23), ('3','3','adidas','200231332',33), ('2','4','zhouxingchi','200231132',43), ('1','5','tomclus','200512345',53), ('1','6','tom','200511345',63); INSERT INTO team VALUES ('5','team5'), ('4','team4'), ('3','team3'), ('2','team2'), ('1','team1'); INSERT INTO certificate VALUES ('1','card1'), ('2','card2'), ('3','card3'), ('4','card4'), ('5','card5'), ('6','card6'); 建立POJO对象 package Search.immediately; public class Certificate ............{ private String id; private String description; private Student stu; public Student getStu() ............{ return stu; } public void setStu(Student stu) ............{ this.stu = stu; } public String getDescription() ............{ return description; } public void setDescription(String description) ............{ this.description = description; } public String getId() ............{ return id; } public void setId(String id) ............{ this.id = id; } } package Search.immediately; import java.util.HashSet; import java.util.Set; public class Team ............{ private String id; private Set students=new HashSet(); private String teamName; private Set tests; public Set getTests() ............{ return tests; } public void setTests(Set tests) ............{ this.tests = tests; } public String getId() ............{ return id; } public void setId(String id) ............{ this.id = id; } public String getTeamName() ............{ return teamName; } public void setTeamName(String name) ............{ this.teamName = name; } public Set getStudents() ............{ return students; } public void setStudents(Set students) ............{ this.students = students; } } package Search.immediately; public class Certificate ............{ private String id; private String description; private Student stu; public Student getStu() ............{ return stu; } public void setStu(Student stu) ............{ this.stu = stu; } public String getDescription() ............{ return description; } public void setDescription(String description) ............{ this.description = description; } public String getId() ............{ return id; } public void setId(String id) ............{ this.id = id; } } HBM文件 student.hbm.xml <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse - Hibernate Tools --> <hibernate-mapping package="Search.batch.immediately" > <class name="Student" table="student" lazy="false"> <id name="id" column="id" unsaved-value="null"> <generator class="uuid.hex"></generator> </id> <property name="cardId" column="cardId"></property> <property name="name" column="name"></property> <property name="age" column="age"></property> <!--为了设置student-certificate的延迟1对1,设置class的lazy="no-proxy"--> <one-to-one name="cer" class="Search.batch.immediately.Certificate" constrained="true" lazy="no-proxy" outer-join="false" cascade="all"> </one-to-one> <many-to-one name="team" column="team_id" outer-join="false" class="Search.batch.immediately.Team"></many-to-one> </class> </hibernate-mapping> Certificate.hbm.xml <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse - Hibernate Tools --> <hibernate-mapping package="Search.batch.immediately" > <!--为了设置student-certificate的延迟1对1,设置class的lazy="true"--> <class name="Certificate" table="certificate" lazy="true"> <id name="id" column="id"> <generator class="foreign"> <param name="property">stu</param> </generator> </id> <property name="description" column="description"></property> <one-to-one name="stu" class="Search.batch.immediately.Student" outer-join="false" constrained="true"> </one-to-one> </class> </hibernate-mapping> Team.hbm.xml <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse - Hibernate Tools --> <hibernate-mapping package="Search.batch.immediately" > <class name="Team" table="team" lazy="false"> <id name="id" column="id"> <generator class="uuid.hex"></generator> </id> <property name="teamName" column="teamName"></property> <!--需要批量加载,设置batch-size="2"--> <set name="students" lazy="false" inverse="true" outer-join="false" > <key column="team_id"></key> <one-to-many class="Search.batch.immediately.Student"/> </set> </class> </hibernate-mapping> 测试代码: package Search.batch.immediately; import java.io.File; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Test ...{ public static void main(String[] args) ...{ Team team=null; String filePath=System.getProperty("user.dir")+File.separator+"src/Search/batch/immediately"+File.separator+"hibernate.cfg.xml"; File file=new File(filePath); SessionFactory sessionFactory=new Configuration().configure(file).buildSessionFactory(); Session session=sessionFactory.openSession(); Query query=session.createQuery("from Team t"); List resultList=query.list(); } 运行,结果如下: Hibernate: select team0_.id as id2_, team0_.teamName as teamName2_ from team team0_ Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id= Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id=? Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id=? Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id=? Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id=? 有5条查询student的SQL(本身有6个学生,但有两个学生属于一个team) 可以看到,这是典型的立即加在,取得team对象后,把team所包含的student取出,如果有100个学生,则会执行100个SQL,这是很没有效率的 我们修改Team的hbm文件,为其配置批量加载student的配置(1对多在set标签上配置,多对1在class标签上配置) <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse - Hibernate Tools --> <hibernate-mapping package="Search.batch.immediately" > <class name="Team" table="team" lazy="false"> <id name="id" column="id"> <generator class="uuid.hex"></generator> </id> <property name="teamName" column="teamName"></property> <!--需要批量加载,设置batch-size="2"--> <set name="students" lazy="false" inverse="true" outer-join="false" batch-size="2" > <key column="team_id"></key> <one-to-many class="Search.batch.immediately.Student"/> </set> </class> </hibernate-mapping> 再次运行测试程序,结果如下: Hibernate: select team0_.id as id2_, team0_.teamName as teamName2_ from team team0_ Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id in (?, ?) Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id in (?, ?) Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id=? 可以看到,查询student只用了3条SQL(5/batch-size+1=3), 如果team对student是延迟加载的,会使什么效果呢,会是这样,我们加载team1时候,由于batch-size=2,所以加载team1就同时批量加载了team2,同理,加载team3时候也就加载了team4,最后再加载team5, 而这些数据都已经在hibernate session的缓存中了 修改team.hbm.xml 配置好lazy="true" <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse - Hibernate Tools --> <hibernate-mapping package="Search.batch.immediately" > <class name="Team" table="team" lazy="false"> <id name="id" column="id"> <generator class="uuid.hex"></generator> </id> <property name="teamName" column="teamName"></property> <!--需要批量加载,设置batch-size="2"--> <set name="students" lazy="true" inverse="true" outer-join="false" batch-size="2" > <key column="team_id"></key> <one-to-many class="Search.batch.immediately.Student"/> </set> </class> </hibernate-mapping> 运行测试程序,结果如下: Hibernate: select team0_.id as id2_, team0_.teamName as teamName2_ from team team0_ Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id in (?, ?) team1:2 team2:1 Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id in (?, ?) team3:1 team4:1 Hibernate: select students0_.team_id as team5_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.cardId as cardId1_0_, students0_.name as name1_0_, students0_.age as age1_0_, students0_.team_id as team5_1_0_ from student students0_ where students0_.team_id=? team5:1 其中可以砍到team2和team4的数据是批量加载来的,已经保存在缓存中,所以读取其students集合对象是,虽然是延迟加载,但不再会去发送SQ查询,而是再缓冲中查询 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-05-22
建议把代码排版一下阿..不然看得头晕.
嘿嘿 |
|
返回顶楼 | |
发表时间:2008-07-12
这么多代码
MY GOD |
|
返回顶楼 | |