八 一对一 用户与身份证的关系
八 一对一 用户与身份证的关系 设计用户实体 主实体package hibernate.bean;public class Person { private int id; private String name; private IDCard idcart;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;}public IDCard getIdcart() {return idcart;}public void setIdcart(IDCard idcart) {this.idcart = idcart;}}映射文件<?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="hibernate.bean"><class name="Person"><id name="id"><generator table="id_card"> <id name="id"> <!-- 设置主键为外键 关联的是主实体的id--> <generator name="useDate"/> <one-to-one name="person"/> </class></hibernate-mapping>测试package hibernate.test;import hibernate.bean.IDCard;import hibernate.bean.Person;import hibernate.util.HibernateUtil;import org.hibernate.Session;import org.hibernate.Transaction;public class OneToOne {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubadd();query(1);} static Person add(){ Session session=null; Transaction tx=null; try{ session=HibernateUtil.getSession(); tx=session.beginTransaction(); IDCard idcard=new IDCard(); idcard.setUseDate("有效期三年"); Person person=new Person(); person.setName("许春荣"); // person.setIdcart(idcard); idcard.setPerson(person); session.save(person); session.save(idcard); tx.commit(); return person; }finally{ if(session!=null) session.close(); } } static void query(int id){ Session session=null; try{ session=HibernateUtil.getSession(); Person person=(Person)session.get(Person.class, id); System.out.println(person.getName()+"-------->"+person.getIdcart().getUseDate()); }finally{ if(session!=null) session.close(); } }}分析:在执行后,我们可以去查看一下从实体下的表结构 在命令行输入 show create table id_card 源码为 ddl语句 CREATE TABLE `id_card` ( `id` int(11) NOT NULL, `use_date` varchar(255) default NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;发现生成的表的主键少了一个定义,根据我们的设计 id_card表的id 不但要是主键也要是外键,它引用的是person表的主键 为什么是这样呢?其实这样并不会影响我们程序的实体的实现效果,为了设计更合理,我们必须要注意在Person的映射文件的one-to-one节点中 少了一个属性constrained定义,加上<one-to-one name=”idCard” constrained=”true”/>ddl语句CREATE TABLE `id_card` ( `id` int(11) NOT NULL, `use_date` varchar(255) default NULL, PRIMARY KEY (`id`), KEY `FK627C1FB461BB04F2` (`id`), CONSTRAINT `FK627C1FB461BB04F2` FOREIGN KEY (`id`) REFERENCES `person` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;这样是不是更合理呢 下面我们来看第二种一对一的设计方式 上面的这种设计方式是把从表的主键id是依赖于主表的主键id而建立的 我们可不可以改变这样的设计方式,而在从表中额外加入一个外键呢 但是,如果我们这样做的话,我们可以在从表下根据一个主表的id,而在从表中加入多条数据这样不就是多对一的关系了吗?是这样的,但是我们是否可以把这个外键同时也设置为唯一键呢哈哈,这不就好了,这只是要修改映射文件即可实现,怎么修改的 请看吧 Person实体的映射文件修改前<?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="hibernate.bean"><class name="Person"><id name="id"><generator 是IDCard的属性 用这来告诉hibernate的从实体隶属于Person --><one-to-one name="idcart" property-ref="person"/></class></hibernate-mapping>IDCard的映射文件修改前<?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="hibernate.bean"> <class name="IDCard" table="id_card"> <id name="id"> <!-- 设置主键为外键 关联的是主实体的id--> <generator name="useDate"/> <one-to-one name="person" constrained=”true”/> </class></hibernate-mapping>修改后的<?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="hibernate.bean"> <class name="IDCard" table="id_card"> <id name="id"> <!-- 设置主键为外键 关联的是主实体的id--> <!-- <generator name="useDate"/> <!-- 在这里加入了many-to-one 而不是one-to-one 并且指定其隶属的实体 Person unique是指定其唯一键 column制定其唯一键的列名 --> <many-to-one name="person" unique="true" column="person_id"/> </class></hibernate-mapping>然后就可以运行测试文件 成功执行 现在我们来查看id_card表的ddl语句 show create table id_card;CREATE TABLE `id_card` ( `id` int(11) NOT NULL auto_increment, `use_date` varchar(255) default NULL, `person_id` int(11) default NULL, PRIMARY KEY (`id`), UNIQUE KEY `person_id` (`person_id`), KEY `FK627C1FB49495921C` (`person_id`), CONSTRAINT `FK627C1FB49495921C` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;发现person_id是个外键 并且还是个唯一键 到这里一对一的映射就完成了 完毕 end!?