欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hibernate

程序员文章站 2022-05-24 08:42:02
...
person 类:
package com.jianchen;
public class Person {
private int id;
private String name;
private IdCard idcard;
public int getId() {
        return id;
}
public void setId(int id) {
        this.id = id;
}
public String getName() {
        return name;
}
public void setName(String name) {
        this.name = name;
}
public IdCard getIdcard() {
        return idcard;
}
public void setIdcard(IdCard idcard) {
        this.idcard = idcard;
}
}


IdCard 类:
package com.jianchen;

public class IdCard {
private int id;
private String cardno;
public int getId() {
        return id;
}
public void setId(int id) {
        this.id = id;
}
public String getCardno() {
        return cardno;
}
public void setCardno(String cardno) {
        this.cardno = cardno;
}
}

Person.hbm.xml文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
        <class name="com.jianchen.Person" table="t_person"  >
                <id name="id">
                        <generator class="foreign" >
                        <param name="property">idcard</param>
                        </generator>
                        
                </id>
                <property name="name" length="10" />
                <one-to-one name="idcard" constrained="true"></one-to-one>
        </class>
</hibernate-mapping>
 
IdCard.hbm.xml文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
        <class name="com.jianchen.IdCard" table="t_idcard"  >
                <id name="id">
                        <generator class="native" />
                </id>
                <property name="cardno" length="10" />
        </class>
</hibernate-mapping>
测试代码:
        public void testPerson(){
                Session session = null;
                try{
                        session = HibernateUtils.getSession();
                        session.beginTransaction();
                        IdCard idcard = new IdCard();
                        idcard.setCardno("dffdf");
                        Person person = new Person();
                        person.setName("张三");
                        //在两个对象之间建立关联。
                        person.setIdcard(idcard);
                        
                        //在一对一关联映射中,存储Person对象时,其关联对象idcard也别存储
                        //而不会抛出TransientObjectException异常,因为它默认了级联属性。
                        session.save(person);
                        session.getTransaction().commit();
                }catch(Exception e){
                        e.printStackTrace();
                        session.getTransaction().rollback();
                }finally{
                        HibernateUtils.closeSession(session);
                }
                注:<one-to-one   constrained="true">是用来实现主键关联
    <many-to-one>是用来实现外键关联
其中<many-to-one unique="true">有一个属性倘若赋值为true则成为唯一外键关联。

hibernate内置的主键生成策略

数据库提供的主键生成机制:identity,sequence(序列)
外部程序提供的主键生成机制.increment(递增),hilo(高低位),seqhilo(使用序列的高低位),uuid.hex
(使用了ip地址+jvm的启动时间(精确到1/4秒)+系统时间+一个计数器值(在jvm中唯一)),uuid.string
其他:native(本地),assigned(手工指定),foreign(外部引用)

映射的实质就是把内存中对象之间的引用转换为数据库中的关系。
many-to-one就是外键引用。

一对一:

主键关联映射
唯一外键关联映射
在一对一主键关联映射中,
默认了级联属性。
Hibernate 一对一外键关联映射(双向关联)
双向关联需要在另外一端(IdCard)端添加<one-to-one>标签,
指示hibernate如何加载其引用对象,默认情况下会根据主键匹配进行加载Person,
因为外键关联映射中,两个实体的关系是由person的外键idcard维护的,所以不能指定使用person的主键对person进行加载,而要根据person的外键idcard进行加载,如<one-to-one name="person" property-ref="idcard"/>

hibernate一对多单向关联映射


这种映射的本质是利用了多对一的关联映射的原理
多对一关联映射:是在多的一端加一个外键维护多指向一的关联引用
一对多关联映射:是在多的一端添加一个外键维护一指向多的关联引用

也就是说:一对多和多对一的映射策略是一致的,只是站的角度不同

缺点:

更新student表中的classesid字段时,需要对每一个student发出一个update的sql,来更新classesid
如果将t_student表中的classesid设置为非空,则不能保存student数据,因为关系是由classesid来维护的,在保存student时,还没有对应的classesid被生成。

Hibernate 一对多双向关联映射


一对多双向关联映射的方法:
在一一端:
在集合标签里面使用<key>标签来表明需要在对方的表中添加一个外键指向一一端。
在多一端:
使用<many-to-one>标签来映射

需要注意:<key>标签所指定的外键字段名需要与<many-to-one>标签定义的外键字段名一致,否则便会造成引用数据的丢失!
如果从一端来维护一对多双向关联的关系,hibernate会发出多余的update语句,所以一般的情况下,我们便会从多一端来维护其关联关系。
 lazy策略可以用在:
<class>标签上,可以取值true/false
<property>标签上,可以取值true/false,这个特性需要类增强
<set>/<list>等集合上,可以取值为true/false/extra
<one-to-one>/<many-to-one>等标签上,可以取值false/proxy/no-proxy

重要的概念:

1,lazy的概念,指在需要的时候才发出sql;
2,lazy策略只是在session打开期间才是有效的
 注意:hibernate类级别的lazy加载策略:可以控制什么时候加载这些普通对象属性。(指的是那些普通属性,有property设置的属性。对于set无影响。)
 hibernate集合属性的懒加载策略:
 在集合属性上,可以配置懒加载策略,取值为:true/false/xetra
 
 
 true:默认取值,他的意思是只有在调用这个集合获取里面的元素对象时,才发出查询语句,加载其集合元素的数据 。
 false:取消懒加载特性,即在加载对象的同时,就发出第二条查询语句加载其关联集合的数据
 extra:一种比价聪明的懒加载策略,即调用集合的size/contains等方法的时候,hibernate并不会去加载整个集合的数据,而是发出一条聪明的sql语句,以便获得需要的值,只有子啊 真正需要用到这些集合元素对象数据的时候,才去发出查询语句加载所有对象的数据。
****在class标签上配置的lazy属性不会影响到关联对象!!!!!  
        }