回顾作业:
事务不能放到DAO里,因为有多个小事务同时运行;放到中间层Service里;
Service 里打开session 传给DAO,每个方法传一个参数;或在DAO的实现类中加一个属性
session和setSession方法;
把接口改掉,抛出一个异常;
一事务一session的原则;
在Service的实现类里加一个Dao的属性;new Dao();再注入一个session;
dao.setSession();
session里有一个缓存,一旦看到它所查询的对象有所变化,
它会自动将它们更新到数据库中;
一、一对多:
1、用户和帐户:
User 有 Account_set (m)
Account 有 User(1)
User 和 Account之间是一对多的关系;
Account和 Address之间是一对一的关系;
一对一时,主键的一方(Address), 没有对应的字段;
一对多时,set 是集合,不能有对应字段,主键的一方(User)不会有对应的字段;
一对多关系映射:
(1) user的xml文件:(一的一方,有一个account的 set集合)
<set name="accounts" cascade="all" inverse="true">
<key column="fid"></key>
<one-to-many class="Account">
</set>
1、集合里存的是PO,集合代表一对多;
2、class="Account" ;说明集合中的PO类型;因为泛型只是编译时有效,所以还要说明类型;
3、key 标签说明的是,关系的另一方(Account)表中与本表关联的外键字段的名字;
映射了四个信息:
1、name="accounts";是本类中的集合属性;
2、一对多关系:one-to-many
3、集合中的PO类型
4、关联的外键字段
5、级联操作,考虑业务;cascade="all" ,帐户是属于用户的;删除用户则帐户也被删除;
6、关系的维护权:
一对多的关系中, 在一的一方写上inverse="true"; 将关系的维护权放在多的一方;
inverse="false"; // User维护关系,存user时, 会先存account;user可能会用到account的记录;
这时存account时,account有外键字段,先插入三条account语句,fid=null;
再插入user,并且要更新account的外键字段;
inverse="true"; // User放弃维护关系,会先存user,再存account;
1)、防止外键为空;把关系的维护交给多的一方;
2)、防止n+1次更新;
如果为false ; user.add(account); s.saveOrUpdate(user); 更新user时会把集合的元素更新一遍;再更新user;
如果为true; 存account时会先存user ,再把自己存上就行了;
inverse="true";
就是在设置如果在内存中的修改或添加了这个集合中的某一个
或某几个对象他不会将全部集合的信息同步到数据库,
而是只将集合中被修改的对象重新同步到数据库。
(2) account的xml文件:多的一方,有一个user属性
<property name="actNo" unique="true" not-null="true">//自动建表时加上约束
<many-to-one name="user" column="fid" cascade="save-update">
cascade="save-update":帐户保存和更新时更新用户,但删帐户时不能删用户;
多对多关系,明天再讲;
二、持久对象的状态:
1、什么叫PO的状态:(内在状态)
PO状态就是PO对象从产生到消亡,整个生命周期中属性值的变化;
属性包括oid、普通属性和关联属性;
2、PO的状态管理的原因和手段:(内在状态)
状态的变化涉及到和数据库同步的问题;所以要进行管理;
手段:
JDBC: 需要用update代码去更新字段;
Hibernate: session管理;
3、Hibernate中PO的状态:(外在状态)
transient:暂态,瞬态; 该对象和任何session无关,在数据库中没有它的记录;
刚new出来的对象;或已经删除的对象;
persistent: 持久对象的持久态;该对象处于某session的管理中;在数据库中有记录;
从数据库中取出的对象;通过save()方法同步到数据库中的对象
detached:游离态、脱管态;当前没有和任何session有关,数据库中有记录;
session关闭后,就成了游离态了;update()同步到数据库中;
状态转换图:
new ---> Transient
save | | 从持久态变成瞬态,oid已经有值了;不是标准的瞬态;
saveOrUpdate | | delete(o);//从数据库中将记录删掉,从session的缓存中将其副本删除
| |
DB: | |
get() -------> Persistent
load() | | update
find() close() | | saveOrUpdate
clear() | | lock
Detached
-----save() ------ session中有一个副本;
session 中有一个缓存;叫一级缓存,只对持久对象进行缓存;
二级缓存在sessionFactory里,一般是将查询结果放在二级缓存里;
不是很好用;知道一级缓存就好了;
save时将其存到session的缓冲区,就变成持久态了;
持久态的对象会自动更新;
处于持久态的对象的状态受session的监控;在缓冲区里面的对象是内存里的对象的副本;
所以对其进行更新时,
从数据库中查出来的对象都是持久态的;
get();//如果找到对象就返回,否则返回空;
load();//如果找到对象就返回,否则抛异常 throw unrecoverableException;
一般都用HQL语句;
s.close();//关闭session,对象变成脱管的;
clear();//将session的缓冲区清空;对象变成脱管的对象;内存中还有,但跟session已经无关了
evict(o1);//将一个对象清出去,变成脱管状态
1-view -1-session :view-session
请求时间太长的话,不能一直开着session,相当于占有连接;
以前的dto :Data transfer object
脱管的对象可以在网络之间进行传输;
一般在中间层调用hibernate;不在网络层用;
脱管态:变成 持久态
状态发生变化时用update或saveOrUpdate将其变成持久态;
调用lock方法将其变成持久态并不更新
暂态的对象的oid为null,但delete后oid有值;
而脱管态的oid有记录;
不知道是暂态还是脱管态的话,用saveOrUpdate();
delete后再调update时会报错;
PO在hibernate种有两种状态:外在状态和内在状态
外在状态:3种状态
内在状态:属性值
外在状态会影响到内在状态的同步;
持久态:内在状态自动管理;和数据库保持同步;
游离态:半自动,将其变回持久态,再同步到数据库种;
瞬态:无关
三、概念:
1、cascade
cascade属性是设置级联操作的.
也就是在操作一端的数据如果影响到多端数据时会进行级联操作,
cascade="none",cascade="save-update",cascade="delete",cascade="all" cascade="persist"
cascade="delete-orphan",cascade属性的值常用的设置为以上五项:
none就是不使用级联操作,默认级联是none。
save-update也就是只有对象保存操作(持久化操作)
或者是持久化对象的更新操作,才会级联操作关联对象(子对象)。
persist就只是将级联对象也持久化到数据库。
delete对持久化对象的删除操作时会进行级联操作关联对象(子对象)。
all 对持久化对象的所有操作都会级联操作关联对象(子对象)。
all-delete-orphan,从集合中删除时,同步将数据库中的记录删掉;
delete之后将表中表示关联的外键id置成null,不会将这条纪录也删除掉;
delete-orphan就不会留有空纪录,而是级联的把相关纪录删除掉。
<many-to-one> 一方有时可以不写;一般在父节点的一端设置;
<one-to-many> 一般写cascade="all"; 只有父删除时所有的子都删除;
级联操作用在one-to-one 和 one-to-many 中,即父端;
2、jdb c中有batch,而hibernate中循环用save();
但数量太大时,缓冲区中放不下,注意:s.flush(); s.clear(); 后在往里放;
先 flush(); //是让缓冲区中的内容真正往数据库中存;但是没有提交;
再 clear();// 清空缓冲区;
batch_size 20 ;//读时读20条;不是更新;
3、默认 flush 的时机:
1)提交commit时会隐含的进行flush;
2)直接调用flush;
3)执行某些查询之前hibernate会自动进行flush;
hibernate 在用oid 去查询时,不一定去数据库里查,先从session中查;
session :一级缓存 ,oid为条件才有用;
sessionFactory: 二级缓存,session 缓存的副本;
查询缓存;from account; //结果在二级缓存中存着;
再去查时 from acount 不会真正去查account ,而是拿id去查和数据库中对比;
一样的话直接用上次查出的结果;否则再从数据库中拿出没有的记录;
但是一旦进行了更新或flush;缓存中的内容都被清空;
模式设置:
FlushMode.AUTO:执行某些查询时,手动flush和commit;
COMMIT:手动flush和commit;
NEVER:只有手动flush;
四、Hibernate控制的事务
hibernate的事务隔离级别和JDBC中大致相同。
设置时要在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)
(1)、锁:物理上只有一种锁,就是数据库的锁;
写的时候一瞬间一定是锁住的;不能取消;
悲观锁和乐观锁是衍生的概念,用来解决并发的;
悲观锁:读回来的时候就锁住了,在它提交之前别人不能修改这条记录;
就是它肯定这个期间一定有人来修改这条记录;
乐观锁:读回来的时候不加锁,就是它肯定期间不会有人来修改这条记录;
但是别人可以修改这条记录;加一个vresion字段;读取的时候把
version也读回来,更新的时候看version是否一致,一致的时候更新,
并将versin加1存回去;
JDBC中version都需要自己维护;而Hibernate帮我们维护;
1) 版本检查
要在其表中多加上一列表示版本信息,会在读取时读到这个版本号,
并在修改之后更新这个版本号,并且只有版本号相同才会予以更新,
如果版本号低于数据库中的,就会抛出例外。
在持久类里加一个version属性;int ; 名字随便起,不一定非得叫version的;
提供set/get方法,构造方法不需要改;
<version name="version" column="version" type="integer" />
这个标签必须紧挨在 id 标签后边;不能写在普通属性后面;
2) 时间戳
使用时间戳,是通过最后修改时间来判断是否来做更新操作,
也就是只有在最后更新时间之后才会做更新。
<timestamp name="updateTime" column="updatetime"/>
分享到:
相关推荐
- 第三天可能深入到对象状态的转换和生命周期管理,以及如何处理事务。 - 第四天可能讲解了HQL的使用,包括查询、更新、删除等操作。 - 第五天可能涉及了高级主题,如性能优化、缓存机制、Cascading和Lazy ...
还可以集成第三方缓存服务,如 EhCache、Infinispan。 七、事务管理 Hibernate支持编程式和声明式事务管理。编程式事务管理通过Transaction对象控制开始、提交和回滚;声明式事务管理通常结合Spring框架,通过@...
**J2EE复习积累(六)-Hibernate4.2** 在J2EE开发中,Hibernate作为一款流行的ORM(对象关系映射)框架,极大地简化了Java应用程序与数据库之间的交互。本篇复习将聚焦于Hibernate 4.2版本,该版本在前一版本的基础上...
9. **缓存机制**:为了提高性能,Hibernate引入了缓存,包括第一级缓存(Session级别的缓存)和第二级缓存(SessionFactory级别的缓存),以及第三方缓存插件如Ehcache。 10. **实体状态**:Hibernate定义了四种...
第三次:4 小时 第四次:12小时 第五次:24小时 第六次:3 天 第七次:7 天 之后 :每15天 当然如果没有及时更新复习的话,下一次的复习更新时间会在上一次复习更新后顺延。 由于对页面样式了解不多,所以写出来...
【北大青鸟ACCP6.0 第三学期 Y2 JAVA方向 hibernate框架】是一个针对Java开发者的学习资源,主要聚焦于Hibernate这一流行的关系对象映射框架。Hibernate作为一个强大的ORM(Object-Relational Mapping)工具,它简化...
3. 使用Hibernate完成持久化操作的准备和步骤: - 准备:配置Hibernate环境,包括hibernate.cfg.xml配置文件、实体类的编写、映射文件的创建。 - 步骤:创建SessionFactory,打开Session,开始事务,执行持久化...
**1.3 第三部分- EventManager Web应用程序** - **编写基本的servlet**:介绍如何创建Servlet来处理HTTP请求。 - **处理与渲染**:展示如何使用Hibernate执行数据库操作,并将结果呈现给用户。 - **部署与测试**:...
"SVSE-S3冲刺题-Hibernate笔试题"这个标题表明这是一个针对SVSE(可能是软件版本、课程阶段或某个特定考试体系的缩写)第三阶段的冲刺复习资料,重点是Hibernate相关的笔试题目。Hibernate是一个开源的对象关系映射...
9. **配置连接池**:为优化数据库连接的管理,通常会结合Hibernate使用第三方连接池,如C3P0、HikariCP等。这样可以在多线程环境下高效复用数据库连接,提高系统性能。 通过学习这个"hibernate操作视频",你将能够...
我们将学习一级缓存(Session级别的缓存)和二级缓存(SessionFactory级别的缓存)的使用,以及第三方缓存插件如Ehcache的集成。 七、高级特性 深入学习Hibernate的高级特性,如延迟加载(Lazy Loading)、集合的...
002---第一个Hibernate示例 创建一个简单的Hibernate应用通常包括以下步骤: 1. 定义实体类(Entity):这是与数据库表相对应的Java类。 2. 创建映射文件(Hibernate Mapping File):XML文件用于定义实体类与数据库...
3. `org.hibernate.Transaction`: 处理事务相关操作。 4. `org.hibernate.Query`: 执行各种数据库查询,支持HQL语言和SQL语句。 5. `org.hibernate.Configuration`: 负责配置并启动Hibernate,创建SessionFactory。 ...
第三次:4 小时 第四次:12小时 第五次:24小时 第六次:3 天 第七次:7 天 之后 :每15天 当然如果没有及时更新复习的话,下一次的复习更新时间会在上一次复习更新后顺延。 在Ajax更新复习次数时通常都会第一次...
第三次:4 小时 第四次:12小时 第五次:24小时 第六次:3 天 第七次:7 天 之后 :每15天 当然如果没有及时更新复习的话,下一次的复习更新时间会在上一次复习更新后顺延。 由于对页面样式了解不多,所以写出来...
"考试复习第二部分,框架整合"这个主题,通常涵盖了多个Java Web开发框架的集成与协作,旨在提高项目开发效率,优化代码结构,并实现更高效的功能复用。在准备这样的考试或者学习过程中,以下是一些重要的知识点: ...
SSH 期末复习题涉及到的主要知识点包括 Struts 2 框架、Hibernate ORM 和 Java Web 开发中的核心概念。以下是对这些知识点的详细说明: 1. **Struts 2**: - **基础类库**:构建 Struts 2 应用的基础类库包括 `...
此外,还会讲解数据库设计的基本原则,如范式理论,包括第一范式(1NF)、第二范式(2NF)、第三范式(3NF)和BCNF(Boyce-Codd范式)。 3. **SQL语言**:SQL(结构化查询语言)是用于管理和处理关系数据库的标准...