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 = “”

posted @ 2018-08-20 18:30  LDJ34  阅读(107)  评论(0编辑  收藏  举报