Hibernate学习笔记(一)

来源:互联网 发布:linux 网络问题排查 编辑:程序博客网 时间:2024/05/22 14:50


基础部分:

ormapping框架:数据库的操作框架
   优点
      1、比较简单
      2、数据缓存:一级缓存    二级缓存   查询缓存
      3、移植性比较好


   缺点
      1、因为sql语句是hibernate内部生成的,所以程序员干预不了,不可控
      2、如果数据库特别大,不适合用hibernate


jdbc的优点和缺点
   缺点
  1、查询代码特别繁琐
  2、重复性代码特别多,频繁的try,catch
  3、数据的缓存
  4、sql的移植性不好
   优点
     速度比较快
     把控性比较好


ormapping:对象关系映射
    让关系型数据库和对象发生关联


*.hbm.xml(映射文件)
   类与表的对应关系
   类上的属性的名称和表中的字段的名称对应关系
   类上的属性的类型和表中的字段的类型对应关系
   把一对多和多对多的关系转化成面向对象的关系


hibernate的配置文件:
   作用是用来连接数据库的


hibernate:
   1、hibernate的加载流程
   2、crud的操作
   3、关系操作    重点
   4、hibernate的优化  重点
       数据缓存
       懒加载
       抓取策略
       ……
   5、hql语句


hibernate配置文件两种加载方式

1、该配置文件必须放在classpath下
2、名称必须为hibernate.cfg.xml


hibernate.cfg.xml
   1、描述数据库的链接的信息
   2、加载映射文件

sessionFactory = configuration.buildSessionFactory();
1、hibernate把数据库的链接信息、把映射文件的信息、持久化类的信息
2、sessionFactory是由单例模式产生的
3、一般情况下一个hibernate应该有一个数据库链接
4、该类本身是线程安全的
5、是一个重量级类


sessionFactory.openSession();
  打开了一个数据库的链接,准备进行数据库的操作


cud的操作

开启事务
   session.beginTransaction();
进行cud的操作
   ……
提交事务,关闭session


注意事项:
   1、一个类是否是持久化类
        1、加载配置文件
        2、在配置文件中加载映射文件
        3、解析映射文件中class元素的name属性,找到对应的类
   2、在客户端的参数的类必须是持久化类


对象的状态:

对象的状态
  临时状态
      new
  持久化状态
      get,save,update
  脱管状态
      clear  close  evict





关系操作:









多对多
  1、关系操作
       1、多对多,谁操作效率都一样
       2、解除关系
             把第三张表的一行数据删除掉
       3、建立关系
             把第三张表的数据增加一行记录
       4、变更关系
             先删除后增加
  2、级联操作
       都是对象针对集合的操作

性能部分:

性能:
   发出的sql语句越少,性能越高
   方法:
      1、懒加载
      2、抓取策略
      3、缓存策略
      4、HQL语句


懒加载
   1、类的懒加载
        1、利用session.load方法可以产生代理对象
        2、在session.load方法执行的时候并不发出sql语句
        3、在得到其一般属性的时候发出sql语句
        4、只针对一般属性有效,针对标示符属性是无效的
        5、默认情况就是懒加载
   2、集合的懒加载
        false  当session.get时,集合就被加载出来了
        true   在遍历集合的时候才加载
        extra
             针对集合做count,min,max,sum等操作
   3、单端关联的懒加载(多对一)
        <many-to-one lazy="false/no-proxy/proxy">  no-porxy 默认值  true
        根据多的一端加载一的一端,就一个数据,所以无所谓




总结:懒加载主要解决了一个问题:类、集合、many-to-one在时候发出SQL语句,加载数据


抓取策略:
   1、研究的主要是set集合如何提取数据
   2、在Classes.hbm.xml文件中
       <set fetch="join/select/subselect">
            join        左外连接
               如果把需求分析翻译sql语句,存在子查询,这个时候用该策略不起作用
            select      默认
               先查询一的一端,再查询多的一端
            subselect   子查询
               如果需要分析翻译成sql语句存在子查询,这个时候用该策略效率最高


懒加载和抓取策略结合:研究对象是set集合
    fetch         lazy                          sql            什么时候发出sql                     说明    
    join          false                      存在子查询         当查询classes时把
                                                            classes和student全部查询出来         这种情况下join没有用
    join          true                       存在子查询        当遍历student时发出查询student    join没用
    join          true                       不是子查询     在session.get(classes)时全部查询出来  这时,lazy没有用
    subselect     true/false                 存在子查询     发出两条sql语句                       如果lazy为true,在遍历集合,如果lazy为false,在一开始就发出
    select        true/false                                发出n+1条sql                         如果lazy为true,在遍历集合,如果lazy为false,在一开始就发出




二级缓存:

