hibernate入门(3)_md
一.Hibernate多表关系
java表达存在方向性
单项一对多:一的可以找到多的
单项多对一:多的可以找到一的
双向一对多:互相可以找到
1.一对多
在一的方面添加set或者list集合,同时配置 xml文件
<!-- 将一对多关系配置 -->
<!--
name :集合属性名
column : 外键类名
class : 属性关联类名
-->
<set name="linkmans">
<key column="lkm_cust_id"></key>
<one-to-many class="Linkman"/>
</set>
在多的一方面添加一的对象,同时配置xml文件
<!-- 多对一关系 -->
<many-to-one name="customer" column="lkm_cust_id" class="Customer"></many-to-one>
2.进阶
2.1(级联保存或更新)
cascade="save-update"
<set name="linkmans" cascade="save-update">
<key column="lkm_cust_id"></key>
<one-to-many class="Linkman"/>
</set>
<many-to-one name="customer" cascade="save-update" column="lkm_cust_id" class="Customer"></many-to-one>
2.2 级联删除(简化操作)
普通删除时,删除一的方面不会删除多的方面,会把多的方面的外键设为null;
配置级联删除:
删除一方时,另一面也会删除
<set name="linkmans" cascade="delete,save-update">
<key column="lkm_cust_id"></key>
<one-to-many class="Linkman"/>
</set>
<many-to-one name="customer" cascade="delete,save-update" column="lkm_cust_id" class="Customer"></many-to-one>
2.3 inverse = “true”(性能优化)
放弃对外键的维护
一对多关系式,多的一方不能放弃维护关系
<set name="linkmans" cascade="delete,save-update" inverse=“true”>
<key column="lkm_cust_id"></key>
<one-to-many class="Linkman"/>
</set>
注意:
当一的一方放弃关系的维护时,删除一的一方的数据就会报错,因为一的一方被引用
:解决方法:添加级联删除
当一的一方没有放弃关系维护的时候,不会报错,默认会把外键置为空,配置级联删除时就会级联删除
3. 多对多:
<!--
name : 属性名
table: 第三方表的名称
key : 本表添加到第三方标的字段名
many-to-many:配置对方属性
-->
<set name="users" table = "sys_user_role">
<key column="role_id"></key>
<many-to-many class="User" column="user_id" ></many-to-many>
</set>
多对多操作时,如果时双向保存数据,某一方必须放弃主键维护,否则报错
org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1-1' for key 'PRIMARY'
如果是级联操作时,使用级联删除,双方都不能放弃主键维护,否则报错(外键删除报错)
二.Hibernate 多表查询
五种查询方式
OID:
Query:
Criteria:QBC查询
SQLQuery:跨数据局的特性会消失
对象导航查询:
1.hql增强查询
1.1 object
查询Customer对象数据
// String hql = "from Customer";
查询所有数据
String hql = "from java.lang.Object";
1.2条件查询
String hql = "from Customer c where c.cid > ?";
query.setParameter(0,10);
String hql = "from Customer c where c.cid > :cid";
query.setParameter("cid",10);
1.3函数查询
String hql = "select count(*) from Linkman l group by l.customer";
1.4投影查询
String hql = "select l.lkm_name from Linkman l";
//投影构造查询
String hql = "select new Linkman(l.lkm_id,l.lkm_name) from Linkman l";
2.QBC查询
2.1条件查询
Criteria criteria = session.createCriteria(Linkman.class);
SimpleExpression gt = Restrictions.lt("lkm_id", 5L);
SimpleExpression lt = Restrictions.gt("lkm_id", 10L);
2.2排序查询
Criteria criteria = session.createCriteria(Linkman.class);
criteria.addOrder(Order.desc("lkm_id"));
//多条件
Criteria criteria = session.createCriteria(Linkman.class);
criteria.addOrder(Order.desc("lkm_name"));
criteria.addOrder(Order.asc("id"));
2.3统计查询
Criteria criteria = session.createCriteria(Linkman.class);
ProjectionList projectionList = Projections.projectionList();
PropertyProjection projection1 = Projections.groupProperty("lkm_id");
Projection projection2 = Projections.rowCount();
projectionList.add(projection1);
projectionList.add(projection2);
2.4离线查询
在其他层处理查询条件,向下传递查询条件即可
//servlet 层
// where
SimpleExpression gt = Restrictions.lt("lkm_id", 5L);
SimpleExpression lt = Restrictions.gt("lkm_id", 10L);
LogicalExpression or = Restrictions.or(gt,lt);
//group
PropertyProjection projection1 = Projections.groupProperty("customer");
Projection projection2 = Projections.rowCount();
ProjectionList projectionList = Projections.projectionList();
projectionList.add(projection1);
projectionList.add(projection2);
DetachedCriteria dc = DetachedCriteria.forClass(Linkman.class);
dc.add(or);
dc.setProjection(projectionList);
//dao层
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
Criteria criteria = dc.getExecutableCriteria(session);
3.HQL多表查询
3.1.内连接
String hql = "from Linkman d inner join d.customer";
会封装成多个对象
3.2迫切内链接
String hql = "from Linkman d inner join fetch d.customer";
封装成一个对象
String hql = "select distinct d from Customer d inner join fetch d.linkmans";
去重
4.抓取策略
4.1延迟加载
失效方法:1.final修饰 2.lazy = “false”
lazy:类级别的延迟加载 或者 关联对象的延迟加载
4.2关联对象的抓取策略合延迟加载
set上的配置
a. fetch的取值:抓取策略
(1) select.默认值,发送普通的select语句
(2) join:发送迫切左外联接去查询。
(3) subselect。发送一条子查询语句查询其关联对象.(查询多个对象,才能体现)
b. lazy的取值:
(1) true。默认值,采用延迟加载
(2) false.不采用延迟加载
(3) extra. 极其懒惰的
many-to-one上的配置
a. fetch的取值:
(1) select.默认值,发送普通的select语句
(2) join:发送迫切左外联接去查询
b. lazy的取值:
(1) proxy。默认值,是否延迟取决于一的一方类<class>上lazy属性
(2) false.不采用延迟加载
(3) no-proxy:不用研究
使用jion时lazy失效
4.3批量抓取
在set上添加 或者 一的一方的class上面
batch-size = “”