Hibernate基础

原理:

1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件

2.由hibernate.cfg.xml中的<mapping resource="com/xx/User.hbm.xml"/>读取并解析映射信息

3.通过config.buildSessionFactory();//创建SessionFactory

4.sessionFactory.openSession();//打开Sesssion

5.session.beginTransaction();//创建事务Transation

6.persistent operate持久化操作

7.session.getTransaction().commit();//提交事务

8.关闭Session

9.关闭SesstionFactory

为什么要用:

1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。

2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作

3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。

4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。

 

public class UserDaoImpl implements UserDao{ 
  
 
  

         @Override 
  
 
  

         public void insertUser(User u) { 
  
 
  

    //        1.加载配置文件 
  
 
  

              //默认加载Hibernate.cfg.xml文件 如果核心配置文件被修改位置 或 改名字 
  
 
  

    //        Configuration cfg = new Configuration().configure("hibernate.cfg.xml"); 
  
 
  

    //         
  
 
  

    //        2.创建sessionFactory 
  
 
  

    //        SessionFactory factory = cfg.buildSessionFactory(); 
  
 
  

    //         
  
 
  

    //        3.开启session 
  
 
  

               //瞬时态 
  
 
  

    //        Session session = factory.openSession(); 
  
 
  

           
  
 
  

    //        4.开启事务 
  
 
  

              Transaction tx = session.beginTransaction(); 
  
 
  

               
  
 
  

    //        5.Session的CUID 
  
 
  

              //持久态 
  
 
  

    //        session.save(u); 
  
 
  

              session.update(u); 
  
 
  

    //        session.delete(u); 
  
 
  

               
  
 
  

    //        6.事务的提交 
  
 
  

              //游离态 
  
 
  

             
   tx.commit(); 
  
 
  

    //        7.关闭资源 
  
 
  

              session.close(); 
  
 
  

         } 
  
 
  

    }

 

1,   对象状态:         Hibernate将实体类对象分为三种状态

  一  、 临时(瞬时)状态:

    创建对象 --> session管理对象 之间的状态

      特点:

      不被session管理

     不与数据库表 列对应

 

二 、持久化状态:

Session管理 --> 事务提交

Session.save(user);//持久化

特点:

被session 管理

与数据库表 列对应

 

三 、游离(脱管)状态:

事务提交以后-->消亡

特点:

不被session管理

与数据库表 列相对应

 

2,SessionFactory 是否需要关闭????

不需要,SessionFactory的创建耗费资源和内存

 

3,

针对于查询而言,是不需要进行事务的处理的

Hibernate提供两种方式:

Get

Load

Get 与 load 区别:

查询时间不同

  1. get方法查询时是立即加载(执行get方法后,立即向数据库发送sql语句查询回数据)   
  2. load方法查询时才用的是延时加载(执行load方法时,并没有向数据库发送sql语句查询数据,而是返回一个代理对象。load方法是在第一次获取代理对象中,非主键的属性时,才发送sql语句进行查询)

查不到数据,返回结果不同:

  1. 当根据所给主键,查不到数据时,  get方法 返回 null
  2. load方法  抛异常

 

 

hibernate.cfg.xml配置

<hibernate-configuration> 
  
 
  

         <!-- SessionFactory --> 
  
 
  

         <session-factory> 
  
 
  

              <!-- 开启三级缓存 又叫查询缓存 --> 
  
 
  

              <property name="hibernate.cache.use_query_cache">true</property> 
  
 
  

              <!--          开启二级缓存 --> 
  
 
  

              <property name="cache.use_second_level_cache">true</property> 
  
 
  

              <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 
  
 
  

               
  
 
  

               
  
 
  

              <!-- 数据库连接信息 --> 
  
 
  

              <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property> 
  
 
  

              <property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:ORCL</property> 
  
 
  

              <property name="connection.username">hr</property> 
  
 
  

              <property name="connection.password">123</property> 
  
 
  

               
  
 
  

              <!-- 配置方言:根据不同的数据库,生成不同的sql语句 --> 
  
 
  

              <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property> 
  
 
  

               
  
 
  

              <!-- 显示出Hibernate生成的sql语句 --> 
  
 
  

              <property name="show_sql">true</property> 
  
 
  

              <!-- 格式化 sql语句 --> 
  
 
  

              <property name="format_sql">true</property> 
  
 
  

               
  
 
  

              <!-- update:在向数据库中插入数据时,如果表不存在,则会自动创建表;如果存在,则向表中新增数据 --> 
  
 
  

              <!-- <property name="hibernate.hbm2ddl.auto">update</property> --> 
  
 
  

               
  
 
  

              <!-- 映射配置文件 --> 
  
 
  

              <mapping resource="com/zrgk/entity/User.hbm.xml" /> 
  
 
  

              <mapping resource="com/zrgk/entity/Emp.hbm.xml" /> 
  
 
  

              <mapping resource="com/zrgk/entity/Dept.hbm.xml" /> 
  
 
  

              <mapping resource="com/zrgk/entity/Student.hbm.xml" /> 
  
 
  

              <mapping resource="com/zrgk/entity/Course.hbm.xml" /> 
  
 
  

              <mapping resource="com/zrgk/entity/Husband.hbm.xml" /> 
  
 
  

              <mapping resource="com/zrgk/entity/Wife.hbm.xml" /> 
  
 
  

              <mapping resource="com/zrgk/entity/Person.hbm.xml" /> 
  
 
  

              <mapping resource="com/zrgk/entity/IdCard.hbm.xml" /> 
  
 
  

         </session-factory> 
  
 
  

    </hibernate-configuration>

