多对一关联映射 many-to-one
关联映射本质:
* 将关联关系映射到数据库,所谓的关联关系是对象模型在内存中的一个或多个引用。
<many-to-one/>标签会在多的一端加入一个外键,指定一的一端,这个外键是由<many-to-one>
中的column属性定义的,如果忽略了这个属性那么默认的外键与实体的属性一致
<many-to-one/>标签的定义示例:
* <many-to-one name="group" column="groupid" cascade="save-update"/>
其中cascade属性为级联操作,值可以为all、save-update、delete,默认为none
级联操作:是对象的连锁操作
* 级联操作的解决方法有两种:1 设cascade属性,2 先进行save操作
<!--
User: Group:
private int id; private int id;
private String name; private String name;
private Group group;
-->
<class name="com.my.hibernate.Group" table="t_group">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
<class name="com.my.hibernate.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="password"/>
<property name="createTime"/>
<property name="expireTime"/>
<many-to-one name="group" column="groupid" cascade="save-update"/>
</class>
public void testSave1(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
Group group=new Group();
group.setName("尚学堂");
User user=new User();
user.setName("采10");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
user.setGroup(group);
User user1=new User();
group.setName("尚学堂");
user1.setName("张三");
user1.setPassword("888");
user1.setCreateTime(new Date());
user1.setExpireTime(new Date());
user1.setGroup(group);
//不能成功保存,抛出TransientObjectException异常
//因为Group为Transient状态,id没有分配值
//persistent状态的对象是不能引用trainsient状态的对象的
session.save(user);
session.save(user1);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
public void testSave2(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
Group group=new Group();
group.setName("尚学堂");
session.save(group);
User user=new User();
user.setName("采10");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
user.setGroup(group);
User user1=new User();
group.setName("尚学堂");
user1.setName("张三");
user1.setPassword("888");
user1.setCreateTime(new Date());
user1.setExpireTime(new Date());
user1.setGroup(group);
//可以存储,因为对Group进行了save操作
session.save(user);
session.save(user1);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
public void testSave3(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
Group group=new Group();
group.setName("尚学堂");
User user=new User();
user.setName("采10");
user.setPassword("123");
user.setCreateTime(new Date());
user.setExpireTime(new Date());
user.setGroup(group);
User user1=new User();
group.setName("尚学堂");
user1.setName("张三");
user1.setPassword("888");
user1.setCreateTime(new Date());
user1.setExpireTime(new Date());
user1.setGroup(group);
//不会抛出异常,因为采用了cascade属性,所以它会先保存Group
//采用cascade属性是解决TransientObjectException异常的一种手段
session.save(user);
session.save(user1);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
public void testload1(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
User user=(User)session.load(User.class, 3);
System.out.println(user.getName());
System.out.println(user.getGroup().getName());
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
一对一关联映射 one-to-one
1 主键关联映射(单向关联Person--->Card)
<one-to-one/>主键关联映射
* 让两个实体对象的id保持相同,这样可以避免多余的字段被创建
* 具体映射:
<id name="id">
person的主键来源于Card,也就是共享Card的主键
<generator class="foreign">
<param name="property">card</param>
</generator>
</id>
<one-to-one/>标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,
constrained="true",表明当前主键上存在一个约束,person的主键作为外键参照了Card
<one-to-one name="card" constrained="true"/>
public void testSave1(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
Card card=new Card();
card.setCardNo("sadfsaffsf");
Person person=new Person();
person.setName("werwer");
person.setCard(card);
//不会出现TransientObjectException异常
//因为一对一主键关联映射中,默认为cascade属性
session.save(person);
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
public void testLoad1(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
Person person=(Person)session.load(Person.class, 7);
System.out.print(person.getName());
System.out.print(person.getCard().getCardNo());
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
一对一关联映射 one-to-one
2 主键关联映射(双向关联Person<--->Card)
需要在Card映射文件中加入<one-to-one/>标签指向person,指示hibernate如何加载person
默认根据主键加载
只能用于查询,load和get
<!--
Person: Card:
private int id; private int id;
private String name; private String cardNo;
private Card card; private Person person;
-->
<class name="com.my.hibernate.Card" table="t_card">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
<one-to-one name="person"/>
</class>
<class name="com.my.hibernate.Person" table="t_person">
<id name="id">
<generator class="foreign">
<param name="property">card</param>
</generator>
</id>
<property name="name"/>
<one-to-one name="card" constrained="true"/>
</class>
public void testLoad2(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
Card card=(Card)session.load(Card.class, 7);
System.out.println(card.getCardNo());
System.out.println(card.getPerson().getName());
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
一对一唯一外键关联映射
1 一对一外键关联映射(单向关联Person--->Card)
<many-to-one/>一对一外键关联映射是多对一的特例,
采用<many-to-one/>标签,设多的一端的unique="true",这样就限制了多的一端的多重性为一
<!--
Person: Card:
private int id; private int id;
private String name; private String cardNo;
private Card card; private Person person;
-->
<class name="com.my.hibernate.Person" table="t_person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="card" unique="true" column="cardid" cascade="save-update"/>
</class>
<class name="com.my.hibernate.Card" table="t_card">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
</class>
一对一唯一外键关联映射
1 一对一外键关联映射(双向关联Person<--->Card)
采用<ont-to-one/>标签,指示hibernate如何加载其关联对象,默认根据主键加载。
外键关联映射中,因为两个实体采用的是person的外键的关系,所以不能指定主键相载person,
而要根据person的外键加载,所以设property-ref="card"
<!--
Person: Card:
private int id; private int id;
private String name; private String cardNo;
private Card card; private Person person;
-->
<class name="com.my.hibernate.Card" table="t_card">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
<one-to-one name="person" property-ref="card"/>
</class>
<class name="com.my.hibernate.Person" table="t_person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="card" unique="true" column="cardid" cascade="save-update"/>
</class>
posted on 2009-11-03 15:53
junly 阅读(425)
评论(0) 编辑 收藏 所属分类:
hibernate/orm