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表中多了一个外键的关联:



  • 相关阅读:
    Wrong codepoints for non-ASCII characters inserted in UTF-8 database using CLP
    SqlException with message "Caught java.io.CharConversionException." and ERRORCODE=-4220
    XSD 数据类型
    Can't read [proguard.ClassPathEntry@1a0c10f] (No such file or directory)
    ubuntu 创建swap分区
    tar分层压缩
    MTK 自定义系统服务
    MTK framework系统默认设置
    MTK 修改默认屏幕亮度
    MTK 隐藏底部状态栏
  • 原文地址:https://www.cnblogs.com/raphael5200/p/5114757.html
Copyright © 2011-2022 走看看