1.HQL多表操作: fetch: 不能和单独条件的with一起使用
①交叉连接 :
②内连接:
显示内连接 :
无条件: from 类名 别名 inner join 类中对方的引用名, 得到list<object[]>,两个表各自的信息
有条件: from 类名 别名 inner join 类中对方的引用名 with或where 类名.id = 2;
隐式内连接 : from Order where Order.c.id = 1;
迫切内连接 : select distinct 类名 from 类名 inner join fetch 类名.对方引用名
结果是from后面的对象,结果会出现重复,需要去重
③外连接:
左外连接 : from 类名 left outer join 类名.对方引用名; 得到的是数组;
迫切左外连接连接 : select distinct 类名 from 类名 left outer join fetch 类名.对方引用名; 得到对象
右外连接
2. 事物管理: 原子性, 一致性, 隔离性, 持久性 脏读, 不可重复读(update), 幻读(虚读),(insert)
隔离级别: read_uncommitted 读取未提交 , read_committed : 解决脏读 repeatable_read: 解决不可重复读
serialzable 串行化, 解决所有问题;不允许两个事物操作用一个目标数据
oracle : 默认是read_committed mysql: 默认是repeatable_read
3. hibernate中设置事物隔离级别:
在核心配置文件中: <property name=" hibernate.connection.isolation">可取值: 1 2 4 8
1.读取未提交 2.解决脏读 4.解决不可重复读 8. 串行化, 解决所有问题
4. hibernate 提供了三种管理session的方式:
①session对象的生命周期与本地线程绑定(threadlocal),保证了在同一个线程获得同一个session
1.在核心配置文件中,
<property name="hibernate.current_session_context_class">thread
2.使用getcurrentsession();
3.注意事项: 在事物关闭或提交,session对象也会关闭,所以不用再次session.close();
②.session对象的生命周期与JTA事物绑定(分布式事物管理)
③hibernate委托程序来管理session的生命周期
5.HQL优化:
1.使用参数绑定 2. 尽量少使用not 3.尽量使用where 来替换having 4.减少对表的查询
5.使用表的别名 6.实体的更新与删除
6. 一级缓存优化 : 大批量更新操作,可能会出现异常; 这时候可能手动清除一级缓存.session.evict和session.clear
7. 延迟加载, 只有真正使用该对象的时候才会加载.提供程序性能. 只有load方法能体现出以下配置.
①类级别检索延迟加载: a. 在映射文件中: 在 class标签中 lazy="true" b. 注解 在类上面@proxy(lazy=true)
如果将lazy设置false, 这时候load与get方法就一样了,都是立即检索.
②.关联级别检索: 查询到对象后,就能获得他的属性和方法,抓取策略
8.关于load和get方法使用时机, 处理大批量数据,用load
如果用load只查询出来对象,不使用,直接把对象返回,就需要对一个延迟对象进行初始化,
hibernate.initialize(对象的引用名);
9. 抓取策略; 指的是查找到某个对象后,通过这个对象去查询关联对象的信息时的一种策略
可以在多对一或多对多的 :
1. 在xml中: set标签中或many-to-one, one-to-many
属性有 fetch主要描述是sql语句的格式, lazy:控制sql语句何时发送
2. 在注解中: 在集合上, @Fetch() @lazycollection(),在many-to-one, one-to-many,@lazytoone();
3.迫切左外连接和左外连接区别:
迫切左外连接: left join fetch
list()方法返回的集合中存放的是实体对象的引用,而且每个实体对象关联的对象也都会被初始化,
因此也会存放所有关联对象的实体对象。
需要注意的是: 查询结果中可能会有重复数据,需要通过LinkedHashSet包裹一下去重,
然后再将其用HashSet包回原来类型。new ArrayList(new LinkedHashSet(目标对象))
左外连接: left join
采用这种检索策略的话,list()方法返回的集合中存放的是对象数组类型。
4.set上的fetch和lazy用于设置关联集合信息的抓取策略
@Fetch() 1.select 多条简单的sql(默认) 2. join 迫切左外连接 3.subselect将生成子查询的sql
@lazy 1.ture 延迟 (默认) 2.false 立即 3.extra 加强延迟(需要什么,就发送什么查询语句)
10. set上的fetch和lazy用于设置关联集合信息的抓取策略, 获取在一的一方如何查询多的一方.
①第一种组合: 会首先查询到客户信息,需要订单时候才会关联查询订单详情.
@Fetch() select 多条简单的sql
@lazy ture 延迟
②.第二种组合: 查询到客户信息,订单也会查询
@Fetch() select 多条简单的sql
@lazy false 立即
③.第三种组合: 查询到客户信息,订单不会查询出详细信息,当我们需要订单个数,只会统计个数,不会查询出订单详情
需要什么就会查询什么,不会多余查询.
@Fetch() select 多条简单的sql
@lazy extra 加强延迟
④第四种组合: lazy会失效,会使用立即查询.
@Fetch() join 迫切左外连接
@lazy 1.ture 延迟 (默认) 2.false 立即 3.extra 加强延迟
⑤第五种组合: 会延迟查询,先查询出所有的客户id, 然后订单的in(客户的id) ,子查询
@Fetch() subselect将生成子查询的sql
@lazy ture 延迟
⑥第六种组合: 会立即查询,先查询出所有的客户id, 然后订单的in(客户的id) ,子查询
@Fetch() subselect将生成子查询的sql
@lazy false 立即
⑦.第七种组合: 会加强延迟查询,先查询出所有的客户id, 然后订单的in(客户的id) ,子查询
@Fetch() subselect将生成子查询的sql
@lazy extra 加强延迟
11. 在many-to-one, one-to-many, 在多的一方如何查询一的一方
One的一方fetch与lazy;
@fetch: select 多条或一条简单的sql join 迫切左外连接(默认值)
@lazy 1.false 立即(默认值) 2.prox是否采用延迟,需要另一方类级别延迟策略来决定 3.no-proxy 不重要
12. 批量抓取 n+1问题
我们在查询多个对象的关联对象时,可以采用批量抓取方式来对程序进行优化,
在配置文件在set中或class中 batch-size属性来设置 , 底层就是where in(,,,)
注解: @Batchsize(size=数字)
注意: 一般在主表中设置. 如果要查子信息,在set上设置, 如果从子方来查询父方,也是在父方设置在<class>
父与子区别: 有外键的称为子表,关联方也就是父表.