1、要求一个属性作为唯一值(使用id)
2、实体类属性,建议不适用基本数据类型,而使用包装类
举个例子:为了区分学生未参加考试和0分。则int 无法表示null。则建议使用包装类
native: 会自动选择合适的数据库。
uuid: 会自动生成一个唯一标识符,对应的实体类 必须是字符串,仍然是hibernate自动添加
添加操作
day01有,不再重复
根据id进行查询,返回一个对象
第一个参数 实体类的运行时类Class
第二个参数 id值
session.get(User.class, 1);
//sql:
//1、根据id进行查询
SELECT * FROM t_user WHERE t.uid=1;
//2、修改
UPDATE t_user SET username='xxx',password='xxx' where id = ?
//hibernate:
User user = session.get(User.class,2);
user.setUserName("laowang");
session.update(user);
//sql:
SELECT FROM t_user WHERE uid = ?
//hibernate:
User user = session.get(User.class,2);
session.delete(user);
传入的是瞬时态,则添加;
传入的是托管态,则更新;
传入的是持久态,也是更新
把数据存到数据库的话,数据库本身是文件系统,那么调用流读取比较耗时。
我们把文件放入内存中,不需要使用流,即可读写数据。这就是缓存
作用范围为:session创建到session关闭。
缓存存储的数据是: 持久态
需要配置,作用范围是sessionFactoy
查询两次,第一次先到一级缓存中找,发现找不到,那么就到数据库中进行查询,把数据放入一级缓存(发送sql语句,访问数据库);第二次查询不会再到数据库中查了,而是在一级缓存中找(不发送sql语句)
在缓存区,另开一处空间为快照区。当一个对象放入缓存中,相应的在快照区添加入这个对象。
如果此时对象被修改了,那么缓存中对象进行修改。。(user.setName(“newName”);
当提交事务的时候,如果快照区和缓存里同一对象内容不一样,那么才进行更新数据库,快照区也在此时进行更新。(session.submit())
优化了性能,只有在需要更新时才进行数据库更新。
我们知道,session是线程隔离的资源,所以在并发开发中,要用到session的绑定。
(1)在核心配置文件中进行配置
thread
(2)调用工具类方法返回本地线程绑定session
Session session = sessionFactory.getCurrentSession();
(3)获取本地绑定的session时,不需要手动关闭session(因为已经和本地线程关联一起)否则会报错
不考虑隔离性产生问题
所谓的脏读,其实就是读到了别的事务回滚前的脏数据。比如事务B执行过程中修改了数据X,在未提交前,事务A读取了X,而事务B却回滚了,这样事务A就形成了脏读。
事务A首先读取了一条数据,然后执行逻辑的时候,事务B将这条数据改变了,然后事务A再次读取的时候,发现数据不匹配了,就是所谓的不可重复读了。
也就是说,当前事务先进行了一次数据读取,然后再次读取到的数据是别的事务修改成功的数据,导致两次读取到的数据不匹配,也就照应了不可重复读的语义。
事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。
也就是说,当前事务读第一次取到的数据比后来读取到数据条目少。
两者有些相似,但是前者针对的是update或delete,后者针对的insert。