hibernate 处于我们项目的持久层的位置,因此有人又把 hibernate 称为持久层框架。把对象持久化的意思就是:把对象的信息保存到数据库或者文件。也就是当应用程序退出以后,仍然可以获取对象信息
hibernate 的事务就是不可分割的事情
hibernate 是对 jdbc 轻量级的封装,有 4 个核心的技术:Configuration、SessionFactory、Session、Transtraction,其中 Configuration 是类,其他三个是接口。
configuration 的用处:1、读取 hibernate.cfg.xml 2、管理对象关系映射文件 3、加载 hibernate 驱动 ,url 以及用户名,密码.... 4、管理 hibernate 配置信息(mapping resource)
sessionfactory(会话工厂) 1、可以缓存 sql 语句和数据,称为 session 级的缓存 2、它是一个重量级的类,因此我们需要保证一个数据库只有一个 sessionfactory
学习 hibernate 的三个重点:
1、学习 hibernate 的 api
2、hibernate.cfg.xml(这个是 hibernate 的核心配置文件)
3、对象关系映射文件
通过 sessionfactory 获取 session 的两个方法:openSession()和 getCurrentSession();
1、openSession() 是获取一个新的 Session:
Session s1 = MySessionFactory.getSessionFactory().openSession();
Session s2 = MySessionFactory.getSessionFactory().openSession();
这两个 Session 对象 s1 和 s2 不是同一个对象,我们可以通过输出它们俩的 hashcode 从而可以看出它们俩的 hashcode 是不同的
2、getCurrentSession() 获取和当前线程绑定的 session,就是在同一个线程中,获取的 session 是同一个 session,这样可以利于事务的控制
Session s1 = MySessionFactory.getSessionFactory.getCurrentSession();
Session s2 = MySessionFactory.getSessionFactory.getCurrentSession();
使用原则:
如果希望在同一个线程中,保证使用同一个 session,则使用 getCurrentSession(),如果在一个线程中,需要使用不同的 session 则使用 openSession()
3、通过 getCurrentSession() 获取的 session 在事务提交后,会自动关闭,通过 openSession() 获取的 session 则必须手动关闭
4、如果是通过 getCurrentSession() 获取的 session,进行查询需要事务提交
如何确定 session 有没有及时关闭?
在 windows 下,从命令行进入 netstat -an [oracle数据库,查:1512,mysql,查:3306,sql server:1433]
Session 会话(接口):
1、session 的一个实例代表与数据库的一次操作,当然可以是 CRUD 的组合
2、Session 实例通过 SessionFactory() 获取,用完需要关闭
3、Session 是线程不同步的(不安全),因此要保证在同一个线程中使用,可以用 getCurrentSession()
4、Session 可以看做是持久化管理器,它是与持久化操作相关的接口
Session 接口里面的 get 和 load 方法的区别:
1、如果查询不到数据,get 方法会返回一个 null,但是不会报错,而 load 如果查询不到数据,则抛出一个异常
2、使用 get 查询数据,会立即访问数据库,发出查询请求(也就是发 select 语句)但是如果使用的 load 查询,即使查询到数据,它返回的是一个代理对象,如果后面没有使用查询结果,它不会真的向数据库发 sql 语句,当后面使用到查询结果的时候,才去发 sql 语句,这个现象称为 lazy 加载(懒加载),这个相当于一个优化
3、通过修改配置文件可以取消懒加载
hibernate 的一级缓存不需要配置就可以使用,但是二级缓存必须要先配置才能使用
load 方法首先到一级缓存(session 缓存)去查询,如果差不多,再到二级缓存去查,如果仍然查不到,那么它就不查了,等到后面用的时候,再去访问数据库查询,在返回查询结果的同时,也产生了 sql 语句(因为访问了数据库),但是如果再次使用 load 进行查询同一个东西,那么就不会再次访问数据库,因为第一次查询的时候,已经把查询结果放在了二级缓存中,所以 load 会在二级缓存里面找到该结果,也不会产生 sql 语句,等到第二次查询结束后,那么该东西就到了 session 缓存里面了,这个时候,再用 get() 方法查询相同的东西的时候,同样不会产生 sql 语句,直接在 session 缓存里面取出,所以用 hibernate 可以减少对数据库查询的次数
手动配置 hibernate 方式开发一个 hibernate 项目,完成 CRUD (增加:create、查询:retrieve、更新:update、删除:delete)操作:
开发流程:
1、创建一个项目
2、引入 hibernate 开发包
3、开发 hibernate(有 3 种方式)
<1> Domain object ---> mapping ---> DB
<2> DB ---> mapping ---> Domain object (使用较多)
<3> 由映射文件开始(使用较少)
4、 开发 domain 对象和对象关系映射文件,该文件的作用是用于指定 domain 对象和表的映射关系,该文件的命名有规范,一般为:domain对象.hbm.xml ,一般放在和 domain 对象同一个文件夹(包)下,domain 对象就是 java 文件。一般映射文件的配置需要一个 DTD 来指定格式,这个 DTD 可以在 hibernate 文件夹下有一个 project 文件夹,那里面有很多 examples,在该文件夹下搜索user.hbm.xml 文件,随便打开一个,就会有 dtd ,然后修改为自己的就行了,而 hibernate.cfg.xml 文件的关于数据库的各种配置,包括:方言,driver class,url 等,可以到 hibernate 文件夹下的 project——>etc 文件夹下的 hibernate.properties.template 文件里面去找
5、手动配置 hibernate.cfg.xml, 该文件用于配置链接数据库的种类,以及数据库驱动,用户名,密码,url....等,该文件的名字一般不能修改
只要把类和映射文件写出来, hibernate 会自动创建对应该数据库类型的表