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属性不会影响到关联对象!!!!!
}
hibernate
最新推荐文章于 2024-07-04 15:45:46 发布