【事务】
事务是数据库上一个或多个操作序列,可以理解为一条或多条SQL语句,使所有数据库操作要么都执行,要么都不执行;
原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
1 为什么要有隔离级别?
两个或以上事务使用同一资源(记录)时,如果没有隔离级别,谁都可以去操作利用资源,这让记录具有了不确定性,然后根据这些不确定性的、有时是错误的记录去做出一些决定,显然会导致错误。隔离级别是为了解决并发问题。错误具体表现:
错度: 因为一个事务修改了记录,未提交,随后发生了回滚
非重复读:因为一个事务修改了记录
假读: 因为一个事务修改了记录,所以两次查询结果不一样
2 事务的隔离级别
Read Uncommited,能读到其他事务更改但未提交的数据。
Read Commited, 不能读到其他事务更改但未提交的数据,但是能读到其他事务已经提交的数据。
Repeatable Read, 在事务中已经查询过的数据,其他事务不能做Update的操作,但是可以Insert新数据。
Serializable, 在事务中已经查询过的表,其他事务不能做更改(包括Insert),更改的操作会被block住。
【HIBERNATE对象标识符(OID)】
在JAVA中,通过地址来区分类的不同对象,在关系型数据库中,通过主键来表示一条记录,这个主键不能为NULL,不能重复,不可修改,HIBERNATE用OID把二者联系起来 。
我们通过<id></id>来配置OID,OID生成方法,HIBERNATE提供了7种:
increnment:生成OID的机制不依赖底层数据库,适合所有的数据库,但它只适用于只有单个HIBERNATE进程访问同一个数据库的场合。所有集群环境下不用。
(双击图片,效果好一些)
【SQL语句分析】
1.分组函数执行顺序:
·根据from中的表做笛卡尔积
·where条件验证
·使用group by
·产生select后面要求的项
·使用HAVING条件
·使用distinct
·使用order by
2.group by
+--------------+-------+--------+--------+
| idsaleperson | state | leader | record |
+--------------+-------+--------+--------+
| 1 | ab | 12 | 1 |
| 2 | ab | 13 | 2 |
| 3 | ab | 14 | 3 |
| 4 | cd | 11 | 4 |
| 5 | ef | 11 | 5 |
| 6 | cd | 12 | 6 |
| 7 | fg | 12 | 7 |
| 8 | NULL | NULL | 8 |
+--------------+-------+--------+--------+
如上,在MYSQL中,group by state,则只会显示一条记录
group by state,leader,则所有结果都显示:
+--------------+-------+--------+-------------+
| idsaleperson | state | leader | sum(record) |
+--------------+-------+--------+-------------+
| 1 | ab | 12 | 1 |
| 2 | ab | 13 | 2 |
| 3 | ab | 14 | 3 |
| 4 | cd | 11 | 4 |
| 6 | cd | 12 | 6 |
| 5 | ef | 11 | 5 |
| 7 | fg | 12 | 7 |
+--------------+-------+--------+-------------+
3 having 后的字段需要在select后出现过
【JAVA对象生命周期】
1.要保证JAVA对象不被回收,HOW?
方法一:让对象的引用始终存在,当一个对象失去引用时,该对象很快就会被当做垃圾了
方法二:save到hibernate的session缓存中,即使我们失去对象的引用,也可loadc出来
2.Session会在下面的时间清理缓存(FlushMode.AUTO模式下):
当调用commit方法时,先清理缓存,然后向数据库提交事务
当调用find()或iterate时,为保证查询结果最新,此时也会清理缓存
当调用FLUSH时
3 Flush()与commit
Flush()- 清理缓存,执行一系列SQL,但不提交事务
COMMIT()-先调用flush,然后提交事务,这意味着操作被永久保存下来了
【一对多】
1.many 2 one 单向关联
由多方负责维护关系,一方完全不管。
<many-to-one name="group" column="groupid" cascade="all"/>
采用cascade属性是解决TransientObjectException异常的一种手段
2 one 2 many 单向关联
由一方负责维护关系,会发出多余的update语句
3 one 2 many 双向
* 在一一端的集合上使用<key>,在对方表中加入一个外键指向一一端
* 在多一端采用<many-to-one>
注意:<key>标签指定的外键字段必须和<many-to-one>指定的外键字段一致,否则引用字段的错误
如果在”一“一端维护一对多关联关系,hibernate会发出多余的udpate语句,所以我们一般在多
的一端来维护关联关系
关于inverse属性:
背景:当我们commit时,通常情况,如果HIBERNATE发现内存中中的对象状态发生改变,那么它也会发出相应的SQL语句,所以有时会产生重复的SQL。
inverse主要用在一对多和多对多双向关联上,inverse可以被设置到集合标签<set>上,
默认inverse为false,所以我们可以从”一“一端和”多“一端维护关联关系,
如果设置成inverse为true,则我们只能从多一端来维护关联关系
注意:inverse属性,只影响数据的存储,也就是持久化
inverse和cascade
* inverse是关联关系的控制方向
* cascade操作上的连锁反应
-------------------------------------------------------------------------------------------------------------------------------------------
【多对多】