前言 上课很容易走神… emmm… 老师讲的注解的 那我就讲讲XML配置吧 可能讲的有错误 希望大佬能指正!感激不尽
准备 创建一个有Hibernate环境的Java项目 这个可以看之前的帖子 从0搭建一个基于Hibernate的Java项目
两种一对一映射方式 一对一其实也可以不用拆表在一个表内进行操作 至于为什么要拆,我个人觉得可能是为了垂直分表?
主键一对一 主键一对一,可以理解为一个表的主键同时也是外键,这个外键对应着另一个表的主键 这里我们用User和Address来做例子 一个User对应一个Address 一个Address对应一个User
User类
1 2 3 4 5 6 7 public class User { private int id; private String name; private Address address; }
User类对应的User.hbm.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" > <hibernate-mapping > <class name ="User" > <id name ="id" > <generator class ="native" /> </id > <property name ="name" /> <one-to-one name ="address" /> </class > </hibernate-mapping >
Address类
1 2 3 4 5 6 7 8 9 10 public class Address { private int id; private String province; private String city; private User user; }
Address类的Address.hbm.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" > <hibernate-mapping > <class name ="Address" > <id name ="id" > <generator class ="foreign" > <param name ="property" > user</param > </generator > </id > <property name ="province" /> <property name ="city" /> <one-to-one name ="user" constrained ="true" /> </class > </hibernate-mapping >
然后我们写个测试类来测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class HibernateTest { @Test public void test01 () { Session session = SessionUtil.getSession(); Transaction transaction = session.beginTransaction(); User user = new User (); user.setName("lwf" ); Address address = new Address (); address.setProvince("广东" ); address.setCity("广州" ); address.setUser(user); session.save(user); session.save(address); transaction.commit(); session.close(); SessionUtil.close(); } }
运行之后,就可以看到数据库新增的记录
user表
address表
address表里面的外键
PS:
1 2 3 4 5 6 7 8 public class HibernateTest { @Test public void test01 () { address.setUser(user); } }
这里可能有人会问为什么是address.setUser(user)
而不是user.setAddress(address)
其实我们是在address设置的外键指向user 当我们希望插入新的一个address对象的时候 肯定需要从user获取他的主键值来作为address的主键 如果是 user.setAddress(address)
的话 address对象其实是没有对user的引用的 插入的时候自然找不到user对象便报错
报错信息org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [pojo.Address.user]
翻译过来就是尝试从一个空属性(user对象)中获取id(主键)属性
利用多对一实现一对一 上面是利用其他表的主键作为自己的主键 多对一实现的一对一就是将自己的主键映射到另一个表的普通字段
还是用上面User和Address来作例子 User类
1 2 3 4 5 6 7 public class User { private int id; private String name; private Address address; }
User类对应的User.hbm.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" > <hibernate-mapping > <class name ="User" > <id name ="id" > <generator class ="native" /> </id > <property name ="name" /> <many-to-one name ="address" column ="address_id" unique ="true" /> </class > </hibernate-mapping >
Address类
1 2 3 4 5 6 7 8 9 10 public class Address { private int id; private String province; private String city; private User user; }
Address类的Address.hbm.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" > <hibernate-mapping > <class name ="Address" > <id name ="id" > <generator class ="native" /> </id > <property name ="province" /> <property name ="city" /> <one-to-one name ="user" property-ref ="address" /> </class > </hibernate-mapping >
老规矩写个测试类来测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class HibernateTest { @Test public void test01 () { Session session = SessionUtil.getSession(); Transaction transaction = session.beginTransaction(); User user = new User (); user.setName("lwf" ); Address address = new Address (); address.setProvince("广东省" ); address.setCity("广州市" ); user.setAddress(address); session.save(address); session.save(user); transaction.commit(); session.close(); SessionUtil.close(); } }
运行之后
user表
address表
user表中的外键
PS: 这里的 user.setAddress(address)
同样也不能换成address.setUser(user)
插入user的时候 需要获取address的主键作为外键 没设置的话获取不到 外键又设置为非空的话 就会插入失败
后记 感觉只写一对一就可以写很多东西 emmm 要学的还很多 希望能学会吧