一、一对一映射简介
一对一关联映射有两种实现策略:
第一种:主键关联,即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联
第二种:唯一外键关联,外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系
其中一对一的关联映射,又分为单向一对一映射和双向一对一映射,这里主要介绍单向一对一映射。
二、实例介绍(主键关联)
2.1,建立两个实体对象类
IdCard类:
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.hibernate; public class IdCard { private int id; private String cardNo; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCardNo() { return cardNo; } public void setCardNo(String cardNo) { this.cardNo = cardNo; } } </span>
映射文件:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><?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.angel.hibernate.IdCard" table="t_idcard"> <id name="id"> <generator class="native"></generator> </id> <property name="cardNo" /> </class> </hibernate-mapping></span>
Person类:
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.hibernate; public class Person { private int id; private String name; IdCard idCard; public IdCard getIdCard() { return idCard; } public void setIdCard(IdCard idCard) { this.idCard = idCard; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } </span>
映射文件:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><?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.angel.hibernate.Person" table="t_person"> <id name="id"> <!--主键关联策略 --> <generator class="foreign"> <!-- 标签中的值是指明标识来源于foreign方式,指定来源对象:Person类的属性idCard --> <param name="property">idCard</param> </generator> </id> <property name="name" /> <!-- one-to-one指的是如何加载它的引用对象 外键约束要设为true --> <one-to-one name="idCard" constrained="true"></one-to-one> </class> </hibernate-mapping></span>
2.2,生成数据库表单
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.hibernate; import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; /** * 将hbm生成ddl * @author Administrator * */ public class ExportDB { public static void main(String[] args) { //默认读取hibernate.cfg.xml文件 Configuration cfg = new Configuration().configure(); SchemaExport export = new SchemaExport(cfg); export.create(true, true); } }</span>
2.3,Hibernate配置
<span style="font-family:KaiTi_GB2312;font-size:18px;"><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_one2one</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">登录密码</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.show_sql">true</property> <mapping resource="com/angel/hibernate/Person.hbm.xml"/> <mapping resource="com/angel/hibernate/IdCard.hbm.xml"/> </session-factory> </hibernate-configuration></span>
2.4,测试类
<span style="font-family:KaiTi_GB2312;font-size:18px;">package com.angel.hibernate; import org.hibernate.Session; import junit.framework.TestCase; public class test_one2one extends TestCase { /** * 测试保存 */ public void testSave1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); IdCard idCard = new IdCard(); idCard.setCardNo("6688"); Person person = new Person(); person.setName("Angel"); person.setIdCard(idCard); // 先保存card,然后保存person,执行SQL语句为: // Hibernate: insert into t_idcard (cardNo) values (?) // Hibernate: insert into t_person (name, id) values (?, ?) session.save(person); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } /** * 测试加载 */ public void testLoad() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Person person = (Person) session.get(Person.class,Integer.valueOf("1")); System.out.println("person.getName()=" + person.getName()); System.out.println("person.getIdCard().getCardNo="+ person.getIdCard().getCardNo()); //执行的SQL语句 //Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from t_person person0_ where person0_.id=? //Hibernate: select idcard0_.id as id1_0_, idcard0_.cardNo as cardNo1_0_ from t_idcard idcard0_ where idcard0_.id=? //控制台结果: //person.getName()=Angel //person.getIdCard().getCardNo=6688 session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } } </span>
以上就是简单的单向一对一关联映射,关于双向关联映射和单向是类似的,在另一个实体映射关系中添加进去一对一的标签配置即可。
三、简单介绍外键关联
使用唯一外键关联,则需要在配置一对一关系时加上property—ref属性。如:我们在Person类中添加上IdCard的外键映射private IdCard idCard,那么在IdCard的配置文件中,则需要加上:
<one-to-one name="idCard" constrained="true" property-ref=“idCard”></one-to-one> 它表示本类(IdCard)的主键将会与关联类(Person)的此属性(idCard)相对应
四、总结
让我想一下,没有配置这种关联映射的时候,在加载数据的时候是怎么做的?
似乎我们一般是用连接查询,比如:where a.id=b.courseid等,或者是将外键的值查出来,然后拿着这个值去另一张表里查对应的数据。但是对于Hibernate来说,只是配置的问题,感觉上经过封装,简单了很多!接下来就是多对多、继承、集合映射的学习了。