一、一级缓存中的数据存储
1.用户做查询操作时,都会将查询的对象存储到一级缓存中。
2.用户做更新操作时,都会先将操作的对象存储到缓存中。然后通过session.flush()将一级缓存与数据库同步。
二、一级缓存中的数据获取
用户做查询操作时,
1.如果是简单主键查询,都会先从缓存中获取数据。
如果没有,才会到数据库中查找数据,
get()、load() 主键查询
iterator() iterator()底层也是简单的主键查询
2.如果是批量查询,则会直接从数据库中获取数据。
list()
get()、load()
首先会从一级缓存中获取数据,如果没有才会到数据库查询数据。
同时将查询的数据存储到缓存中。
list()
不会从一级缓存中获取数据。
直接从数据库中获取数据。只生成一条sql语句。
同时将查询的数据存储到缓存中。
iterator()
会从缓存中获取数据。
首先生成一条查询主键ID的语句,
然后调用it.next(),根据主键ID查询。首先会从一级缓存中获取数据,如果没有才会到数据库中查找数据。
三、一级缓存与数据库的同步( 持久化对象与数据库的同步)
1.用户做更新操作时,首先会将对象转化为持久化对象。再根据相关操作对对象作出相关标记。
save() 保存对象到一级缓存,并打上保存标记
update() 修改对象到一级缓存,并打上修改标记。
delete() 删除对象到一级缓存,并打上删除标记。
saveOrUpdate() 保存或修改对象,并打上相关标记。
2.调用session.flush()生成sql语句,并执行。将一级缓存与数据库同步。
它会根据持久化对象的标记生成不同的sql语句,并执行。
四、 用户与一级缓存、数据库交互顺序
查询对象:
如果是简单主键查询,首先会先从缓存中查找对象,如果没有就会从数据库中查找,然后存储到缓存中。
如果是批量查询,则直接从数据库中获取数据,
更新对象(增、删、改):
首先将更新的对象存储或更新到缓存中,并打上相应的标记。
当事务提交时,再根据标记进行提交缓存中的数据。
五、其他
5.1 get()\load()
get():
1.立即加载。
2.获取的对象是对象。
3.如果查询的对象不存在,返回NUll。
load()
1.延时加载。只有在使用对象时,才查询。
2.获取的是代理对象。其作用就是实现延时加载。
3.如果查询的对象不存在,则返回一个异常ObjectNotFoundException 。
4.如果session关闭,第一次使用load()获取的代理对象,则会报错。
5.2 list()\iterator()
list()
直接生成一条sql语句。从数据库中查询数据,
Iterator it=qr.iterator()
it.next()
首先会生成一条sql语句,查询所有符合条件的数据的主键ID。
然后在根据主键ID,一条一条查询数据。
iterator() -- 首先会生成一条sql语句,查询所有符合条件的数据的主键ID。
it.next()-- 然后根据ID一条一条查询数据。
5.3 多条sql何为一条sql
1.用户操作只与一级缓存进行交互,用户多次修改数据,也只是修改一级缓存中的数据。
2.只有调用session.flush()\session.getTracsaction.commit() 时才会生成sql。将一级缓存与数据库同步。
3.虽然用户多次修改数据,但是也只是更新了持久化对象。
用户调用session.flush()时,它根据持久化对象的更新标志,然后生成sql作出同步。
public static void main(String[] args) {
session.beginTransaction();
UserEntity user=(UserEntity) session.get(UserEntity.class, 2);
//修改一次
user.setAge(12);
session.update(user);
//修改两次
user.setAge(13);
session.update(user);
session.flush();
}
5.4 session.flush()\session.getTracsaction.comit()
session.flush()
生成一条sql语句,将一级缓存与数据库同步。
session.getTracsaction.comit()
生成一条sql语句,将一级缓存与数据库同步。
并提交事务。
【它内部隐式调用了session.flush()】
不同点:
如果只使用了session.flush(),只会生成sql并执行。
但最后由于事务没提交,数据依旧回滚。
如果只使用了session.getTracsaction.comit()。
它不仅会生成sql并执行,
还会提交事务,将执行的sql数据持久化。
5.5 update() 的变形
5.5.1 使用update()方法做更新
public static void main(String[] args) {
session.beginTransaction();
UserEntity user=(UserEntity) session.get(UserEntity.class, 2);
//修改一次
user.setAge(12);
session.update(user);
session.getTransaction().commit();
}
5.5.1 使用update()方法的变形做更新
public static void main(String[] args) {
session.beginTransaction();
UserEntity user=(UserEntity) session.get(UserEntity.class, 2);
//修改一次
user.setAge(122);
session.getTransaction().commit();
}
5.6 session.flush() 会将一级缓存与数据库同步,同时重置持久化对象的状态。
5.6.1 将多条sql合成了一条。只更新一次
public static void main(String[] args) {
session.beginTransaction();
UserEntity user=(UserEntity) session.get(UserEntity.class, 2);
//修改一次
user.setAge(122);
user.setAge(144);
session.flush();
}
5.6.2 session.flush()重置持久化对象的状态,生成两条sql
public static void main(String[] args) {
session.beginTransaction();
UserEntity user=(UserEntity) session.get(UserEntity.class, 2);
//修改一次
user.setAge(111);
session.flush();
user.setAge(222);
session.flush();
}
5.7 sql的创建时间
只有调用sesison.flush() 或session.getTransaction.commit()方法时,
才会生成sql并执行。否则不会生成sql语句。
5.7.1 session的更新操作操作的只是持久化对象,不会生成sql
public static void main(String[] args) {
session.beginTransaction();
UserEntity user=(UserEntity) session.get(UserEntity.class, 2);
//修改一次
user.setAge(1112);
session.update(user);
}
5.7.2 使用session.flush()会生成sql
public static void main(String[] args) {
session.beginTransaction();
UserEntity user=(UserEntity) session.get(UserEntity.class, 2);
//修改一次
user.setAge(1112);
session.update(user);
session.flush();
}