【学习笔记】Hibernate 一对一关联映射 组件映射 二级缓存 集合缓存
啊讲道理放假这十天不到啊
感觉生活中充满了绝望 这就又开学了
好吧好吧继续学习笔记?还是什么的
一对一关联映射
这次我们仍然准备了两个表
一个是用户表Users
一个是档案表Resume
他们的关系是一对一(一个用户只能有一份档案 一份档案只能属于一个永固)
我们无需建表,Hibernate会检查数据库中有没有对应的表,如果没有,自动生成
我们也可以用来看自动生成的表是什么样子的
一对一外键映射FK
那么接下来是小配置文件
user的小配置文件
<one-to-one name="resume" class="Resume" property-ref="user"></one-to-one>
name属性是小配置关联的实体类中 存放的另一个实体的对象的名称
Class当然是一对一关系中对应的实体类
那么Users这个实体类结构如下
property-ref 改变有关联关系对象的列的等值对比
默认:A表主键默认关联B表主键
设置后是让A表的主键关联B表的非主键列
resume的小配置文件
<many-to-one name="users" class="Users" columm="uid" unique="true" cascade="all"></many-to-one>
column 关联的主键列(相当于档案表是外检表,用户表是主表)
unique 唯一的 保证了一对一的关系
Resume实体类如下
编写测试类。
@Before public void before() { session = HibernateUtil.currentSession(); tx = session.beginTransaction(); } @After public void after() { tx.commit(); HibernateUtil.closeSession(); } @Test public void insert() { Resume resume = new Resume(); resume.setResname("斯沃的机密档案"); Users user = new Users(); user.setUname("斯沃"); resume.setUser(user); user.setResume(resume); session.save(resume); }
运行成功后我们来看看自动生成的表的结构
User用户表里只有我们的编号和姓名两列
而在档案表里除了编号和档案名称
还多出了一列 用户id
一对一外键映射相当于一个一对多的关联映射,但是加上了一个唯一约束使得一个User只能对应一个档案
(否则多个档案的Userid列会可以指向同一个User)
一对一主键映射PK
然后呢是一对一主键映射
我比较懒 因为已经提前知道一对一外键映射和逐渐映射
自动生成的表的表结构是不一样的
可是我比较不想举一个新的例子 所以仍用用户和档案的例子
为了避免重复,我们在小配置中让他们关联的表名变化
这次是Users2表和Resume2表(虽然实体类的名称没有变)
那么实体类是没有变化的
我们直接来看小配置
先看档案的
<one-to-one name="user" class="Users" cascade="all"></one-to-one>
没有什么可以说的样子
看Users用户的
哦对了在这里突然想到 为什么用户表叫Users而不是User 关键字的问题
<one-to-one name="resume" class="Resume" constrained="true"></one-to-one>
constrained 约束用户表中出现的档案列必须在主表档案表中出现过
另外一点 就是Users表的主键生成策略
<id name="userid" type="java.lang.Integer"> <!--主键生成策略--> <generator class="foreign"> <param name="property">resume</param> </generator> </id>
这里使用的主键生成策略是foreign 关联到的是表RESUME
也就是两个表的对应的记录的主键会相同
所以在查询的时候只需要查询一个主键就可以把它们关联起来
测试类的代码如下
@Before public void before() { session = HibernateUtil.currentSession(); tx = session.beginTransaction(); } @After public void after() { tx.commit(); HibernateUtil.closeSession(); } @Test public void insert() { Resume resume = new Resume(); resume.setResname("斯沃的机密档案"); Users user = new Users(); user.setUname("斯沃"); resume.setUser(user); user.setResume(resume); session.save(user); }
等等 为啥感觉区别不大= =
不要在意细节 看看结果是怎么样的
果然如我所说= =
组件映射
那么接下来是组件映射
组件映射就是两个实体类 一对一的关系
或者说其实一个实体类是另一个实体类的扩展
我们举的例子是一个 People 人 和一个PeopleInfo 人的信息
其中人保存的是人的编号pid 名字pname 和 对应的人的信息这个实体类
我们看一下两个实体类
噢我们只需要一个小配置文件 就是People的小配置文件
那么需要怎么写。。。
<class name="People" table="PEOPLE"> <id name="pid" type="java.lang.Integer"> <!--主键生成策略--> <generator class="native"/> </id> <property name="pname" type="string"/> <component name="info" class="PeopleInfo"> <parent name="people"/> <property name="address"></property> <property name="phone"></property> </component> </class>
在class节点中
使用一个component节点 关联着另一个类
然后 就 可以使用 了
@Test public void insert() { People people=new People(); people.setPname("天命"); PeopleInfo info=new PeopleInfo(); info.setAddress("北京"); info.setPhone("15201520190"); people.setInfo(info); info.setPeople(people); session.save(people); }
最后我们看看运行后生成的表
果然是只有一个表的 表中的列是People和PeopleInfo两个实体类中的集合