Hibernate的缓存:

  1. 一级缓存 是session级别缓存
  1. 特点:自动开启,不能关闭
  2. 当开启一级缓存时,先去session对象中查找数据,如果没有查找到,则去数据库取值,将取出来的数据先放到session中,再放到对象中;当再有查询时,先去session查找如果查找到,则直接取值,而不需要去数据库中取值;这样减少的数据库的连接数,并提高效率。
  1. 如何清除缓存:
  1. session.flush()     清session的缓存,把数据同步到数据库中 
  1. 如果session中的对象,与数据库中的不一致,就再次查询
  1. session.clear()     清session的缓存,数据不会同步到数据库中
  1. 直接从session中清除
  1. session.evict(user)   把指定对象从session的缓存中清除,数据不会同步到数据库中
  1. 二级缓存
  1. sessionFactory级别的
  1. 数据是所有Session共享的  
  2. 什么样的数据放入到二级缓存中?
  1. 查询多
  2. 少增删改
  1. 使用:
  1. 导入缓存的jar包  -->  ehcache-1.2.3.jar
  2. 在src下放入缓存的策略
  1. 将..\project\cache-ehcache\src\test\resources\ehcache.xml复制到src下
  1. 二级缓存需要手动开启
  1. 在核心配置文件中配置:

<!-- 开启二级缓存 -->

           <property name="cache.use_second_level_cache">true</property>

  1. 指定对象放入到二级缓存中
  1. 方式一:在配置文件中配置:<class-cache usage="read-only" class="com.entity.User"/>
  2. 方式二:在映射文件中配置:<cache usage="read-only"/>
  1. 指定缓存代理商
  1. <!-- hibernate3的二级缓存配置 -->

<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

  1. <!-- hibernate4的二级缓存配置 -->

<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

  1. 禁用缓存
  1. 方式一:<property name="hibernate.cache.use_second_level_cache">false</property>
  2. 方式二:session.setCacheMode(CacheMode.IGNORE); // 设置缓存模式:禁止一级缓存和二级缓存之间进行数据交互
  1. 缓存配置文件:
  1. <diskStore path="java.io.tmpdir"/><!-- 缓存对象存在磁盘上路径 -->
  2. 缓存规则:
  1. maxElementsInMemory  内存中最多缓存多少个对象
  2. timeToIdleSeconds    最大空闲时间(秒)
  3. timeToLiveSeconds    最大存活时间
  4. overflowToDisk       内存中数量超过规定时,是否把对象存到磁盘上     
  5. eternal              是否是永久的
  6. 案例:
  7. <defaultCache
  8. maxElementsInMemory="10000"
  9. eternal="false"
  10. timeToIdleSeconds="120"
  11. timeToLiveSeconds="120"
  12. overflowToDisk="true"
  1. 缓存注意:
  1. 一级缓存和二级缓存都只存储对象,不会存储字段的结果集
  2. get、load、iterate方法支持一级和二级缓存,但list方法不支持
  1. 三级缓存(查询缓存)
  1. 基本步骤
  1. 在配置文件中,配置开启查询缓存:<property name="hibernate.cache.use_query_cache">true</property>
  2. 通过代码设置启用查询缓存:query.setCacheable(true);
  3. 注意:只有list方法支持查询缓存,iterate方法不支持查询缓存