get和load:
相同:两者都是一级,二级,数据库查找,
不同:1 查找不到get返回null,load异常
2 get一定是返回实体对象,load在lazy=true(默认lazy=true,映射文件上类级别可配lazy属性)且一级缓存查不到时返回cglib代理对象,使用对象时再查询二级缓存和数据库
一级缓存无并发访问问题
二级缓存生命周期长,默认不开启,需自己配置,可能出现并发访问,适合放很少修改,偶尔并发也无关紧要的数据
在hql里使用参数(防止sql注入):?或冒号加参数名,?则用参数位置设置值,冒号用参数名设置值
getCurrentSession:常用实现是线程本地,内部也会调用openSession()进行创建和保存,事务提交会关闭session,并从线程本地移除session
openSession()的事务提交不会关闭session,需手动关闭
save:数据插入,得到主键id,设置给对象,但插入的记录是加了X锁的,我们查不到
update: update时不更新,所以不知道数据库是否已有此id,但会检查id是否为null,事务提交时更新
要不在连接字符串指定默认数据库,要不在映射处用catalog指定数据库
hibernate.cfg.xml可含mapping resource或mapping class来查找映射文件或映射类
hibernate可以自动建表,像@Column里的属性(如length)不是用来校验,而是用来建表的
主键GenerationType:
Table: select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update
Sequence: select next_val as id_val from hibernate_sequence for update
Identity: 直接插入,获取返回id
Auto:数据库自主选择,我这边实验用的是Sequence
对象状态追踪:如get或save放入缓存后,未修改则commit时不更新,修改过则commit时更新,其实commit时进行了dirty check,PersistenceContext内含Object(当前对象)和EntityEntry(内含对象的loadedState,即初始状态)的映射,进行状态比较决定是否更新
试验:LockMode
PESSIMISTIC_READ:get使用此模式,mysql下是lock in share mode
PESSIMISTIC_WRITE:get使用此模式,mysql下是for update
比如使用msyql,使用MySQLDialect,Dialect内定义了各类LockMode对应的加锁语句(如for update)
switch ( lockMode ) {
case UPGRADE:
return getForUpdateString();
case PESSIMISTIC_READ:
return getReadLockString( timeout );
case PESSIMISTIC_WRITE:
return getWriteLockString( timeout );
case UPGRADE_NOWAIT:
case FORCE:
case PESSIMISTIC_FORCE_INCREMENT:
return getForUpdateNowaitString();
case UPGRADE_SKIPLOCKED:
return getForUpdateSkipLockedString();
default:
return ""; //代码为dialect的判断,MySQLDialect重写了getReadLockString