zoukankan      html  css  js  c++  java
  • 一对一关联映射

    Hibernate中实现一对一映射有基于外键的方式和基于主键的方式。由于基于主键方式的映射在实现删除等操作时存在的问题且不够灵活,一般建议使用基于外键的方式实现。



    以个人与身份证的关系为例(主要看映射文件的配置和实体类):

    基于外键的方式(只有有外键方可以维护关联关系):

    package test.hibernate.hbmOneToOne;
    
    public class Person {
    
    	private Integer id;
    	private String name;
    	private IDCard idCard;
    
    	public Integer getId() {
    		return id;
    	}
    
    	public void setId(Integer 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;
    	}
    
    	@Override
    	public String toString() {
    		// TODO Auto-generated method stub
    		return "[Person:id=" + id + ",name=" + name + "]";
    	}
    
    }



    package test.hibernate.hbmOneToOne;
    
    public class IDCard {
    
    	private Integer id;
    	private String IDNumber;
    	private Person person;
    
    	public Integer getId() {
    		return id;
    	}
    
    	public void setId(Integer id) {
    		this.id = id;
    	}
    
    	public String getIDNumber() {
    		return IDNumber;
    	}
    
    	public void setIDNumber(String iDNumber) {
    		IDNumber = iDNumber;
    	}
    
    	public Person getPerson() {
    		return person;
    	}
    
    	public void setPerson(Person person) {
    		this.person = person;
    	}
    	@Override
    	public String toString() {
    		// TODO Auto-generated method stub
    		return "[IDCard:id="+id+",IDNumber="+IDNumber+"]";
    	}
    
    }



    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 package="test.hibernate.hbmOneToOne">
    	<class name="Person" table="person">
    		<id name="id" type="integer" column="id">
    			<generator class="native" />
    		</id>
    		<property name="name" />
    		<one-to-one name="idCard" class="IDCard" property-ref="person"></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 package="test.hibernate.hbmOneToOne">
    	<class name="IDCard" table="idCard">
    		<id name="id" type="integer" column="id">
    			<generator class="native" />
    		</id>
    		<property name="IDNumber" />
    		<many-to-one name="person" class="Person" column="personId" unique="true">
    		</many-to-one>
    
    	</class>
    </hibernate-mapping>



    测试类

    package test.hibernate.hbmOneToOne;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.junit.Test;
    
    public class App {
    
    	private static SessionFactory sessionFactory = new Configuration()//
    			.configure()//
    			.addClass(Person.class)// 添加Hibernate实体类(加载对应的映射文件)
    			.addClass(IDCard.class)//
    			.buildSessionFactory();
    
    	@Test
    	public void testSave() throws Exception {
    		Session session = sessionFactory.openSession();
    		session.beginTransaction();
    		// --------------------------------------------
    
    		// 构建对象
    		Person person = new Person();
    		person.setName("张三");
    
    		IDCard idCard = new IDCard();
    		idCard.setIDNumber("377489392002121X");
    
    		// 关联起来
    		person.setIdCard(idCard);
    		idCard.setPerson(person);
    
    		// 保存
    		session.save(person);
    		session.save(idCard);
    
    		// --------------------------------------------
    		session.getTransaction().commit();
    		session.close();
    	}
    
    	@Test
    	public void testGet() throws Exception {
    		Session session = sessionFactory.openSession();
    		session.beginTransaction();
    
    		// 获取数据
    		Person person = (Person) session.get(Person.class, 2);
    		System.out.println(person);
    		System.out.println(person.getIdCard());
    
    		IDCard idCard = (IDCard) session.get(IDCard.class, 2);
    		System.out.println(idCard);
    		System.out.println(idCard.getPerson());
    
    		session.getTransaction().commit();
    		session.close();
    	}
    
    	// 解除关联关系,从有外键方
    	@Test
    	public void testRemoveRelation() throws Exception {
    		Session session = sessionFactory.openSession();
    		session.beginTransaction();
    		// --------------------------------------------
    
    		IDCard idCard = (IDCard) session.get(IDCard.class, 1);
    		idCard.setPerson(null);
    
    		// --------------------------------------------
    		session.getTransaction().commit();
    		session.close();
    	}
    
    	// 删除,只能做有外键方到无外键方的单向关联
    	@Test
    	public void testDelete() throws Exception {
    		Session session = sessionFactory.openSession();
    		session.beginTransaction();
    		// --------------------------------------------
    
    		// Person person=(Person) session.get(Person.class, 2);
    		// session.delete(person);//删除失败,有personId外键,抛出异常
    
    		IDCard idCard = (IDCard) session.get(IDCard.class, 3);
    		session.delete(idCard);// 卡删了,人还在
    
    		// --------------------------------------------
    		session.getTransaction().commit();
    		session.close();
    	}
    }



    基于主键的方式(双方都不可以维护关联关系,映射文件配置有所不同):

    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 package="test.hibernate.hbmOneToOne2">
    	<class name="Person" table="person2">
    		<id name="id" type="integer" column="id">
    			<generator class="native" />
    		</id>
    		<property name="name" />
    		<one-to-one name="idCard" class="IDCard"></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 package="test.hibernate.hbmOneToOne2">
    	<class name="IDCard" table="idCard2">
    		<id name="id" type="integer" column="id">
    			<!-- 
    			当使用基于主键的一对一映射时,有外键方的主键
    			生成策略 一定要是foreign。 
    			参数property:生成主键值时所根据的对象。
    			 -->
    			<generator class="foreign">
    				<param name="property">person</param>
    			</generator>
    		</id>
    		<property name="IDNumber" />
    		<!-- constrained外键约束 -->
    		<one-to-one name="person" class="Person" constrained="true">
    		</one-to-one>
    
    	</class>
    </hibernate-mapping>



    package test.hibernate.hbmOneToOne2;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.junit.Test;
    
    public class App {
    
    	private static SessionFactory sessionFactory = new Configuration()//
    			.configure()//
    			.addClass(Person.class)// 添加Hibernate实体类(加载对应的映射文件)
    			.addClass(IDCard.class)//
    			.buildSessionFactory();
    
    	@Test
    	public void testSave() throws Exception {
    		Session session = sessionFactory.openSession();
    		session.beginTransaction();
    		// --------------------------------------------
    
    		// 构建对象
    		Person person = new Person();
    		person.setName("张三");
    
    		IDCard idCard = new IDCard();
    		idCard.setIDNumber("377489392002121X");
    
    		// 关联起来
    		person.setIdCard(idCard);
    		idCard.setPerson(person);
    
    		// 保存
    //		session.save(person);
    		session.save(idCard);
    
    		// --------------------------------------------
    		session.getTransaction().commit();
    		session.close();
    	}
    
    	// 解除关联关系
    	@Test
    	public void testRemoveRelation() throws Exception {
    		Session session = sessionFactory.openSession();
    		session.beginTransaction();
    		// --------------------------------------------
    
    //		IDCard idCard = (IDCard) session.get(IDCard.class, 1);
    //		idCard.setPerson(null);//抛异常
    		
    		Person person=(Person) session.get(Person.class, 3);
    		person.setIdCard(null);//数据库中的数据没有改变
    
    		// --------------------------------------------
    		session.getTransaction().commit();
    		session.close();
    	}
    
    	// 删除
    	@Test
    	public void testDelete() throws Exception {
    		Session session = sessionFactory.openSession();
    		session.beginTransaction();
    		// --------------------------------------------
    
    //		IDCard idCard = (IDCard) session.get(IDCard.class, 2);
    //		session.delete(idCard);//正常
    		
    		Person person=(Person) session.get(Person.class, 3);
    		session.delete(person);//抛异常,id作为外键
    
    		// --------------------------------------------
    		session.getTransaction().commit();
    		session.close();
    	}
    }
    更多详情请关注 http://www.cnblogs.com/baixingqiang/
  • 相关阅读:
    Mesos以及Marathon安装总结
    Mesos的quorum配置引发的问题
    chronoy & NTP
    /boot下面文件说明
    jquery插件
    不错的源码演示:admin5源码
    dos中执行cd命令切换不到对应的盘解决方法
    ThinkPHP重写规则优化URL及Rewrite规则详细说明
    PHP实现MySQL数据导出为EXCEL(CSV格式)
    php中常用$_SERVER的用法
  • 原文地址:https://www.cnblogs.com/baixingqiang/p/5842815.html
Copyright © 2011-2022 走看看