一、Configuration类:
1、 作用:
(1)管理hibernate配置信息
(2)读取hibernate.cfg.xml文件
(3)加载hibernate的驱动,例如:url,用户名
(4)管理对象关系映射文件<mapping resource="">
一个应用程序只创建一个Configuration对象。
2、常用的Configuration的操作方法:
(1)创建Configuration类的实例:
Configuration config = new Configuration().configure();
Hibernate会自动在当前CLASSPATH所指定的路径下查找Xml配置文件hibernate.cfg.xml,并将其内容加载到内存中,为后续工作做好准备。
(2)不使用默认的hibernate.cfg.xml,使用自定义的配置文件:
File file = new File("e:\\work\\hibernate.xml");
Configuration config = new Configuration().configure(file);
(3) 为Configuration指定持久化类: 可以直接实例化Configuration来获取一个实例 并为他指定XML映射定义文件 如果映射定义文件在类路径中 请使用addResource()
Configuration cfg = new Configuration().addResource("com/demo/hibernate/beans/User.hbm.xml");
(4) 为Configuration指定持久化类: 指定被映射的类 让Hibernate帮你寻找映射定义文件
Configuration cfg = new Configuration().addClass(com.demo.hibernate.beans.User.class);
(5)Configuration的三种加载方式:在Hibernate的启动与开发流程中 要使用一个Configuration 需要为他设置三个方面的内容
A.数据库连接属性
B.hbm.xml文件
C.POJO类
其中 第二个和第三个只需要设置一个 就会自动需找另一个 因为这两者只需一个
第一种方式是使用hibernate.cfg.xml 该文件设置了数据库连接的属性和hbm.xml映射文件配置 hibernate会自动加载该配置属性 并自动找到POJO 因此要取得Configuration对象 只需要简单的创建改对象即可
Configuration cfg = new Configuration();
cfg.configuration("hibernate.cfg.xml");
第二种方式是通过hibernate.properties 省略
第三种方式是完全在构造时进行硬编码设置 设置过程如下所示
Configuration cfg =new Configuration()
.addClass(com.demo.hibernate.beans.User.class)
.setProperty("hibernate.dialect","org.hibernate.dialect.MySQLInnoDBDialect")
.setProperty("hibernate.connection.datasource","java:comp/env/jdbc/test")
.setProperty("hibernate.order_update","true");
二、SessionFactory接口:
1、作用:
a)用来产生和管理Session
b)通常情况下每个应用只需要一个SessionFactory
c)除非要访问多个数据库的情况
d) 关注两个方法即: openSession 和 getCurrentSession
i. openSession每次都是新的,需要close
ii.getCurrentSession 从上下文找,如果有,用旧的,如果没有,建新的
1.用途,界定事务边界
2.事务提交自动close
3.跟current_session_context_class (JTA、thread) 有关系
a)thread 使用 connection
注:上下文是什么?当前session运行的上下文,在hibernate.cfg.xml里指定的:
最常用的就是thread,看当前的线程里有没有session对象,有了就拿,没有就建新的。
<property name="current_session_context_class">thread</property>
2、SessionFactory,产生session的工厂。一般情况下,每一个session里都有一个数据库的连接,所以产生session的工厂里边一定有好多个数据库连接,所以SessionFactory维护的最重要的东西就是数据库连接池。当它产生一个session的时候,他会从数据库连接池拿出一个连接交给session。
三、Session接口:
(一)Session概述
1、Session接口是Hibernate向应用程序提供的操纵数据库的最主要的接口,它提供了基本的保存、更新、删除和加载Java对象的方法。(注意:查询功能是由Query接口实现,但Query的对象是由Session获取的)
2、Session具有一个缓存(Hibernate的一级缓存),位于缓存中的对象称为持久化对象,它与数据库中的相关记录对应。Session能够在某些时间点,按照缓存中对象的编号来执行相关的SQL语句,来同步更新数据库,这一过程被称为刷新缓存(flush)
3、站在持久化的角度,Hibernate把对象分为4种状态:持久化状态、临时状态、游离状态、删除状态,Session的特定方法能使对象从一个状态转换到另一个状态。
(二)持久化对象的状态:
1、临时对象(Transient):
1)在使用代理主键的情况下,OID通常为null
2)不处于Session的缓存中
3)在数据库中没有对应的记录
2、持久化对象(托管)(Persist):
1)OID不为null
2)位于Session缓存中
3)若在数据库中已经有和其对应的记录,持久化对象和数据库中的相关记录对应
4)Session在flush缓存时,会根据持久化对象的属性编号,来同步更新数据库
5)在同一个Session实例的缓存中,数据库表中的每条记录只对应唯一的持久化对象
3、删除对象(Removed):
1)在数据库中没有和其OID对应的记录
2)不再处于Session缓存中
3)一般情况下应用程序不该再使用被删除的对象
4、游离对象(脱管)(Detached):
1)OID不为null
2)不再处于Session缓存中
3)一般情况下游离对象由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录
(三)Session的核心方法:
1、Session 的 save() 方法:使一个临时对象转变为持久化对象,完成以下操作:
把 News 对象加入到 Session 缓存中, 使它进入持久化状态
选用映射文件指定的标识符生成器, 为持久化对象分配唯一的 OID. 在 使用代理主键的情况下, setId() 方法为 News 对象设置 OID 使无效的.
计划执行一条 insert 语句:在 flush 缓存的时候
Hibernate 通过持久化对象的 OID 来维持它和数据库相关记录的对应关系. 当 News 对象处于持久化状态时, 不允许程序随意修改它的 ID
persist() 和 save() 区别:当对一个 OID 不为 Null 的对象执行 save() 方法时, 会把该对象以一个新的 oid 保存到数据库中; 但执行 persist() 方法时会抛出一个异常.
2、Session 的 get() 和 load() 方法:都可以根据跟定的 OID 从数据库中加载一个持久化对象,区别:
当数据库中不存在与 OID 对应的记录时, load() 方法抛出 ObjectNotFoundException 异常, 而 get() 方法返回 null
两者采用不同的延迟检索策略:load 方法支持延迟加载策略。而 get 不支持。
3、Session 的 update() 方法:使一个游离对象转变为持久化对象, 并且计划执行一条 update 语句.
若希望 Session 仅当修改了 News 对象的属性时, 才执行 update() 语句, 可以把映射文件中 <class> 元素的 select-before-update 设 为 true. 该属性的默认值为 false
当 update() 方法关联一个游离对象时, 如果在 Session 的缓存中已经存在相同 OID 的持久化对象, 会抛出异常
当 update() 方法关联一个游离对象时, 如果在数据库中不存在相应的记录, 也会抛出异常.
4、 Session 的 saveOrUpdate() 方法:
判定对象为临时对象的标准
Java 对象的 OID 为 null
映射文件中为 <id> 设置了 unsaved-value 属性, 并且 Java 对象的 OID 取值与这个 unsaved-value 属性值匹配
5、 Session 的 merge() 方法:
6、Session 的 delete() 方法:既可以删除一个游离对象, 也可以删除一个持久化对象。处理过程是:
计划执行一条 delete 语句
把对象从 Session 缓存中删除, 该对象进入删除状态.
强调:session获取Connection对象的方法是调用doWork()方法
session.doWork(new Work() {
@Override
public void execute(Connection conn) throws SQLException {
System.out.println(conn);
}
});
四、Transaction接口: ,就是一组对数据库的操作集合,它们要么全部成功,要么全部失败.这个可以保证数据的一致性,事务具有原子性。
1、Hibernate本身没有实现自己的事务管理功能,而是对底层JDBC事务或 JTA用户事务 ( 在两个系统或两个数据库同时使用事务)的轻量级封装
2、hibernate对数据的操作都是封装在事务当中,并且默认是非自动提交的方式,所以用session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库中。
3、使用hibernate进行操作时,(增删改)必须显示的调用Transaction
示例:
Transaction ts=s.beginTransaction();
...
ts.commit();
s.close();
发生异常需要ts.rollback()回滚。
五、Query接口: 是Hibernate的查询接口,用于从数据存储源查询对象及控制执行查询的过程,Query包装了一个HQL查询语句。
1、用法: 通过SessionFactory获得了session对象后,除了可以通过get(类名.class, id)方法得到相应的对象,还可以通过获得Query对象来取得需要的对象
Query对象在Session对象关闭之前有效,否则会抛出SessionException异常。因为Session对象就像JDBC中的Connection 对象,即数据库的一次连接。关闭Connection对象,Statement对象就不能再使用,所以关闭Session后就不能再使用Query对象了。
2、常用方法:
(1)setxxx():用于设置HQL语句中问号或者变量的值;设置HQL语句中问号或者变量的值有两种使用方式:
A.setString(int position,String value);设置HQL中的“?”的值,其中position代表“?”在HQL中的位置,value是要为“?”设置的值
例:
Query query=session.createQuery("from UserInfoPO u where u.age>? and u.useName like ?");
query.setInteger(0, 22); //使用"?",第一个下标是从0开始的,给第一个问号赋值22
query.setString(1, "%志%"); //设置第二个问号的值为“%志%”
B.setString(String paraName,String value);设置HQL中“:”后所跟变量的值;其中paraName代表HQL中“:”后边的变量名,value是该变量的值:
例:
Query query=session.createQuery("from UserInfoPO u where u.age>:minAge and u.useName like:useName");
query.setInteger("minAge", 22); //设置minAge的值
query.setString("userName", "%志%"); //设置useName的值
(2)list();返回查询结果,并把查询结果转换成list对象;也可以用query.uniqueResult();//得到一个单个的对象
Query query=session.createQuery("from UserInfoPO u where u.age>:minAge and u.useName like:useName");
query.setInteger("minAge", 22); //设置minAge的值
query.setString("userName", "%志%"); //设置useName的值
List<UserInfoPO> list=query.list();
for(int i=0;i<list.size();i++){
ui=(UserInfoPO)list.get(i);
System.out.println(ui.getUserName());
}
(3)executeUpdate();执行更新和删除语句
Query query=session.createQuery("delete from UserInfoPO");
query.executeUpdate(); //删除数据
(4)分页查询:
query.setFirstResult(位置如0);//表示从哪个位置开始查询,返回query对象
query.setMaxResult(记录条数);//表示当页共几条记录,返回一个集合
session.createQuery("select count(*) from 类名").uniqueResult();//得到记录总数