Hibernate深入

来源:互联网 发布:淘宝手机地址转换 编辑:程序博客网 时间:2024/06/07 03:39

1.no-session 问题

1.1 no-session问题的产生
异常名称:org.hibernate.LazyInitializationException: could not initialize proxy - no Session1、no-session问题产生的原因是获取数据使用延迟加载数据的方式,当使用数据前关闭session的,再使用数据时,数据不会加载,进而报错
1.2 解决no-session问题
1、在session关闭之前,直接使用数据,这时数据会加载完成,此后再使用数据就是完整数据
1.3 数据的抓取策略
提高执行效率以及解决no-session的问题常用的抓取策略抓取策略可以配置在类上,表示类的抓取策略,也可以配置到set或者one-to-many等上表示对方的抓取策略lazy属性在one-to-many中有三个属性   false、proxymany-to-many 有三个属性  false,true,extra1、set节点中配置抓取策略    fetch:"join" 抓取时使用左外连接       使用join可以提高查询效率,因为执行的sql语句相对较少    fetch:"select"  抓取时使用多条SQL语句    相比于join效率低一些    使用HQL/SQL查询 fetch="join"失效,lazy属性有效,因为HQL和SQL已经指定了语句,按指定的语句操作    使用get/load或者QBC 查询时,使用hibernate底层的语句查询   lazy属性无效,fetch属性有效        lazy="false"是否懒加载,延迟加载   false表示不延迟加载  true表示延迟加载    extra  极其懒惰,除查询属性外,查询其他的内容,是不查询属性。    lazy="proxy"   代表代理,就是由对方来执行抓取策略,也即由对方的抓去策略来执行    fetch决定的是sql语句的格式 ,lazy决定的是sql语句出现的时机2、many-to-one   节点中配置抓取策略抓取策略是当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候, Hibernate如何获取关联对象的策略。抓取策略包括:    查询时机:延迟加载、立即加载    查询方式:单表查询、多表查询抓取策略可以在hbm映射文件中声明,也可以通过在HQL 语句定义。QBC、get查询方式使用hbm映射文件中定义的抓取策略进行。Hql不能使用hbm文件中定义的抓取策略,它通过迫切内连接、迫切外连接方式实现抓取策略。1.3.2   类抓取策略    设置类级别抓取策略 ,修改 hbm文件 <class>元素 lazy属性,默认为true延迟加载,修改为false 立即加载。    如果修改为false则get方法和load方法一样都是立即加载。     如果采用默认true,get立即检索,load延迟检索。1.3.3   关联抓取策略    当通过对象导航方式查询关联对象时可以设置数据抓取策略。比如:调用 customer.getCstLinkmans()获取cstLinkmans信息时通过抓取策略修改数据的获取方式。1.3.3.1 一对多、多对多<set> 元素提供 lazy属性 和 fetch 用于设置 抓取策略Fetch(默认select) Lazy(默认true)    策略join    True    采用迫切左外连接join    false   采用迫切左外连接select  true    延迟检索select  false   立即检索   fetch=join fetch="join"实现批量抓取。如果fetch设置为join,lazy不起作用。get、QBC、HQL都支持fetch方式。get和QBC方式会采用左外连接SQL方式,fetch=join时会忽略lazy。测试:查询客户关联查询联系人,设置fetch=join   fetch=select (默认值 )生成多条SQL语句lazy=true 延迟加载 (默认值 )lazy=false 立即加载 测试:查询客户关联查询联系人,设置fetch=select lazy=true、fetch=select lazy=false1.3.3.2 多对一多对一, hbm采用 <many-to-one>元素,提供lazy属性和fetch属性,用来配置抓取策略 Fetch(默认select) Lazy(默认proxy)   策略join    True    采用迫切左外连接join    false   采用迫切左外连接select  false   立即检索select  proxy   按照class中设置lazy执行Class中设置为 true则为延迟加载Class中设置为false则为立即加载   fetch=join 采用迫切左外连接查询测试:查询客户关联查询客户来源,设置fetch=join   fetch=select (默认值)产生多条SQL语句     Lazy=false表示立即加载    lazy=proxy表示:    按照class (被关联对象的class) 中设置lazy执行    Class中设置为 true则为延迟加载    Class中设置为false则为立即加载测试:查询客户关联查询客户来源,设置fetch=select lazy=proxy、fetch=select lazy=false

3 批量策略

N+1问题:    比如说查询customer表时,查询所有cutomer,会输出一条sql语句,同时查询其对应的linkman时,会每条customer都查询一次sql语句,会产生N+1条sql语句,    效率相对较慢,可以使用批量增加策略解/决方案在 set节点上配置batch-sezi="10",这样表示一次查询10个客户的联系人,减少了SQL语句,大大提高执行了效率

4 HQL语句的加强

1、String hql = "from Customer" 语句正确  返回的是所有Customer对象2、String hql="from Customer where custId=3" 语句正确查询为id=3的Customer对象3、String hql ="select * from Customer" 语句错误,因为类中没有*对应的属性4、String hql = "select custName from Customer" 语句正确 返回的结果是 custName  String类型5、String hql = "select custId,custName from Customer" 语句正确,返回的结果是数组,第一个元素为custID,第二个为custName6、String hql = "select new Customer() from Customer" 语句错误7、String hql = "select new Customer(custId) from Customer" 错误,必须要有对应的构造函数8、String hql = " from Customer as c order by c.custId";正确,返回的是Customer对象并排序9、String hql = "from java.lang.Object" 多态查询,查询所有的持久化对象10、String hql = " from Customer c inner join c.linkmans" 语句正确、显示外连接11、String hql = "from Customer c,LinkMan l where c.custId=L.customer.custId"语句正确、隐式外连接  12、String hql = " from Customer c inner join LinkMan l on c.custId=L.customer.custId" 语句错误    进行内联接操作时,虽然查询了linkman,但并没有将linkman赋值到customer中,使用连接查询,返回的是数组,两个元素分别为对应的对象13、配合fetch迫切 使用  String hql = " from Customer c inner join fetch c.linkmans"    将查询到的linkman封装到对应的customer中,返回的结果是customer对象14、 String hql = "  from Customer c left  join fetch c.linkMans";使用左外连接进行查询的时候如果一个客户有多个联系人,这个客户就会    查询多次,使用distinct去重就可以了  String hql = "select distinct c from Customer c left join fetch c.linkMans ";
0 0
原创粉丝点击