Hibernate_02
Hibernate_02
勤劳的开发者px 发表于2个月前
Hibernate_02
  • 发表于 2个月前
  • 阅读 0
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 学生专属云服务套餐 10元起购>>>   

Hibernate的主键

主键的类别

  • 自然主键:与业务相关
  • 代理主键:与业务无关

主键的生成策略

  1. increment: 适用于short,int,long作为主键。数字主键

    Hibernate框架提供的一种主键增长机制.
    不是使用的数据库本身自动增长机制

    • 先进行查询:select max(id) from user;
    • 再进行插入:获得最大值+1作为新的记录的主键
    • 问题:不能在集群环境下或者有并发访问的情况下使用
  2. identity: 适用于short,int,long作为主键。数字主键

    使用在有自动增长数据库中,采用的是数据库底层的自动增长机制

    • 底层使用的是数据库的自动增长(auto_increment)
    • 适用于类型MySQL的数据库,具有增长功能类型的数据库
    • 问题:类似于Oracle数据库是没有自动增长,因此存在局限性
  3. sequence:适用于short,int,long作为主键。数字主键

    底层使用的是序列的增长方式

    Oracle数据库底层没有自动增长,想自动增长需要使用序列

    --创建序列
    create sequence seq_newsId
    increment by 1
    start with 1
    maxvalue 999999999;
    --查询序列
    select seq_newsid.nextval from sys.dual

    问题:适用于oracle类型没有自增长的数据库。
    MySQL类型的数据库可用,但是是通过表来模拟Oracle的序列行为,效率方面较于自增长偏低。

  4. uuid(掌握): 适用于char,varchar类型的作为主键。字符串主键

    使用随机的字符串作为主键

  5. native(掌握):适用于short,int,long作为主键。数字主键

    本地策略.根据底层的数据库不同,自动选择适用于该种数据库的生成策略.

    • 如果底层使用的MySQL数据库:相当于identity
    • 如果底层使用Oracle数据库:相当于sequence
  6. assigned(了解):主键的生成不用Hibernate管理了.必须手动设置主键

Hibernate持久化概念

持久化类

在Hibernate中,用来描述数据库表结构的类,称之为持久化类

  • Java类与数据库的某个表建立了映射关系.这个类就称为是持久化类
  • 持久化类 = Java类 + hbm的配置文件

持久化类定义规范

  • 遵循JavaBean定义规范
    • 类是公有的
    • 需要一个无参的构造函数
    • 属性是私有的,需要给拱getter和setter方法进行访问属性
  • 必须用一个属性描述数据库表的主键
  • 主键属性的类型必须是引用类型,且需要实现Serializable接口
  • 属性的类型尽量都是引用类型

OID的概念(Object Id)

将持久化类中用来描述表主键的属性,称之为OID属性。
持久化对象会被session进行管理,session管理过程中通过OID进行查找唯一对象,作用是用来标记唯一对象的。

持久化对象的状态

由持久化类创建的对象就是持久化对象。
Hibernate为了管理持久化对象:将持久化对象分成了三个状态

  • 瞬时态:Transient Object

    没有持久化标识OID, 没有被纳入到Session对象的管理

  • 持久态:Persistent Object

    有持久化标识OID,已经被纳入到Session对象的管理

  • 游离态:Detached Object

    有持久化标识OID,没有被纳入到Session对象的管理

持久化对象的状态的转换

hibernate底层实现过程中,定义的三种状态主要方便开发人员调用session的API。

hibernate中持久态对象是具有自动更新数据库的能力。这个也是底层实现为开发人员提供的便利操作。

瞬时态

没有持久化标识OID, 没有被纳入到Session对象的管理

  • 创建瞬时态的对象(new对象)
User user = new User()
  • 瞬时态对象转换持久态(通过session操作对象)
session.save(obj)

持久态

有持久化标识OID,已经被纳入到Session对象的管理

  • 获得持久态的对象
session.get();
session.load();
  • 持久态转换成瞬时态对象
session.delete();  

