Hibernate

  1. Hibernate总结
    Hibernate详解
    https://blog.csdn.net/lsh6688/column/info/lshhibernate
    Hibernate入门这一篇就够了
    https://www.cnblogs.com/mq0036/p/8522150.html
    SSH之Hibernate总结篇
    https://www.cnblogs.com/Java-web-wy/p/6533672.html
    hibernate学习笔记(一)
    https://www.cnblogs.com/zhengcheng/p/5014246.html
  2. Hibernate的三种状态:瞬时态、持久态、托管(即游离态)态及互相转化
    https://blog.csdn.net/HD243608836/article/details/77852842
    个人笔记:持久化状态对象的任何变化都会自动同步到数据库中,session的get/save/update/delete方法本质上是转换对象状态,get/save/update都会得到持久化状态的对象,从而将对象数据同步到数据库
  3. 一级缓存及快照/二级缓存
    hibernate的缓存和快照
    https://blog.csdn.net/jing_44944/article/details/40348107
    Hibernate的缓存技术详解
    http://www.cnblogs.com/xiaoming0601/p/5882980.html
    Hibernate的缓存机制
    https://blog.csdn.net/weixin_42669555/article/details/81049420
    Hibernate缓存简介和对比、一级缓存、二级缓存详解
    https://blog.csdn.net/u012518860/article/details/78256874
    hibernate 的缓存机制
    https://www.cnblogs.com/wy2185/p/5124443.html
    解析hibernate中的缓存
    https://www.cnblogs.com/HDK2016/p/7351727.html
    hibernate缓存机制详细分析
    https://www.cnblogs.com/xiaoluo501395377/p/3377604.html
    个人笔记:
    调用session的get方法,会发送sql语句到数据库,hibernate将得到的ResultSet结果封装到对象中返回,生成两个对象,一个放入session一级缓存中,另一个放入快照.
    此时再次调用get方法获取相同OID的数据时,会先在一级缓存中查找,若已存在,则直接返回此对象.否则再查询数据库.
    事务提交时,hibernate会对比缓存和快照中的两个对象(OID相同),若有更改,则发送sql update语句到数据库,若一样,则不操作数据库.
    持久化对象即存在于一级缓存的对象.
    瞬时->持久化:调用save方法
    游离->持久化:调用update方法
    saveOrUpdate:自动识别对象状态,将其放入缓存转为持久化对象.

new一个对象并手动赋id值,此时该对象处于什么状态?
若该id在数据库中不存在,则为瞬时状态
若该id存在数据库中,则为游离状态

持久化状态(即存在于session一级缓存中)的对象,会在事务提交时自动同步到数据库中

hibernate中save,update,saveOrUpdate的用法和区别
https://blog.csdn.net/wufaliang003/article/details/73997636
三种状态
注意:使用sessionFactory的getCurrentSession方法需要在主配置文件中进行配置
<property name="hibernate.current_session_context_class">thread</property>
通过getCurrentSession方法获得session对象,在事务提交时session会自动关闭,不要手动调用close关闭.

hibernate中的批量查询:
1.HQL(hibernate query language)查询:适合不复杂的多表查询
2.Criteria查询:适合单表条件查询
3.原生SQL查询:复杂的业务查询

一对多|多对一

配置文件表达

LinkMan.hbm.xml
<many-to-one name="customer" column="lkm_cust_id" class="Customer"  >
</many-to-one>
Customer.hbm.xml
<set name="linkMens" inverse="true" cascade="save-update"  >
	<key column="lkm_cust_id" ></key>
	<one-to-many class="LinkMan" />
</set>

级联操作cascade:
save-update 级联保存更新
delete:级联删除
all:save-update+delete
其本质上是简化操作,减少代码量(即不必对每个对象调用save或delete),可用save-update,不建议使用delete.

inverse:
在保存对象时,一对多关系的两方都会维护外键关系,一的一方在维护外键时,hibernate会发送不必要update语句提交外键id,降低性能.
其本质上是性能优化.
在一的一方配置文件中,配置inverse=“true”,反转,将维护外键关系交给另一方完成.
注意:外键字段在多的一方,多的一方不能放弃维护关系
原则:无论哪方反转,都必须要有一方负责维护关系
一对多关系中,一的一方放弃.因此代码中一的一方也不需要在set属性中add另一方的对象.
删除一的一方时,因为其放弃维护外键且被引用,所以无法直接调用delete删除,设置不反转可解决,会将多的一方的外键字段置为null.或设置cascade=“delete”,级联删除.

多对多(员工与角色)

表中表达
使用中间表,至少两列,都是外键列,分别引用两张表的主键
实体表达
两方都使用集合来表达拥有多个对方
员工对象中使用set集合存角色对象,角色对象中亦使用set集合存员工对象.
配置文件表达
set标签还需带上table属性,指中间表的表名
key的column属性填引用本对象的外建名
many-to-many

User.hbm.xml
<set name="roles" table="sys_user_role">
	<key column="user_id"></key>
	<many-to-many class="Role" column="role_id"></many-to-many>
