Hibernate核心接口(图片)
Configuration
概述:Configuration 类负责管理Hibernate 的配置信息。它包括如下内容:
1 Hibernate运行的底层信息:数据库的URL、用户名、密码、JDBC驱动类,数数据库据库Dialect,连接池等。
2 数据库的特性信息
3 Hibernate映射文件(*.hbm.xml)。
Hibernate配置的两种方法:
属性文件(hibernate.properties)。
调用代码:Configuration cfg = new Configuration();
Xml文件(hibernate.cfg.xml)。(推荐使用)
调用代码:Configuration cfg = new Configuration().configure();
SessionFactory
作用:
1 创建session
2 作为二级缓存,提高效率,存放经常查看但不经常修改的数据,例如,用户名,密码
3 生成全局事务,可以对session里的所有事务做确认
创建:
通过Configuration创建
SessionFactory factory=cfg.buildSessionFactory();
使用特点:
原则上,一个数据库使用一个session工厂
session工厂:线程安全,可被多个线程共享,创建耗时,通常在初始化的时候创建(web项目中推荐使用listener,java项目中使用静态全局变量,使用静态初始化块进行初始化)
Session(持久化管理器)
作用:
1 ORM
2 作为一级缓存(不需要配置)
3 管理事务
4 管理连接,采用dbcp连接池
创建:
由工厂创建
session=factory.openSession();
特点:线程不安全,使用完一定要关闭,多线程的时候采用绑定技术
Transaction(事物)
概念:数据库对存储或修改数据的确认操作
特性:一致性,原子性,持久性,隔离性
原子性:一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
事务种类:
本地事务(jdbc事务):本地的一个数据库的操作
跨资源事务(jta事务):转账的时候两个账户的金额要同时变化
事务请求代理:用一个事务管理多个事务(二次提交,若第一次提交没有回滚,就再次提交;若有回滚,其他所有事务都不提交)
如何使用事务:
hibernate是手动提交事务的
使用Hibernate进行操作时必须显式的调用Transaction(默认:autoCommit=false)
事务范围:
局部事务:session创建的事务,只对session里的事务做确认
开启事务session.beginTransaction();
提交事务session.getTransaction().commit();
事务回滚session.getTransaction().rollback();
工厂性事务:工厂创建的事务,都可以用工厂性事务做确认
Query
概念:通过HQL(对象的方式)对数据库做查询
Query支持HQL(查询HQL )接口允许你在数据库上执行查询并控制查询如何执行。查询语句使用HQL或者本地数据库的SQL方言编写。
HQL是Hibernate的查询语言,查询对象,注意: HQL不能直接指定表,只能指定对象、指定实体。
持久化对象的生命周期
瞬时对象(瞬时态):使用new 操作符初始化的对象
User user=new User();
特点:1没有纳入session管理,2数据库中没有对应的记录,3长时间未使用就GC掉
持久化对象:它由持久化管理器Session统一管理
session.save(user);
特点:
1 必须要有明确的主标识
2 User对象的属性的值对应数据库中字段的值一致(commit()提交事务后)
离线对象:Session关闭之后,持久化对象就变为离线对象
特点:
1没有纳入session统一管理
2 在数据库中有对应的记录
Junit测试
使用目的:不需要编写主方法,直接测试编写每个方法,方便测试
传统单元测试语法:
1 导入junit.Jar
2 继承junit.framework.TestCase类
3 类名以大写的Test结束
4 方法名以小写test开头
5 不能有任何参数和返回值
最好单元测试的代码单独建立一个目录(Source Folder),且与src目录同级
junit4只需要导入junit4.jar,在测试的方法上面加上@Test
通过Session缓存来理解持久化对象的生命周期
1瞬时状态
(1)此时user对象的属性值都还是初始值
session的临时集合为null
(2)执行到save()方法前
此时User对象的属性值为
session的零时集合依然为null,同上
2 持久态
执行完save()方法
此时user里的属性值如下图,hibernate自动生成了主键
session的两个临时集合instance和state存放情况
instance存放最新的实体对象数据,state存放最早的实体对象的数据
session缓存persistenceContext里的entityEntries的map里
map里的entries的teble里
Key里面存放的值为:(存放User对象当前最新的状态)
Value里面的值为:
existsInDatabase的值为false,表示数据库里还未有这条记录
loadedState存放的是最早的状态,和数据库里的一样
修改User对象里的属性值
hibernate此时会根据state集合里面的值来生成sql语句
此时session里的临时集合instance里的值改变,state集合里的值不改变
session缓存里面的map集合的key里面的值改变,value里面的loadedState存放的值不变
3 持久态 提交完事务
User的属性值为;
Session缓存里面的map集合的key和value里的loadedState和existsInDatabase值情况(loadedState里的值会更新为和key的值一样,existsInDatabase变为true,表示数据库中已经有和User实体对象属性对应得记录):
session两个零时集合得值会变为null,在变为null之前,hibernate会先根据state集合里面得值生成一条sql语句:
Hibernate: insert into User (name, password, createTime, expireTime, id) values (?, ?, ?, ?, ?)
然后发现instance里面的值与state集合里面的值不一样,又会根据instance里面的值创建一条新的更新sql语句:
Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?
4离线态(session关闭之后)修改User对象属性值
User对象的值为;
session的两个临时集合和缓存里面的值都为null
5从离线态到持久态
Session缓存里面map的key值为:
Value里面的existsInDatabase的值和loadedState里的值为:
existsInDatabase为true表示数据库里已经有这个User对象属性对应的记录,但是此时值不一致
loadedState为null,是因为不清楚数据库里是什么值
此时session两个临时集合里的值依然为Null
6 持久态(事务提交后)
session缓存的map集合的value的loadedState的值(和key里的值一样):
Hibernate会根据map里面的key的值来创建一条更新的sql语句
Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?
此时session两个临时集合里的值依然为null
7离线态(session关闭)
数据库中的记录的各个字段的值和User对象对应的属性值一致