二级缓存:存放公有数据
   1、适用场合:
        1、数据不能频繁更新
        2、数据能公开,私密性不是很强
   2、hibernate本身并没有提供二级缓存的解决方案
   3、二级缓存的实现是依赖于第三方供应商完成的
         ehcache
         oscache
         jbosscache
         swamchache
   4、二级缓存的操作
         1、二级缓存存在sessionFactory中
         2、生命周期:与sessionFactory保持一致
         3、使用二级缓存的步骤
             1、在hibernate.cfg.xml
                  <property name="cache.use_second_level_cache">true</property>
                  <property name="cache.provider_class">
                        org.hibernate.cache.EhCacheProvider
                  </property>
             2、让某一个对象进入到二级缓存中
                 * 在配置文件中
                   <class-cache usage="read-only" class="cn.itcast.hiberate.sh.domain.Classes"/>
                 *  在映射文件中
                    <cache usage="read-only"/>
             3、使用
                  session.get/session.load

   5、查询缓存



查询:

hibernate的查询方式
   1、hql(hibernate query language)  query
   2、Criteria query
   3、Native query


new source folder 



session:



session.getCurrentSession的用法
  1、在hibernate的配置文件中:
        <property name="current_session_context_class">thread</property>
  2、不需要写session.close方法,在事务提交的时候会自动关闭(由hibernate内部完成)
  3、crud都需要事务
      1、因为是一个线程,所以整个方法中一个session,一个事务
      2、保证了整个业务操作的安全性


缓存
   1、缓存的生命周期
   2、数据库的数据是怎么样放入到缓存中的
   3、缓存中的数据是怎么样放入到数据库中的
   4、客户端怎么样从缓存中把数据取出来
   5、客户端怎么样把一个数据放入到缓存中
   6、怎么样把一个对象从缓存中取出
   7、把缓存中所有的数据清空


页面缓存


session缓存:
   1、生命周期就是session的生命周期
   2、一级缓存存放的数据都是私有数据
        把session存放在threadlocal中,不同的线程是不能访问的,所以保证了数据的安全性
   3、怎么样把数据存放到一级缓存中
        利用session.save/update/load/get方法都可以存放在一级缓存中
   4、利用session.get/load方法可以把数据从一级缓存中取出
   5、session.evict方法可以把一个对象从一级缓存中清空
   6、利用session.clear方法可以把session中的所有的数据清空
   7、利用session.Refresh方法把数据库中的数据同步到缓存中
   8、session.flush
        在session的缓存内部,会去检查所有的持久化对象
           1、如果一个持久化对象没有ID值,则会发出insert语句
           2、如果一个持久化对象有ID值,则会去检查快照进行对比,如果一样,则什么都不做,如果不一样,则发出update语句
           3、检查所有的持久化对象是否有关联对象
                检查关联对象的级联操作
                检查关联对象的关系操作
   9、批量操作



权限管理练习:


目标:
    根据用户、角色、权限的概念,让用户登录以后获取用户能够访问到的权限,
    根据用户的权限去检查有没有对页面上某一个元素的操作的功能


步骤:
   1、建立持久化类和映射文件生成相应的表
   2、在表中插入测试的数据
   3、需求代码的步骤
       1、在tomcat服务器启动的时候,执行一个ServletContextListener
               把所有的用户和所有的用户能够访问到的权限值全部取出来
               技术点:user,role,privilege三张表的多对多的查询  核心表示user:from User
                       把数据取出来以后可以采用转化成set集合的方式去重复
                       最后把权限的集合封装成为Map,将来用户登录以后,可以根据用户名很容易得取出权限
       2、登录:
             1、输入http://localhost:8080/struts_hiberante_access,跳转到登录页面,所以在web.xml中
                      欢迎页面设置成为login.jsp
             2、先跳转到login.jsp
             3、提交请求,跳转到LoginAction       
                   1、利用模型驱动获取页面的数据
                   2、判断用户名和密码是否正确
                       正确的时候,根据username把该用户能够访问到的权限Set<Privilege>取出来
                       把Set<Privilege>放入到了session中
             4、点击用户管理
                   用户列表页面,在页面上判断该用户是否有编辑、删除、查看的权限,如果有,才能显示其按钮,如果没有,则不显示
                   因为在数据库中已经规定了:"user_update"该字符串是编辑的权限
                                             "user_show"该字符串是查看的权限
                                             "user_delete"该字符串有删除的权限
                   所以得用s:if语句来判断用户的权限有没有这些字符串
             5、判断的过程:
                  1、该用户的权限在session中,利用ognl表达式可以把权限的集合提取出来
                         <s:iterator value="#session.privilege_session">
                  2、<s:if test="">中test的内容能够直接跟ognl表达式,所以name可以直接出现在test中
                           <s:if test="name=='user_show'">







0 0