</set>
Role.hbm.xml
<set name="users" table="sys_user_role" inverse="true" >
	<key column="role_id" ></key>
	<many-to-many class="User" column="user_id" ></many-to-many>
</set>

多对多中,维护外键会在中间表插入记录,若两方都维护,则会插入重复记录.
解决方法1:在代码中只在其中一方的set属性中赋值
或2.配置文件中使用inverse=“true”
在开发中遇到多对多关系,一定要选择一方放弃维护关系.
员工与角色中,角色一般已确定,后续录入员工时,对其设置set角色属性,即可完成外键维护,为中间表插入记录.因此选择角色放弃维护外键.

cascade属性同样可减少代码量,可用可不用.

查询总结:
1.oid查询-get
2.对象属性导航查询
3.HQL
4.Criteria
5.原生SQL

HQL

Query query = session.createQuery(String hql)
  query.list();
  query.uniqueResult();
  面向对象,hql语句中不会出现表中字段名
  “from Customer”
排序:
  “from Customer order by id asc/desc”
条件查询:
  “from Customer where id = ?”/ “from Customer where id = :id”
  query.setParameter(0,2) / query.setParameter(“id”,2)
分页查询:
  query.setFirstResult(0);
  query.setMaxResults(2);
统计查询:
  “select count(*) from Customer”
  “select sum(id) from Customer”
  “select avg(id) from Customer”
  “select max(id) from Customer”
  “select min(id) from Customer”
投影查询:
  只查询部分字段
  “select name from Customer”
  “select id,name from Customer” 用List<Object[]>接收结果
  “select new Customer(id,name) from Customer” 用List接收结果,相当于使用构造函数,因此需要创建对应的构造函数

多表查询(不常用)
内连接
  内连接
   “from Customer c inner join c.linkMens”
   用List<Object[]>接收结果,数组中有Customer和LinkMan对象
  迫切内连接
   “from Customer c inner join fetch c.linkMens”
   用List接收结果,linkMan会被封装到Customer的set中
外连接
  左外
  “from Customer c left join c.linkMens”
  左外迫切
  右外
  “from Customer c right join c.linkMens”
  右外迫切

Criteria

Criteria c = session.createCriteria(Customer.class);
List<Customer> list = c.list();
 条件查询
   c.add(Restrictions.idEq(2l));
   c.add(Restrictions.eq(“id”,2l));
 分页查询
   c.setFirstResult(0);
   c.setMaxResults(2);
 排序查询
   c.addOrder(Order.asc(“id”));
 统计查询
   c.setProjection(Projections.rowCount());

离线Criteria
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
拼装条件,与Criteria一致
dc.add(Restrictions.isEq(2l));
关联session
Criteria c = dc.getExecutableCriteria(session);

查询优化

类级别查询
懒加载
  get方法:立即加载.执行方法时立即发送sql语句查询结果
  load方法:默认为懒加载.执行方法时不发送sql语句,先返回一个代理对象,其具有查询数据库的功能,在使用该对象时才发送sql语句执行查询
  可以在配置文件的class元素上配置lazy属性来控制是否对类进行懒加载,若lazy=“false”,则load与get无区别
  为了提高效率,建议使用懒加载
关联级别查询
  集合策略(从Customer获取LinkMan) Customer.hbm.xml
   配置文件中set标签的lazy和fetch属性
   lazy决定是否懒加载
     true(默认值)延迟加载,在使用到集合属性时才查询数据库
     false立即加载
     extra极其懒惰,在懒加载相同,并且若只获得集合的size,只会用count语句查询
   fetch决定加载策略,即使用什么类型的sql语句加载集合数据
     select(默认值):单表查询
     join:多表查询 left outer join,一条sql语句查出所有字段,此时lazy属性失效,相当于立即加载
     subselect:子查询 “from Customer”
       懒加载下,当使用list集合中的set属性时,会使用子查询语句获取全部set数据
       立即加载下,获取customer集合时,即直接发送两条sql语句获取数据
       极其懒惰,使用size时只会用count语句查询
       
  关联属性策略(从LinkMan获取Customer) LinkMan.hbm.xml
   many-to-one标签的lazy和fetch属性
   lazy:
    false:立即加载
    proxy(默认值):由customer的类级别加载策略决定
   fetch加载策略
    select(默认值):单表查询
    join:多表查询 left outer join,一条sql语句查出所有字段,此时lazy属性失效,相当于立即加载

结论:fetch选择默认select,lazy选择默认true

no-session问题:懒加载下,数据对象返回到页面上才会进行查询,此时session已经关闭
扩大session的作用范围,filter会在请求到达servlet前先执行,整个流程完成之后(包括页面显示)还会再经过一次filter
filter前处理中,打开session,开启事务.执行完servlet\service\dao\jsp.后处理中关闭session,提交事务
spring提供的OpenSessionInViewFilter可解决该问题

批量抓取:set标签的batch-size="3"属性,抓取集合数量为3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值