目录
1.概述
1.1对象持久化的3中方式
①序列化对象,将对象存储到格式化的文本文件中。
②将对象持久化到xml文档中。
③将对象持久化到数据库中,一般为关系型数据库。
1.2对象关系映射ORM
ORM(Object/Relation Mapping)实现了java应用中的对象到关系型数据库中表的自动持久化,并使用元数据来描述对象和数据库之间的映射关系。元数据通常采用xml格式。
1.3Hibernate工作原理
// 1.造对象
Employee emp = new Employee();
emp.setEmpName("班长");
emp.setWorkDate(new Date());
// 获取加载配置文件的管理类对象
Configuration config = new Configuration();
config.configure(); // 默认加载src/hibenrate.cfg.xml文件
// 创建session的工厂对象
SessionFactory sf = config.buildSessionFactory();
// 创建session (代表一个会话,与数据库连接的会话)
Session session = sf.openSession();
//2.用session.save()保存到数据库
// 开启事务
Transaction tx = session.beginTransaction();
//保存-数据库
session.save(emp);
// 提交事务
tx.commit();
// 关闭
session.close();
sf.close();
2.核心接口
2.1 Configuration类
作用:
对Hibernate进行配置,启动hibernate并连接数据库系统。
在hibernate的启动过程中,Configuration的实例首先找到xml的配置文件hibernate.cfg.xml,读取相关的配置信息,然后创建一个唯一的SessionFactory对象。
一般一个项目只需要一个Configuration类,如果项目中需要访问多个数据库,就需要创建多个Configuration实例,以此来为每个数据库都创建一个SessionFactory实例。
常用方法:
Configuration config=new Configuration().configure(); 默认加载src/hibernate.cfg.xml。
Configuration config=new Configuration().configure(“cn/config/hibernate.cfg.xml”); 加载指定路径下的主配置文件。
SessionFactory sessionFactory=config.buildSessionFactory(); 创建SessionFactory实例
2.2 SessionFactory接口
作用:
负责Hibernate的初始化。SessionFactory接口作为数据存储源的代理,负责建立session对象。
一般一个项目只需要一个SessionFactory接口,如果项目中需要访问多个数据库,就需要创建多个Configuration实例,以此来为每个数据库都创建一个SessionFactory实例。
特点:
①线程安全,同一实例可以供多个线程共享。
②重量级,不能随意创建和销毁它的实例。
常用方法:
Session session=sessionFactory.openSession(); 创建一个sesison对象
Session session=sessionFactory.getCurrentSession(); 创建session或取出session对象
区别:
openSession()直接创建一个新的Session实例;使用后,需代用session.close()方法手动关闭。
getCurrentSession()创建的Session实例会被绑定到当前线程中;在提交(commit)或回滚(rollback)时,会自动关闭。
2.3 Session接口
作用:
Session接口是Hibernate中使用最广泛的接口,也是持久化操作的核心。
Session对象的生命周期以Transaction对象的事务开始和结束为界。Session提供了一系列与持久化相关的 操作。
特点:
①线程非安全,应避免多个线程共享一个Session实例。
②轻量级,实例的创建和销毁不需要太多的资源。
③有一个缓存,即Hibernate的一级缓存。用于存放当前工作单元加载的对象。
常用方法:
session.save(user) ,将对象加入缓存,并保存到数据库中
session.update(user),将对象加入缓存,并更新数据库中的数据。(此方法必须为对象设置主键)
session.saveOrUpdate(user),若没有设置主键,执行保存;若设置了主键,执行更新;若设置的主键不存在,则报错。
session.delete(user)删除缓存中的记录,并删除数据库中的记录。(此方法必须为对象设置主键)
session.get(User.class,id)通过标识符得到指定类的持久化对象。
session.load(User.class,id)通过标识符得到指定类的持久化对象。
session.contains(user)判断session缓存中是否有指定对象。
session.evict(user)移除session缓存中指定对象(通常先用contains方法判断,再移除)
session.clear()清空session缓存中的全部对象。
Transaction tx = session.beginTransaction();开启事务
创建查询对象的方法:
Query query=session.createQuery("from User"); HQL(Hibernate Query language)语句查询
Criteria criteria = session.createCriteria(User.class); Criteria语句查询
SQLQuery sqlQuery = session.createSQLQuery("SELECT * FROM t_Dept limit 5;").addEntity(Dept.class); SQL语句查询
2.4 Transaction接口
作用:
Transaction接口用于事务管理,它对底层的事务接口(如:JDBC API)进行了封装。用户可以利用Transaction对象定义自己的原子操作。Session执行完数据库操作后,要使用Transaction进行事务的提交后,才能真正将数据操作同步到数据库中。
常用方法:
tx.commit(); 提交事务
tx.rollback(); 事务回滚
3.总结
3.1对象的三种状态
Hibernate中对象的状态: 临时/瞬时态(Transient)、持久态(Persistent)、游离态(Detached)。
- 瞬时态
使用new操作符初始化的对象不是立刻就持久化的,他们的状态是瞬时的。
特点:
(1) 不处于Session的缓存中,即不被任何一个Session实例关联。
(2) 在数据库中没有对应的记录。
- 持久态
当调用session的save/saveOrUpdate/get/load等方法的时候,对象就是持久态。处于持久化状态的对象,当对对象属性进行更改的时候,会反映到数据库中!
特点:
(1) 处于Session的缓存中,被当前Session实例关联。
(2) 在数据库中有对应的记录。
- 游离态
Session关闭后,持久化对象就变为游离对象;
特点:
(1) 不处于Session的缓存中,即不被任何一个Session实例关联。
(2) 在数据库中有对应的记录。
//创建瞬时态对象
User user=new User();
user.setName("xiaohua");
user.setPassword("123");
//user 对象处于瞬时态
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
session.save(user);//调用save方法
//此时已处于持久态
tx.commit();
session.close();//调用close方法
//此时处于游离态
对象状态转换图:
3.2 get、load的区别
①get()如果没有找到持久化类返回null;
load()如果没有找到持久化类直接抛出异常。ObjectNotFoundEcception
②get()是直接返回实体类。不论*.hbm.xml文件中<class>元素的的lazy属性是true还是false。
当调用load()方法的时候,若*.hbm.xml文件中<class>元素的的lazy属性为true,则会返回一个目标对象的代理对象,在这个代理对象中只存储了目标对象的ID值,其他都为null值,只有当调用除ID值以外的属性值的时候才会发出SQL查询。(即load方法采用延迟加载)
当调用load()方法的时候,若*.hbm.xml文件中<class>元素的的lazy属性为false,则是直接返回实体类。
总结:
使用get加载,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null。
使用load加载,Hibernate会认为该id对应的对象是一定存在的,所以它可以放心的使用,它可以放心的使用代理来 延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常。