hibernate笔记

来源:互联网 发布:淘宝上的红酒是真的吗 编辑:程序博客网 时间:2024/06/07 22:41

框架

  • 生命周期管理

  • 查询定位

  • 配置器

提供静态配置策略。让用户可以控制服务的细节部分。如,资源在哪里等等 
  • 依赖解析
分析组件之间的依赖关系,实现相互通讯,动态管理
  • 不同协议层的通讯支持
与不同的系统(平台)进行通讯,如用JDBC和数据存储数据库,用RMI分布组件 
  • 扩展支持

  • DAO层框架

将查询结果封装为bean类,实现面向对象的操作对条件查询的自动组合

CRM(customer raletionship management)

概述

功能模块

客户信息管理联系人管理商机管理统计分析系统管理综合查询

hibernate

概述

Object relational mapping 对象关系映射

利用描述对象和数据库表之间映射的元数据,自动将java程序中的对象持久化到关系型数据库中通过操作java对象,完成对数据库的操作
  • 持久层框架
  • 对jdbc进行轻量化封装,简化代码,减少内存消耗
  • 简化dao层编码
  • 支持多对多
  • 可扩展

配置

POJO模式(plain old java object)

pojo类包含与数据库相关属性,通过getset方法访问

映射文件

xml文件配置映射一张表对应一个pojo类

核心配置文件

配置参数
配置参数的来由:hibernate-release-5.0.7.Final\project\etc\hibernate.properties配置数据库连接和hibernate运行所需要的各个属性的值    数据库连接参数    方言      <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> **MySQL5Dialect**    显示sql语句    自动建表:none(默认) create create-drop update validate(不建表,结构不匹配报错)    <property name="hibernate.hbm2ddl.auto"></property>    导入mapping文件
xml与properties对比
  • properties文件
    • .properties文件主要是以key-value键值对的形式存在。
    • .properties只能赋值,不能够进行其他的操作。
  • xml文件
    • 改变底层配置不需要改变和重新编译代码,只需要修改xml中的属性
    • 只有在修改了接口后才需要重新编译。 因为服务器在运行的时候会重新加载web.xml文件。
    • mapping resource标签加载映射文件
    • .xml文件主要是树形结构。
    • .xml格式的文件要比.properties格式的文件更灵活一些
    • .xml格式的文件可以有多种操作方法,例如添加一个属性,或者做一些其他的定义等。

运行机制

configuration读取配置
  • 读取配置文件
  • 创建sessionFactory对象
  • properties配置下读取xml映射文件
sessionFactory读取映射
  • configuration类完成任务

  • 重量级,不能随意创建和销毁

  • 一个数据源对应一个sessionFactory

  • 作用

- 负责hibernate的初始化和建立session对象- 保存自动生成的sql语句,映射数据和可重复数据- 保存配置的映射关系,维护二级缓存- 提供session连接,openSession(手动关闭),getCurrentSession(绑定线程)
  • 抽取工具类
原因:重量级资源,一个项目只需要一个具体业务逻辑不使用SessionFactory
  • 重量级的理解
相对于Sesion而言是重量级一个数据库对应一个SessionFactorySessionFactory存放了大量预定义的SQL语句以及映射元数据,需要很大的缓存轻量级是指它的创建和销毁不需要消耗太多的资源,意味着可以在程序中经常创建和销毁session 的对象
session管理持久化对象
  • 单线程对象
  • 轻量级

  • 作用

- 开启事务- 创建pojo对象并添加数据- 通过save,update,saveOrUpdate方法保存到数据库,delete删除- get,load根据主键查询- createQuery和createSQLQuery,条件查询
Transaction管理事务
  • beginTransaction
  • commit
  • rollBack
  • 数据库对事务的管理以commit为准,rollback后如果没有关闭,数据库默认commit了

持久化类

  • 提供无参构造,反射生成实例

  • 私有属性,提供get和set方法

    • java规范
  • 属性使用包装类Integer\Double等

    • 默认值不同, int:0, Integer:null。 数据库里面,0值和null值不同。
  • oid字段与表主键对应

    • 判断是否同一个java对象,使用地址值
    • 判断是否同一个持久化对象,使用oid的值
  • 持久化类尽量不用final修饰

    • 延迟加载机制中使用动态代理生成代理对象,final修饰无法执行此机制
    • hibernate动态代理使用cglib机制,生成的是继承被代理类的代理子类,final类无法被继承

瞬时态

  • 与数据库无关
  • 仅用于携带数据
  • 没有oid

持久态

  • 存在oid标识
  • 加入到了session缓存中
  • session没有关闭
  • 事务未提交前变为持久态
    • 拥有持久化标识,oid与数据库建立起了关联
  • 自动更新数据库

