我们在做数据库操作的时候存在这样的一个场景:我们涉及到的表太多了,访问的数据量过大,就会发现有时候很慢,甚至报错,但是hibernate很好的解决了这个问题--懒加载机制。
总结:
hibernate3是支持懒加载的,在发出load命令的时候,我们发现:他并不会发出查询指令,而是返回代理对象,当真正需要查询的时候通过代理对象去查询。
懒加载需要注意的是:
1 实体类不能是final的
2 能实现懒加载的对象都是被CGLIB(反射调用)改写的代理对象,所以不能是final修饰的
3 须要asm,cglib两个jar包
4 相应的lazy属性为true
5 相应的fetch属性为select
能够实现懒加载的关联机制:
(1)one-to-one
这里有三种情况,分别是:唯一主键、单向一对一和双向一对一:
唯一主键:person.hbm.xml文件代码:
<span style="font-size:14px;"><hibernate-mapping>
<class name="com.test.hibernate.Person" table="tb_person">
<id name="id">
<generator class="foreign">
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<one-to-one name="idCard" constrained="true"/>
</class>
</hibernate-mapping> </span>
单元测试类:
<span style="font-size:14px;">public void testSave1(){
Session session = null;
Transaction tx = null;
try{
session= hibernateUntils.getSession();
/*返回一个事务实例*/
tx=session.beginTransaction();
IdCard idcard= new IdCard();
idcard.setCardNo("130629199202050387");
Person person=new Person();
person.setName("张三");
/*建立关联*/
person.setIdCard(idcard);
//这里是需要注意的,我们只需要保存person,就能把idcard保存进去,并且能够查到
session.save(person);
/*提交事务的时候会清理缓存*/
tx.commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null)
{
tx.rollback();
}
}finally{
hibernateUntils.closeSession(session);
}
//detached状态
}</span>
单向一对一:只能用person 找到idCard:
xml文件代码:这属于多对一的一个特例:
<span style="font-size:14px;"><hibernate-mapping>
<class name="com.test.hibernate.Person" table="tb_person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="idCard" unique="true"/>
</class>
</hibernate-mapping> </span>
单元测试类:
<span style="font-size:14px;">public void testSave1(){
Session session = null;
Transaction tx = null;
try{
session= hibernateUntils.getSession();
/*返回一个事务实例*/
tx=session.beginTransaction();
IdCard idcard= new IdCard();
idcard.setCardNo("130629199202050387");
Person person=new Person();
person.setName("张三");
/*建立关联*/
person.setIdCard(idcard);
//这里需要注意,单项一对一中,两个实体都必须保存,否则事务会回滚
session.save(idcard);
session.save(person);
/*提交事务的时候会清理缓存*/
tx.commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null)
{
tx.rollback();
}
}finally{
hibernateUntils.closeSession(session);
}
//detached状态
}</span>
双向一对一:在单项一对一的基础上,还需要在另一个实体的映射文件进行添加一对一标签,并且在实体类中也需要加入这个字段
<span style="font-size:14px;"><hibernate-mapping>
<class name="com.test.hibernate.IdCard" table="tb_idcard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
//加入一对一标签才能够找到idcard类
<one-to-one name="person" property-ref="idCard"></one-to-one>
</class>
</hibernate-mapping></span>
单元测试类:
<span style="font-size:14px;">public void testSave1(){
Session session = null;
Transaction tx = null;
try{
session= hibernateUntils.getSession();
/*返回一个事务实例*/
tx=session.beginTransaction();
IdCard idcard= new IdCard();
idcard.setCardNo("12345678912");
Person person=new Person();
person.setName("张三");
/*建立关联*/
person.setIdCard(idcard);
//这里和唯一主键的写法是一样的,我们只需要我们加标签的实体,那么关联的另一个实体也会持久化到数据库
session.save(idcard);
/*提交事务的时候会清理缓存*/tx.commit();}catch(Exception e){e.printStackTrace();if(tx != null){tx.rollback();}}finally{hibernateUntils.closeSession(session);}//detached状态}
(2)one-to-many
XML 文件代码:
<span style="font-size:14px;"><hibernate-mapping>
<class name="com.test.hibernate.Classes" table="tb_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students">
<key column="classesid"/>
<one-to-many class="com.test.hibernate.Student"/>
</set>
</class>
</hibernate-mapping></span>
(3)many-to-one
XML文件代码(ps:单向一对一映射是多对一的一个特例 ):
<span style="font-size:14px;"><hibernate-mapping>
<class name="com.test.hibernate.User" table="tb_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="group" column="groupId"></many-to-one>
</class>
</hibernate-mapping></span>
以上机制的查询类:
<span style="font-size:14px;">public void testLoad1(){
Session session = null;
try{
session= hibernateUntils.getSession();
session.beginTransaction();
User user=(User)session.load(User.class, "402895b3530c13cd01530c1539170001");
session.delete(user);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
hibernateUntils.closeSession(session);
}
}</span>
总结:
今天小编从懒加载到hibernate为我们提供的各种实体之间关系维护的方式,这些都是为了我们程序更好的运行,当数据量偏大的时候会出现各种问题,但是这中懒加载机制正好为我们规避了这些问题,所以了解这些对我么的开发很有好处!