一对一关系映射:比如中国公民和身份证,一个人对应一张身份证,一张身份证也是对应一个人
Person类:
public class Person { private int id; private String name; private IDCard idCard;
配置文件:
<class name="Person" table="person"> <id name="id" column="id"> <!--主键生成策略为外键,就是取其关联的idCard对象的主键,所以保存person时, idCard对象必须存在id值--> <generator class="foreign"> <param name="property">idCard</param> </generator> </id> <property name="name" column="name" type="java.lang.String" not-null="true"></property> <!--constrained="false"表示由hibernate创建表时,这种一对一关系是否创建一个外键关系来维护--> <one-to-one name="idCard" class="com.hibernate.bean.IDCard" constrained="false" ></one-to-one> </class>
IDCard类:
public class IDCard { private int id; private String cardNumber;
配置文件:
<class name="IDCard" table="idcard"> <id name="id" column="id"> <generator class="native"> </generator> </id> <property name="cardNumber" column="cardNumber" type="java.lang.String" not-null="true"></property> </class>
测试方法:
public void savePerson(){ Session session = null; Transaction transaction = null; try { session = sessionFactory.openSession(); transaction = session.beginTransaction(); IDCard idCard = new IDCard(); /** * 这个地方idCard该不该设置主键值要分情况讨论,否则很容易出错 */ //idCard.setId(11); idCard.setCardNumber("43092219"); Person person = new Person(); person.setName("yly"); person.setIdCard(idCard); session.save(person); transaction.commit(); }catch (Exception e){ if (transaction!=null){ transaction.rollback(); } e.printStackTrace(); }finally { if (session!=null){ session.close(); } } }
idCard配置为:
<generator class="native">
表示主键由hibernate选择主键的生成方式,由数据库决定;如果此时person表和idCard表之间建立了外键约束,那么就不能手动设置idCasd的id值,id值对应的身份证记录必须真实存在(hibernate就是判断此idcard对象必须为持久化状态),否则保存person的时候会报错;
hibernate会产生这样两条语句:就是先保存idCard得到id值,再保存Person
如果你没有建立外键约束,手动设置idCasd的id值就没有问题,那么保存person时,person的id值就直接取你手动设置的这个值,不会再先保存idCard取id,会产生如下一条sql:
当你从数据库查询一个person对象时,关联的idcard对象也会同时查询出来:
String hql = "from Person"; Query query = session.createQuery(hql); List<Person> personList = query.list();
hibernate查询时,会先查询一个person表,再根据person的id去查找idCard表