实体类创建的注意事项
1.持久化类提供无参数构造
2.成员变量私有,提供共有get/set方法访问.需提供属性
3.持久化类中的属性,应尽量使用包装类型
4.持久化类需要提供oid.与数据库中的主键列对应
5.不要用final修饰class
动态代理生成(用Proxy的newInstance方法对这个实例对象代理生成一个代理对象。)
https://www.cnblogs.com/hywhyme/p/11618895.html
cglib代理 其实就是继承你写的对象 添加方法 来实现的代理 如果你写的类是final修饰的 没法更改 自然也就无法生成代理
hibernate使用cglib代理生成代理对象
hibernate 三种状态
临时状态(瞬态):刚用new 语句创建,还没有被持久化,并且不处于Sesssion 的缓存中。
持久化状态:已经被持久化,并且加入到Session 的缓存中。
游离状态:已经被持久化,但不再处于Session 的缓存中。
增删改查 其实就是状态之前的转化
hibernate缓存
首先session将一个对象加入自己的管理范围内,其实也就是把该对象放入自己的一级缓存中,例如,session.save(xxx);
这个语句就是将xxx保存在自己的一级缓存中,等待事务提交后,hibernate才真正的发sql语句,对数据库进行操作。
如果你多次取得同一个对象的话 可以使用==看是否是同一个对象 其实是一个对象 减少了对数据库的访问 并且缓存放在内存中 加快了速度
//1 创建,调用空参构造 Configuration conf = new Configuration().configure(); //2 根据配置信息,创建 SessionFactory对象 SessionFactory sf = conf.buildSessionFactory(); //3 获得session Session session = sf.openSession(); //4 session获得操作事务的Transaction对象 //获得操作事务的tx对象 //Transaction tx = session.getTransaction(); //开启事务并获得操作事务的tx对象(建议使用) Transaction tx2 = session.beginTransaction(); //---------------------------------------------- User user = session.get(User.class, 1l); User user2 = session.get(User.class, 1l); User user3 = session.get(User.class, 1l); User user4 = session.get(User.class, 1l); System.out.println(user==user2); //---------------------------------------------- tx2.commit();//提交事务 session.close();//释放资源 sf.close();//释放资源
快照
如果调用修改方法 hibernate会比对 修改后的对象和缓存中的对象 是不是一样 如果不一样就存入缓存 在放入数据库 如果一样的 那么久不会放入数据库了
事务
ACID
原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
事务前后数据的完整性必须保持一致。
隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
事务并发问题
脏读
脏读发生在一个事务A读取了被另一个事务B修改,但是还未提交的数据。假如B回退,则事务A读取的是无效的数据。这跟不可重复读类似,但是第二个事务不需要执行提交。
不可重复读
在基于锁的并行控制方法中,如果在执行select时不添加读锁,就会发生不可重复读问题。
在多版本并行控制机制中,当一个遇到提交冲突的事务需要回退但却被释放时,会发生不可重复读问题。
幻读
幻读发生在当两个完全相同的查询执行时,第二次查询所返回的结果集跟第一个查询不相同。
发生的情况:没有范围锁。
事务的隔离级别
读未提交- 无法解决任何问题 0001
读已提交 - 解决了脏读 0010
可重复读(mysql默认级别)- 解决了不可重复读和脏读 幻读没有解决 0100
串行化 - 没有问题 性能最低 1000
使用 配置隔离级别
<property name="hibernate.connection.isolation">4</property>
指定session与当前线程进行绑定
<property name="hibernate.current_session_context_class">thread</property>
在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了 getCurrentSession()方法即可获得与当前线程绑定的session对象
不同层之间如果需要同一个session 直接调用getCurrentSession()方法可以获得同一个session对象了