脱管态

  • session被关闭
  • 持有oid,与数据库关联
  • evict方法,清除session中某个对象
  • close,关闭session
  • clear,清除session中所有对象

三态转换

  • new对象(瞬时态)–>session保存(持久态,持有了oid,可以未提交)–>session关闭,托管态
  • session通过get方法,直接成为持久态

主键生成策略

主键分类

  • 自然主键
    • 失去了对主键的控制权
  • 代理主键(id)(推荐)
    • 使用没有任何意义的一个字段
  • 主键参数是serializable类型
    • 主键写进数据库执行的是io操作,必定是serializable对象

hibernate的主键策略

  • increment

    • 不能在集群下使用
    • 适合代理主键
    • 不能在多线程下使用
    hibernate内部操作select max(id) from table,将id+1作为候选主键  
  • identity

    • 适合代理主键
    • 适合int,long等类型
    • 由底层数据库支持,要求底层数据库支持自增长类型。
  • sequence

    • 适合代理主键
    • 适合int,long等类型
    • 由底层数据库支持,要求底层数据库支持序列类型。
  • native

    • 根据底层数据库自动匹配
    • 如果支持identity,匹配identity
    • 如果支持sequence,匹配sequence
    • 适合int,long等类型,不支持字符串类型
  • uuid

    • 比整数型占用更多空间
    • hibernate底层为oid分配uuid,覆盖service或web层指定的oid
  • assigned

    • 适合自然主键,需要手动指定(默认值)

缓存

缓存原理

利用高速存储区域,保存低速存储区域的数据,从而提高访问速度数据库执行的是io操作,io操作是对硬盘的操作,硬盘操作读写数据比内存操作慢弊端:高速存储区空间,小于低速存储区缓存替换算法:    - 先入先出:最先保存的数据,最先被替换。    - 命中优先:查询次数少的(命中率低的),最先被替换         - 命中:缓存的数据被访问一次为命中一次

一级缓存

概述
  • Session缓存,第一次从数据库取值,并放入缓存,再次取值由缓存提供,减少对数据库的访问次数
内部结构
缓存区数据放入快照区commit提交事务,判断缓存区数据与快照区是否相同,不同则执行update方法
代码实现
  • map集合存放缓存对象,生命周期与Session相同,key为oid
  • close清空缓存

二级缓存

  • 生命周期与SessionFactory相同
  • 需要手动配置
  • 应用程序的缓存
    • 可以被应用范围内的所有事务共享访问
    • 应用范围的缓存可以使用内存或硬盘作为存储介质
    • 缓存的生命周期依赖于应用的生命周期
  • 非集群环境下可用
  • 集群环境下不使用,用redis代替

事务管理

事物的特性

  • 原子性
  • 一致性
  • 隔离性
  • 持久性

事物的并发

  • 脏读
  • 不可重复读
  • 虚读幻读

事物的隔离级别

  • readUncommited
  • read commited
  • repeatable read
  • serializable

hibernate管理办法

  • 代码操作
    • beginTransaction
    • commit
    • rollback
  • 配置事务隔离级别
    • hibernate.cfg.xml
  • 管理session

    • 业务层获取传递给dao层

    • session绑定线程

    ThreadLocal绑定线程的原理:ThreadLocal是一个Thread的本地变量,当一个线程访问到ThreadLocal时,会得到一个独立的ThreadLocal副本,这个副本与线程绑定,再将要与线程绑定的资源,放入这个副本变量的集合中,就实现了资源与线程的绑定这个办法只能实现线程之间的隔离,不能实现线程之间的通信
  • hibernate的绑定办法
    • thread
    • thread
    • getCurrentSession方法获得Session对象
    • 事务提交后Session自动关闭
    • 再次调用getCurrentSession方法后,获取的是一个新的Session
    • jta
    • session生命周期与jta绑定
    • managed
    • 委托程序管理session(如:spring)
  • 不需要rollback
    • 所有修改,都是针对一级缓存区,没有向数据库发送update/delte/insert 语句
    • hibernate调试没有异常才发送sql语句

检索

导航对象图检索

OID检索

  • 利用session的set和load方法加载对象

  • get和load的区别

    get是执行立即发送sql语句,load 方法延迟加载,只有在真正使用数据的时候才发送

HQl语句

  • 可以设定查询条件
  • 支持投影查询(检索对象部分属性)
  • 支持分页查询
  • 支持分组查询
  • 提供内置聚集函数
  • 能够 调用用户定义的sql语句
  • 支持嵌套查询
  • 支持动态绑定参数
获取hibernate的Session对象编写HQL语句session.createQuery调用Query的set方法设置参数调用Query的list或uniqueResult方法查询
迫切内连接(fetch关键字)
  • 普通内连接将查询的数据进行一层封装,返回集合元素为多个对象的数组
  • 迫切内连接将查询的数据进行多层封装,将从对象放入主对象的集合中
    • select distinct x from Department x inner join fetch x.employees
  • 手动去重distinct
