对于对象状态大家先看这张图
当你的session会话去数据库中get一个对象也就代表去数据库里面查了一次,获得到的对象也就是数据库中的数据,当你用get获取的对象状态为持久态,也就是你对这个对象进行删除或者修改的话数据库中对应的数据也会相应的改变
持久状态的对象也会根据不同的操作变成临时状态和游离状态,临时状态的对象当你对它进行操作是不会影响到数据库中的数据,
游离状态的对象也能通过update变成持久状态,而游离状态情况下的对象你对它进行操作,它可能会影响到数据库中的数据,也有可能不会影响
稍微列举个代码帮助大家理解
public static void main(String[] args) {
/**
* 使用帮助类来获取session 会话
*/
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
//持久态对象
Student student=session.get(Student.class,1);
session.close();
//现在的student就是游离态对象
session=SessionFactoryUtils.openSession();
student.setSname("花花");
session.update(student);
//现在的student又成为了持久态对象
student.setSname("花花2");
session.delete(student);
//临时态对象
student.setSname("花花2");
//然后由变为持久态对象
session.save(student);
transaction.commit();
/**
* 使用帮助类来关闭会话
*/
SessionFactoryUtils.closeSession();
}
1、hibernate是通过管理对象来操作数据,这里对象指的是持久化对象。
2、hibernate中的三种状态的对象是可以相互转换的,通常编码时只关注持久
化对象。关注get、save、update方法所操作后的对象
Hibernate对象的加载机制
这个理论相对简单,也就是当你用session.get获取的对象加载机制为立即加载,也就是说当你用了这个方法它就会立马加载这个对象 而你用session.load加载获取到的对象为延迟对象,这个对象只有当你要使用它的时候它才会加载,当你只用load这个方法加载的对象一个代理对象,并不是一个能直接使用的对象
hibernate的并发控制就是多个用户同时获取到某一条数据,进行不同的处理,当a修改的时候成功了,但是b修改的时候将a修改的内容覆盖了,这个时候数据就没有了数据的准确性,这是不行的所以面对这种问题hibernate有对应的解决办法,接下来贴代码
首先在数据库加一个字段类型为int 然后在实体类中加上 再在实体类映射文件中加这一句、
<version name="version" type="java.lang.Integer" column="version"></version>
<!--name是实体类的全路径限定名 table 是数据库名字-->
<class name="com.zking.two.Student" table="t_hibernate_student">
<!--name为实体类属性 type为实体类的数据类型 column 数据库列名-->
<id name="sid" type="java.lang.Integer" column="sid">
<generator class="increment" />
</id>
<version name="version" type="java.lang.Integer" column="version"></version>
<!--属性-->
<property name="sname" type="java.lang.String"
column="sname">
</property>
</class>
这里用main方法来模拟了一下这个两个用户同时获取到同一条数据的情况
public static void main(String[] args) {
Student student=new Student();
student.setSid(1);
student.setSname("名字");
student.setVersion(1);
edit(student);
}
public static void edit(Student s){
//帮助类获取session会话
Session session = SessionFactoryUtils.openSession();
Transaction transaction = session.beginTransaction();
session.update(s);
transaction.commit();
SessionFactoryUtils.closeSession();
}
数据库的变成了这个
然后再执行这个模拟又一个用户的修改
public static void main(String[] args) {
Student student=new Student();
student.setSid(1);
student.setSname("名字dad");
student.setVersion(1);
edit(student);
}
然后控制台会报错Error during managed flush [Row was updated or deleted by another transaction这就 保证了数据的准确性