比较有争议的,进入特殊的状态(删除态:Hibernate中不建议使用的

游离态

有持久化标识OID,没有被纳入到Session对象的管理

  • 持久态对象转成游离态对象
session.close();
session.evict(obj);
session.clear();

 

hibernate的缓存

缓存概述

缓存就是一块内存空间。将数据源(数据库或者文件)中的数据读取出来存放到缓存中,再次获取的时候 ,直接从缓存中获取,这样可以提升程序的性能!

Hibernate的二级缓存

  • 一级缓存:session对象的缓存,自带的不可卸载的.一级缓存的生命周期与session一致。
  • 二级缓存:sessionFactory的缓存,默认没有开启,需要手动配置才可以使用的。二级缓存可以在多个session中共享数据。

Session的缓存

  • Session接口中,有一系列的java的集合,这些java集合构成了Session级别的缓存(一级缓存).将对象存入到一级缓存中,session没有结束生命周期,那么对象在session中存放着
  • 内存中包含Session实例 –> Session的缓存(一些集合) –> 集合中包含的是缓存对象
  • 证明一级缓存的存在,编写查询的代码即可证明
    • 在同一个Session对象中两次查询,可以证明使用了缓存

Hibernate的快照机制

  • 数据发生变化时在commit时会自动进行数据同步操作

Hibernate的事务

事务的概念

事务就是逻辑上的一组操作,组成事务的各个执行单元,操作要么全都成功,要么全都失败.

事务的特性

  • 原子性: 事务不可分割.
  • 一致性: 事务执行的前后数据的完整性保持一致.
  • 隔离性: 一个事务执行的过程中,不应该受到其他的事务的干扰.
  • 持久性: 事务一旦提交,数据就永久保持到数据库中.

隔离性

  • 脏读: 一个事务读到了另一个事务未提交的数据.
  • 不可重复读: 一个事务读到了另一个事务已经提交的update数据,导致多次查询结果不一致.
  • 虚读: 一个事务读到了另一个事务已经提交的insert数据,导致多次查询结构不一致.

隔离级别

  • Read uncommitted     未提交读: 读的问题都有可能发生
  • Read committed      已提交读: 可以避免脏读,但是不可重复读,虚读都有可能发生
  • Repeatable read      可重复读: 避免脏读,不可重复读.但是虚读是有可能发生
  • Serializable       串行化:以上读的情况都可以避免

Hibernate配置隔离级别

需要在hibernate.cfg.xml的配置文件中通过标签来配置

<property name="hibernate.connection.isolation">4</property>

取值

  • 1: Read uncommitted isolation,未提交读
  • 2: Read committed isolation,已提交读,解决脏读。
  • 4: Repeatable read isolation,可重复读
  • 8: Serializable isolation,串行化 

Hibernate的Session绑定

配置session绑定到当前线程

  • 在hibernate.cfg.xml文件中,添加属性

    <property name="hibernate.current_session_context_class">thread</property>
    
  • 通过SessionFactory的getCurrentSession()方法获得Session

    Session session = sessionFactory.getCurrentSession();
    

Session获取方式的区别

调用getCurrentSession()方法时,会判断当前线程中是否绑定了session。

  1. 如果绑定了,直接返回线程中绑定的session
  2. 如果没有绑定,先去创建一个session,然后讲session存储到当前线程中,再返回。

调用openSession()方法时,只会创建一个新的session,且不会存储到当前线程。

通过getCurrentSession()方法获得的session,无需调用close方法释放资源。

  1. transaction.commit();
  2. transaction.rollback();时,
  3. 会自动调用session.close()释放资源             

通过openSession()方法获得的session需要手动释放资源

QBC查询

QBC: Query By Criteria.按条件查询

常用条件查询

//创建QBC条件查询
Criteria criteria = session.createCriteria(Class);
//添加条件
criteria.add(Restrictions.api...);
//查询出结果
List list = criteria.list();
运算符 条件API 描述
= Restrictions.eq() 等于
> Restrictions.gt() 大于
< Restrictions.lt() 小于
>= Restrictions.ge() 大于等于
<= Restrictions.le() 小于等于
between Restrictions.between() 在某个范围内
like Restrictions.like() 模糊查询
in Restrictions.int() 在…中
and Restrictions.and() 并且
or Restrictions.or() 或者

排序查询

//创建QBC条件查询
Criteria criteria = session.createCriteria(Class);
//添加排序
criteria.addOrder(Order.api...);
//查询出结果
List list = criteria.list();
运算符 条件API 描述
desc Order.desc() 降序
asc Order.asc() 升序

分页查询

//创建QBC条件查询
Criteria criteria = session.createCriteria(Class);
//设置下标
criteria.setFirstResult(0);
//设置每页显示的数量
criteria.setMaxResults(3);
//查询出结果
List list = criteria.list();

 

共有 人打赏支持
粉丝 2
博文 47
码字总数 96234
评论 (0)
×
勤劳的开发者px
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: