zoukankan      html  css  js  c++  java
  • Hibernate 、多表关联映射


    hibernate.cfg.xml:

    <hibernate-configuration>
        <session-factory name="sessionFactory">
        	<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        	<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        	<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=UTF-8</property>
        	<property name="hibernate.connection.username">root</property>
        	<property name="hibernate.connection.password"></property>
        	<property name="hibernate.show_sql">true</property>
        	<property name="hibernate.format_sql">true</property>
        	<property name="hibernate.hbm2ddl.auto">update</property>
        	<mapping resource="cn/hbm/Person.hbm.xml" />
        	<mapping resource="cn/hbm/IdCard.hbm.xml" />
        </session-factory>
    </hibernate-configuration>

    Person:

    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;
    	}
    	
    }
    

    hbm.xml

    <hibernate-mapping package="cn.model">
    	<class name="Person" table="PERSON">
    		<id name="id" column="ID">
    			<generator class="native"></generator>
    		</id>
    		<property name="name" column="NAME" type="java.lang.String" />
    		<one-to-one name="idCard" />
    	</class> 
    </hibernate-mapping>
    

    IdCard:

    public class IdCard {
    	private Integer id;
    	private Date usefullLife;
    	private Person person;
    	public Person getPerson() {
    		return person;
    	}
    	public void setPerson(Person person) {
    		this.person = person;
    	}
    	public Integer getId() {
    		return id;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public Date getUsefullLife() {
    		return usefullLife;
    	}
    	public void setUsefullLife(Date usefullLife) {
    		this.usefullLife = usefullLife;
    	}
    }
    
    hbm.xml:

    <hibernate-mapping package="cn.model">
    	<class name="IdCard" table="ID_CARD">
    		<id name="id" column="ID">
    			<!-- 对一主键关联映射的内容 foreign:表明当前表的主键的生成使用另外一个相关联的对象的标识符(依托于其他表的主键)
    			和 one-to-one联合一起使用  -->
    			<generator class="foreign">
    				<param name="property">person</param>
    			</generator>
    		</id>
    		<property name="usefullLife" column="USEFULL_LIFE"/>
    		<!-- constrained="true" 是否添加约束  -->
    		<one-to-one name="person" constrained="true" />
    	</class> 
    </hibernate-mapping>


    创建表并添加数据

    public void save(){
    		Session session=null;
    		Transaction tran=null;
    		try{
    			
    			Person person=new Person();
    			person.setName("杰克");
    			
    			IdCard idCard=new IdCard();
    			idCard.setUsefullLife(new Date());
    			idCard.setPerson(person);
    			
    			person.setIdCard(idCard);
    			
    			session=HibernateSessionFactory.getSession();
    			tran=session.beginTransaction();
    			session.save(person);
    			session.save(idCard);
    			tran.commit();
    		}catch(Exception e){
    			if(session!=null){
    				session.close();
    			}
    		}
    	}

    执行后会看到,Person和IdCard的id是一样的,通过<generator class="foreign"> 外部关系的型式可以使idCard的id和person的id关联起来


    再看一下创建的SQL:


    他们关联的关系是使用了主外键约束进行关联;

    查询的时候通过Person可以得到IdCard,通过IdCard也可以得到Person

    	public Person getPersonById(Integer id){
    		Session session=null;
    		try{
    			session=HibernateSessionFactory.getSession();
    			return (Person)session.get(Person.class, id);
    		}catch(Exception e){
    			if(session!=null){
    				session.close();
    			}
    		}
    		return null;
    	}
    	public IdCard getIdCardById(Integer id){
    		Session session=null;
    		try{
    			session=HibernateSessionFactory.getSession();
    			return (IdCard)session.get(IdCard.class, id);
    		}catch(Exception e){
    			if(session!=null){
    				session.close();
    			}
    		}
    		return null;
    	}
    	
    测试代码:

    	@Test
    	public void testGet(){
    		
    		Demo demo=new Demo();
    		Person per=demo.getPersonById(1);
    		System.out.println("人员姓名:"+per.getName()+",身份证有效期:"+per.getIdCard().getUsefullLife());
    	}


    	@Test
    	public void testGet2(){
    		Demo demo=new Demo();
    		IdCard idCard=demo.getIdCardById(1);
    		System.out.println("身份证ID:"+idCard.getId()+",人员姓名 :"+idCard.getPerson().getName());
    	}



    通过两个查询可以看出,通过IdCard获取 person的时候,实际上他们是查了两次!


    对于这种一对一的映射关系,我们同样可以使用many-to-one的方式进行实现;

    只需要在IdCard的映射关系中,使Person唯一即可:



    只需要更改IdCard的映射文件即可:

    <hibernate-mapping package="cn.model">
    	<class name="IdCard" table="ID_CARD">
    		<id name="id" column="ID">
    			<generator class="native" />
    		</id>
    		<property name="usefullLife" column="USEFULL_LIFE"/>
    		<many-to-one name="person" column="PERSON_ID" unique="true" not-null="true" />
    	</class> 
    </hibernate-mapping>
    

    使用这种方式在创建表的时候,表之间关系和one-to-one是一样的:


    但是表结构是不一样的,在IdCard表中多了一个外键的关联:



  • 相关阅读:
    【贪心】【堆】Gym
    【并查集】Gym
    【拓扑排序】【bitset】Gym
    【递归】【线段树】【堆】AtCoder Regular Contest 080 E
    【二分图】【并查集】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem L. Canonical duel
    【动态规划】【滚动数组】【bitset】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem J. Terminal
    【二分】【字符串哈希】【二分图最大匹配】【最大流】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem I. Minimum Prefix
    【枚举】【最小表示法】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem F. Matrix Game
    【推导】【构造】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem E. Space Tourists
    【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem D. Clones and Treasures
  • 原文地址:https://www.cnblogs.com/raphael5200/p/5114757.html
Copyright © 2011-2022 走看看