many-to-one
Group.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.bjsxt.hibernate.Group" table="t_group"> <id name="id"> <generator class="native"/> </id> <property name="name"/> </class></hibernate-mapping>
User.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.bjsxt.hibernate.User" table="t_user"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <!-- <many-to-one name="group" column="groupid" cascade="all"/> --> <many-to-one name="group" column="groupid"/> </class></hibernate-mapping>
public void testSave1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Group group = new Group(); group.setName("尚学堂"); User user1 = new User(); user1.setName("菜10"); user1.setGroup(group); User user2 = new User(); user2.setName("容祖儿"); user2.setGroup(group); //不能成功保存,抛出TransientObjectException异常 //因为Group为Tran sient状态,oid没有分配值 //persistent状态的对象是不能引用transient状态的对象的 session.save(user1); session.save(user2); 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 user1 = new User(); user1.setName("菜10"); user1.setGroup(group); User user2 = new User(); user2.setName("容祖儿"); user2.setGroup(group); //可以正确存储 session.save(user1); session.save(user2); 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 user1 = new User(); user1.setName("菜10"); user1.setGroup(group); User user2 = new User(); user2.setName("容祖儿"); user2.setGroup(group); //不会抛出异常,因为采用了cascade属性,所以它会先保存Group //采用cascade属性是解决TransientObjectException异常的一种手段 session.save(user1); session.save(user2); 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.name=" + user.getName()); System.out.println("user.group.name=" + user.getGroup().getName()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
hibernate一对一主键关联映射(单向关联Person---->IdCard)
一对一主键关联映射:让两个实体对象的id保持相同,这样可以避免多余的字段被创建
具体映射:
<id name="id"> <!-- person的主键来源idCard,也就是共享idCard的主键 --> <generator class="foreign"> <param name="property">idCard</param> </generator> </id> <property name="name"/> <!-- one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载, constrained="true", 表明当前主键上存在一个约束,person的主键作为外键参照了idCard --> <one-to-one name="idCard" constrained="true"/>
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.bjsxt.hibernate.IdCard" table="t_idcard"> <id name="id"> <generator class="native"/> </id> <property name="cardNo"/> </class></hibernate-mapping>
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.bjsxt.hibernate.Person" table="t_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>
public void testSave1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); IdCard idCard = new IdCard(); idCard.setCardNo("88888888888888"); Person person = new Person(); person.setName("菜10"); person.setIdCard(idCard); //不会出现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(); User user = (User)session.load(User.class, 3); System.out.println("user.name=" + user.getName()); System.out.println("user.group.name=" + user.getGroup().getName()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
hibernate一对一主键关联映射(双向关联Person<---->IdCard)
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.bjsxt.hibernate.IdCard" table="t_idcard"> <id name="id"> <generator class="native"/> </id> <property name="cardNo"/> <one-to-one name="person"/> </class></hibernate-mapping>
public void testLoad2() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); IdCard idCard = (IdCard)session.load(IdCard.class, 1); System.out.println("idcard.cardNo=" + idCard.getCardNo()); System.out.println("idcard.person.name=" + idCard.getPerson().getName()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
hibernate一对一唯一外键关联映射(单向关联Person---->IdCard)
一对一唯一外键关联映射是多对一关联映射的特例
可以采用<many-to-one>标签,指定多的一端的unique=true,这样就限制了多的一端的多重性为一通过这种手段映射一对一唯一外键关联
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.bjsxt.hibernate.Person" table="t_person"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <many-to-one name="idCard" unique="true"/> </class></hibernate-mapping>
public void testSave1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); IdCard idCard = new IdCard(); idCard.setCardNo("88888888888888"); Person person = new Person(); person.setName("菜10"); person.setIdCard(idCard); //不能成功保存,因为IdCard是Transient状态 session.save(person); 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(); IdCard idCard = new IdCard(); idCard.setCardNo("88888888888888"); session.save(idCard); Person person = new Person(); person.setName("菜10"); person.setIdCard(idCard); // 成功 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, 2); System.out.println("person.name=" + person.getName()); System.out.println("idCard.cardNo=" + person.getIdCard().getCardNo()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
hibernate一对一唯一外键关联映射(双向关联Person<---->IdCard)
一对一唯一外键关联双向,需要在另一端(idcard),添加<one-to-one>标签,指示hibernate如何加载其关联对象,默认根据主键加载person,外键关联映射中,因为两个实体采用的是person的外键维护的关系,所以不能指定主键加载person,而要根据person的外键加载,所以采用如下映射方式:<one-to-one name="person" property-ref="idCard"/>
相关资源:垃圾分类数据集及代码