多对一关联映射 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 >
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);
}
}
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);
}
}
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 >
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 >