迫切左外连接
  • from Product p left outer join fetch p.category where p.category.cid=1

QBC(query by criteria)

  • 完全面向对象
  • hibernate核心查询对象
  • 主要针对单表操作
  • 离线条件检索(detachedCriteria)
    • 可以在其他层生成DetachedCriteria对象,封装数据,向下传递参数
    • DetachedCriteria中的约束条件添加后不会自动清除,需要手动置为null
    • ObjectOutputStream方法实现detachedCriteria的克隆效果
获取Session获取criteriaRestriction静态创建criterion条件对象add方法向criteria中添加criterionProjects静态创建聚合函数对象setProjection方法向criteria中添加ProjectOrder静态创建Order对象addOrder方法向criteria中添加Orderlist或uniqueResult方法查询

SQL查询

  • 手动封装java对象
    • addEntity
  • 用于使用底层数据库的sql方言,生成特殊sql语句

映射关系

一对一

class A{  B b;}class B{  A a;}

一对多

  • 实例关系
Class A{    Set(B) bs;}Class B{  A a;}
  • 映射文件

    <Set>标签<set name = "linkmans"><key column="lkm_cust_id"></key>column描述外键<one-to-many class="cn.itcast.hibernate.domain.Linkman"></>class属性描述关联类<set>

多对多

  • 不建议使用联合主键,使用没有意义的字段/(代理主键)
  • 实例关系
Class A{  Set(B) bs;}Class B{ Set(A) as;}
  • 映射文件

    “`
    标签
    table中间表
    column对象在中间表中外键的名称

list和set的选用
  • list映射中要求提供index标签column字段(id),进行count查询时,hibernate默认查询的是max(id)+1
  • list映射自动生成表时,会将代理主键id与某个外键作为联合主键
  • Set集合无序(符合数据库特点),不重复
  • list在配置文件中要求配置索引列,该字段如果是主键,而有多个list执行了保存,则会出现索引重复异常(线程问题)

级联操作

curd操作,配置cascade属性
  • 级联查询
    • 配置一对多\多对多关系之后,自动级联查询,配置延迟加载会暂缓sql语句的发送
  • 级联保存
    • cascade配置:save-update
  • 级联删除
    • cascade配置:delete
    • 直接发送delete的sql语句
    • 如果有外键关联,需要先get/load获得完整对象
外键维护
  • inverse:true放弃,false不放弃
  • 双向外键维护导致进行了两次维护
  • 一对多,一表放弃维护
  • 多对多,主动方维护外键,被动方放弃外键维护权
  • 放弃外键维护结果
    • 一对多:一方保存,多方不生成外键
    • 多对多:一方保存,不生成中间表
    • 多方(未放弃外键维护权)不受影响

抓取策略

关联对象的抓取策略
  1. set标签
    • fetch的取值:抓取策略
      • select.默认值,发送普通的select语句
      • join:发送迫切左外联接去查询(lazy失效)
      • subselect。发送一条子查询语句查询其关联对象.(查询多个对象,才能体现)
  2. many-to-one标签
    • fetch的取值:
      • select.默认值,发送普通的select语句
      • join:发送迫切左外联接去查询
      • 注意:1的一方的配置先取消

延迟加载(lazy load)

延迟加载定义
在真正需要数据的时候,才执行数据加载操作。Hibernate从数据库获取某一个对象数据\对象的集合属性值\所关联的另一个对象时,创建一个代理对象来代表这个对象这个对象上的所有属性都是默认值;只有在真正需要使用该对象的数据时才创建这个真实对象,真正从数据库中加载它的数据,
  • 类级别的延迟加载
    • 查询某个对象时,是否延迟,标签上配置lazy属性,默认值是:ture,默认延迟加载。
    • 一般采用默认值,如果使用立即加载,调用get()方法即可。
  • 关联级别的延迟加载
    • 查询一个对象的关联对象时,是否延迟。在或上配置延迟。
    • hibernate关联对象默认采用延迟加载。可以避免一些无谓的性能开销
    • many-to-one标签
    • lazy的取值:
      • proxy。默认值,是否延迟取决于一的一方类上lazy属性
      • false.不采用延迟加载
      • no-proxy:不用研究
    • set标签
    • lazy的取值:
      • true。默认值,采用延迟加载
      • false.不采用延迟加载
      • extra. 极其懒惰的
抓取策略和延迟加载的区别
fetch: 抓取策略。确定查询关联对象,使用那种方式(SQL语句)lazy: 延迟加载。确定什么时候发送SQL语句,查询关联对象
批量抓取
  • batch-size
    • 底层sql语句变成了select * from table where column in(?,?);

原创粉丝点击