1. 对象的三种状态(hibernate管理的对象)
1.1 临时状态 (new delete)
1.2 持久状态(get save update)
1.3 游离状态 (close)
临时状态 :数据库中没有 当有一个对象new一个对象
持久化状态:当save时就是持久化状态
当处在持久化状态的时候 里面的所有操作都会忽略
因为当处在持久化对象的时候 。在程序的缓存中自动保存了对象的引用
会把session中的对象和目前的对象进行比较
当达不到的时候 会更新session中的数据 所有会相对执行两条sql语句 一条是查询 一条是更新
这也叫做一级缓存
package w1.test;
import java.sql.Date;
import java.sql.Timestamp;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import w1.entity.User;
public class Test1 {
public static void main(String[] args) {
Configuration conf = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = conf.buildSessionFactory();
Session session = sessionFactory.openSession();
// session.getTransaction();//获得一个事务对象
Transaction transaction = session.beginTransaction();
/* User user=new User();
//瞬时状态
user.setId(6);
user.setRemark("备注:6666");
user.setSex("女");
user.setBirthday(new Date(new java.util.Date().getTime()));
user.setUserPwd("123");
user.setUserName("徐佳慧2");
user.setRealName("xjh2");
//持久化对象
session.save(user);
//任何操作都会被忽略 被忽略了我们自己的操作
//现在只有两种状态 被修改 (删除不被执行)
user.setId(1);
//在保存的session里面找到这个 并且进行管理
//没有意义的 因为不会被执行(只会根据现在的值进行改变)
session.delete(user);
transaction.commit(); // 事务提交
//离线状态 数据库中有但是不被session所管理
session.close();
sessionFactory.close();*/
/* User user=new User();
user.setId(5);
user.setRemark("备注:555555");
user.setSex("女");
user.setBirthday(new Date(new java.util.Date().getTime()));
user.setUserPwd("123");
user.setUserName("zlx");
user.setRealName("赵立新");
session.save(user);
//这条语句有没有意义 (没有意义)
user.setUserPwd("4567");
session.save(user);
transaction.commit();
session.close();
sessionFactory.close();*/
//当session没有关闭之前 都是持久化对象
//都是没有意义的 因为值已经被保存到内存中
}
}
Session的缓存在于速度快 占用内存低
因此Session的缓存可以提高数据访问的性能。
3.Hibernate的加载策略
加载策略分为两种:立即加载、延迟加载
1.立即加载:在执行数据库操作时,是立刻生成sql语句完成操作
示例如下:
public User getUser(User user) {
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
System.out.println(123);
User u = session.get(User.class, user.getId());//立即加载
System.out.println(456);
System.out.println(u.getId());
System.out.println(u.getUserName());
transaction.commit();
session.close();
return u;
}
效果如下:
懒加载:
lazy="true" 可以在实体类设置一个值控制他的懒加载
立即加载:不管你需不需要,它都给你生成sql语句 耗性能,性能差
懒加载:你需要什么就加载什么 相比立即加载它的性能更好
4.Hibernate的并发控制
原因:同一条数据同时由多个人操作
Hibernate处理并发:通过更新状态来解决,分为如下四步
1.在数据库中添加一个字段
3.在对应实体类的映射文件的设置<version name="version" type="java.lang.Integer" column="version"></version>,用于状态列与状态属性关联
注意:version标签必须在property标签之前,否则会违反hibernate的dtd约束,会报以下错误:xml解析错误
Caused by: org.hibernate.boot.InvalidMappingException: Could not parse mapping document: com/zking/two/entity/Student.hbm.xml (RESOURCE)
4.每次操作时都传递状态属性,数据库会自动更新对应的状态列(每次更新状态,状态值会加1)
原数据库的数据
示例:我把姓名的gay的学生改gay xiang,代码如下:
执行代码后,结果如下:
如果用sql语句描述话:update t_hibernate_student set version = version + 1,sname = ? where sid = ? and version= ?
假如两个人同时对数据进行操作,versionqq原本为1,被第一个人修改后变成了2
那第二个人再进行数据操作时,数据已经更新,version已经变成了2,第二个人的version还是1,所以第二个人的操作会报错
ERROR: HHH000346: Error during managed flush [Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.study.entity.Student#5]]