本期内容:
1、一对多的关联配置
2、懒加载
3、一对多的子关联
4、多对多的关联
一、一对多的关联配置
数据库:主表从表,通过外键关联
而我们的内容就是将数据库中表与表之间的关系给映射到实体类里面
今天用到订单表与订单项表进行演示:一个订单对应多个订单项
将以下内容导入,注意将xml文件中的路径改成对应的实体类的路径
执行OrderDaoTest类的这串代码,找到订单id为7的订单:
public void testGet() {
Order order = new Order();
order.setOrderId(7);
// order.setInitOrderItems(1);
Order o = this.orderDao.get(order);
System.out.println(o.getOrderNo());
// System.out.println(o.getOrderItems());
}
报这种错的含义是未找到Order这个类,也就是没有把这个文件包在hibernate.cfg.xml文件中
<!-- 一对多 -->
<mapping resource="lv/com/two/entity/Order.hbm.xml" />
<mapping resource="lv/com/two/entity/OrderItem.hbm.xml" />
执行出,找到文件:
二、懒加载(hibernate默认)
执行OrderDaoTest类的这串代码,想要查到订单表里的所有订单项
public void testGet() {
Order order = new Order();
order.setOrderId(7);
// order.setInitOrderItems(1);
Order o = this.orderDao.get(order);
System.out.println(o.getOrderNo());
// 查看此订单表里的所有订单项
System.out.println(o.getOrderItems());
}
报错:懒加载初始化失败,因为orderItems订单项在初始化的时候,session已经关闭了
解决方案:
public void testGet() {
Order order = new Order();
order.setOrderId(7);
order.setInitOrderItems(1);
Order o = this.orderDao.get(order);
System.out.println(o.getOrderNo());
// 查看此订单表里的所有订单项
System.out.println(o.getOrderItems());
}
由于在Order类中定义了加载方式,所以在上代码中设置为1
private Integer initOrderItems = 0;//0代表懒加载,1代表强制加载
在OrderDao中有方法:
public Order get(Order order) {
Session session = SessionFactoryUtil.getSession();
Transaction transaction = session.beginTransaction();
Order o = session.get(Order.class, order.getOrderId());
// 并且想要查询出关联的订单项的数据是,采用强制加载
if(o != null && new Integer(1).equals(order.getInitOrderItems())) {
// 强制加载订单o关联的订单项数据
Hibernate.initialize(o.getOrderItems());
}
transaction.commit();
session.close();
return o;
}
订单o关联的订单项数据全部呈现出来:
性能调优(解释了hibernate默认采用懒加载的原因)
实际场景:
1、只使用订单表的数据——希望懒加载
2、需要同时使用订单以及当单项表数据——不希望懒加载
三、一对多的子关联
我们看到树形节点 这张表:
SQL语句分析:
--查询出权限管理节点的相关信息
SELECT * FROM t_hibernate_sys_tree_node where
tree_node_id=6;
--当前节点的父节点信息(当前节点的父id是父节点的id)
SELECT * FROM t_hibernate_sys_tree_node where
tree_node_id=1;
--当前节点的子节点信息(当前节点的id是子节点的父id)
SELECT * FROM t_hibernate_sys_tree_node where
parent_node_id=6;
需要同时获取到当前节点以及当前节点的父节点的相关信息
TreeNodeDaoTest:
private TreeNodeDao treeNodeDao = new TreeNodeDao();
// 查询当前节点以及当前节点的父节点与子节点
@Test
public void testLoad() {
TreeNode treeNode = new TreeNode();
treeNode.setNodeId(6);
treeNode.setInitChildren(1);
TreeNode t = this.treeNodeDao.load(treeNode);
System.out.println(t);
System.out.println(t.getParent());
System.out.println(t.getChildren());
}
四、多对多的相关配置
就相当于两个一对多
这次我们需要书籍表以及书记类别表
对于书籍而言,它可以分为多种类别;对于书籍类别而言,它有多本书。
book.hbm.xml文件:
<?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="lv.com.two.entity.Book" table="t_hibernate_book">
<!-- <cache usage="read-only" region="com.zking.five.entity.Book"/> -->
<id name="bookId" type="java.lang.Integer" column="book_id">
<generator class="increment" />
</id>
<property name="bookName" type="java.lang.String"
column="book_name">
</property>
<property name="price" type="java.lang.Float"
column="price">
</property>
<!--
table:中间表,中间表的数据由框架维护
name:关联属性
inverse:(true)反转,也就是中间表的数据由另一张表维护。
(false)也就是中间表的数据由自己维护
两张表都是false时,数据会产生两条
两张表都是true时,数据不会产生
一张表为false,一张表为true,数据能够正常维护的key:当前表的主键在中间表的外键
many-to-many:当前表的主键在中间表查出另一表的外键
-->
<set table="t_hibernate_book_category" name="categories" cascade="save-update" inverse="false">
<!-- one -->
<key column="bid"></key>
<!-- many -->
<many-to-many column="cid" class="lv.com.two.entity.Category"></many-to-many>
</set>
</class>
</hibernate-mapping>
本期内容结束~