Hibernate——hibernate中的对象状态,一级缓存(了解),事务,查询
一、hibernate中的对象状态
hibernate中的对象分为三种状态
- 瞬时状态:没有id,没有在session缓存中
- 持久化状态:有id(有与数据库中对应的id),在session缓存中
- 游离|托管状态:有id,没有在session缓存中
1、save方法
save方法实际上并不是保存,而是执行SQL语句来获取id的值并保存到session中
@Test //三种状态特点 //save方法: 其实不能理解成保存.理解成将瞬时状态转换成持久状态的方法 //主键自增 : 执行save方法时,为了将对象转换为持久化状态.必须生成id值.所以需要执行insert语句生成. //increment: 执行save方法,为了生成id.会执行查询id最大值的sql语句. public void fun2(){ //1 获得session Session session = HibernateUtils.openSession(); //2 控制事务 Transaction tx = session.beginTransaction(); //3执行操作 Customer c = new Customer(); // 没有id, 没有与session关联 => 瞬时状态 c.setCust_name("联想"); // 瞬时状态 session.save(c); // 持久化状态, 有id,有关联 //4提交事务.关闭资源 tx.commit(); session.close();// 游离|托管 状态, 有id , 没有关联 }
2、持久化状态
持久化状态对象的任何变化都会自动同步到数据库中
@Test //三种状态特点 // 持久化状态特点: 持久化状态对象的任何变化都会自动同步到数据库中. public void fun3(){ //1 获得session Session session = HibernateUtils.openSession(); //2 控制事务 Transaction tx = session.beginTransaction(); //3执行操作 Customer c = session.get(Customer.class, 1l);//持久化状态对象 c.setCust_name("微软公司"); //4提交事务.关闭资源 tx.commit(); session.close();// 游离|托管 状态, 有id , 没有关联 }
三种状态的转换图
二、一级缓存
缓存的作用就是提高效率,当然hibernate中的一级缓存也是为了提高操作数据库的效率。
1、提高查询效率
2、减少不必要的修改语句发送
三、事务
事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。
事务的结束有两种,当事务中的所以步骤全部成功执行时,事务提交。如果其中一个步骤失败,将发生回滚操作,撤消撤消之前到事务开始时的所以操作。
1、事务的特性
事务具有四个特征:原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持续性( Durability )。这四个特性简称为 ACID 特性。
a.原子性
事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做
b.一致性
事 务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。
c.隔离性
一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
d.持续性
也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。
2、事务的并发问题
1、脏读
一个事务看到了另一个事务未提交的更新数据;当事务读取尚未提交的数据时,就会发生这种情况。
例如事务A正在访问数据,并且对数据进行了修改,更改了一行数据,这种修改还没有提交到数据库中,而事务B在事务A提交更新之前读取了已更新的行,然后使用了这个数据。
如果事务A回滚该更新,则事务B使用的这个数据由于还没有提交,就会被认为是不曾存在的数据,即为脏数据,根据脏数据所做的操作可能是不正确的。
2、 不可重复读
在同一事务中,两次读取同一数据,得到内容不同,也就是有其他事务更改了这些数据;
例如事务A查询一条记录后,事务B更新了事务A查询的记录,并提交了事务,那事务A再次查询上次的记录时,对同一数据查询了两次,得到的结果不同,这称为不可重复读。
3、幻读
一个事务在执行过程中读取到了另一个事务已提交的插入数据;即在第一个事务开始时读取到一批数据,但此后另一个事务又插入了新数据并提交,此时第一个事务又读取这批数据但发现多了一条,即好像发生幻觉一样。
3、事务的隔离级别
在项目中如何管理事务
业务开始之前打开事务,业务执行之后提交事务,执行过程中出现异常.回滚事务.
在dao层操作数据库需要用到session对象,在service控制事务也是使用session对象完成,我们要确保dao层和service层使用的使用同一个session对象
在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了. 我们开发人员只需要调用sf.getCurrentSession()方法即可获得与当前线程绑定的session对象
注意1: 调用getCurrentSession方法必须配合主配置中的一段配置
注意2:通过getCurrentSession方法获得的session对象.当事务提交时,session会自动关闭,不要手动调用close关闭
确保service和dao层使用同一个Session
将当前线程和session绑定到一起(Threadlocal方法),在同一线程中获取相同的session
四、hibernate中的批量查询
1、HQL查询
Hibernate独家查询语言,属于面向对象的查询语言
a.基本查询
如果是查询表中全部字段,可以不用写select *
b.条件查询
1)?占位符
2)命名占位符
c.分页查询
2、Criteria查询
a.基本查询
b.条件查询
c.分页查询
d.聚合查询
3、原生SQL查询
a.返回对象集合
b.条件查询
c.分页查询