寒莎

导航

Hibernate系统知识

                                     Hibernate

//----------------------------------------------------------------------------------

                         第一篇:hibernate入门
//----------------------------------------------------------------------------------

 1. 应用程序的分层体系结构
        表示层
          |
        业务层
Object    |
   |    持久层  (Hibernate JPA)
Mapping   |
   |      |
Relation 数据层

  2.Hibernate是最流行的ORM(Object-Relation Mapping:对象/关系映射)框架之一,也是最早实现JPA的规范框架之一,它被jboss收购后,目前作为jboss的一个开源框架,
    其中,涉及JPA的子项目有三个:Hibernate Core,Hibernate 框架的核心实现;Hibernate Annotations,支持jdk 5.0 的注释;
    Hibernate EntityManager支持JPA的实现
        概念:
               ORM全称为Object-Relation Mapping,对象/关系映射:就是利用描述对象和关系数据库之间映射的源数据,自动的把Java应用程序中的对象持久化到关系数据库的表
               ORM框架的作用:帮助我们利用面向对象的思想开发基于关系型数据库的应用程序:
                              *1*将对象数据保存到关系数据库的表中
                              *2*将关系数据库表中数据读入到对象中
               ORM的优势:
               
提高生产率:减少了重复性的持久性相关的代码,减少开发时间。
               
可维护性:重构方便,提高可维护性。
               
更好性能:ORM为性能优化问题考虑得比你更多。
               
厂商独立性:不依赖数据库,你的应用更具有可移植性。
3.配置Hibernate框架:
 3.1架包的使用:
                核心包:Hibernate-core-3.x.x.jar
                产生查询分析器:antlr-2.7.6.jar
                po字节码的动态生成:javassist-3,9.0.jar
                规范包:jta-1.1.jar
                解析xml配置文件和xml映射文件:dom4j-1.6.1.jar
                日志服务通用库:slf4j-api-1.5.8jar
                日志服务实现库:log4j.jar
                slf4j和log4j之间的转换: slf4j-log4j12-1.5.8.jar
  3.2 ##  a. 添加hibernate配置文件hibernate.cfg.xml,(根据工程实例进行编写)
               常用配置:
                        数据库连接参数配置
                        数据库方言配置
                        数据库连接池配置
                        指定对象关系映射文件
                        缓存属性配置
                        其它配置:如是否输出SQL到控制台等。
   b. 添加日志服务配置文件log4j.properties
          c. 设计持久化实体类:只要是一个POJO(Plain Ordinary Java Objects就是简单javaBean,为了避免和EJB混淆所造成的简称)即可
                               必须具备的条件:c1.为所有属性声明getter和setter方法。
                                               c2.
有一个默认的构造方法。
                                               c3.
提供一个作为对象标识符(OID)的属性。
                                               c4.
如果属性的类型是集合,则必须定义成接口类型。如:List、Set、Map。
                                               c5.
持久化类如果要支持序列化,则需要实现Serializable接口

          d.创建对象-关系映射文件 User.hbm.xml
            要在Hibernate配置文件中指明映射文件的位置<mapping resource="com/qiujy/domain/User.hbm.xml" />

            主键生成器最常用的两种:native:根据底层数据库对自动生成标识符的支持能力来选择identity,sequence或hilo.适用于代理主键。主键类型要是long、int或short。
                                    uuid:Hibernate采用128位的UUID算法来生成标识符。UUID算法能够在网络环境中生成唯一的一个32位16进制数字的字符串。适用于代理主键。String类型的数据

   e.使用Hibernate API 进行持久化操作
            操作过程
           
根据hibernate的默认配置文件构建一个(全局的)SessoinFactory实例
              SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
           
获取Session实例
             Session session = sessionFactory.openSession();
          
开启事务
             session.beginTransaction();
          
利用Session实例进行持久化操作
            session.save(Object obj);
         
提交事务
             session.getTransaction().commit();
         
关闭Session
            session.close();                  
         f.Session类主要用来执行实体的持久化操作。
          Session中的方法几乎都声明抛出org.hibernate.HibernateException非受检异常。
         新增:session.save(account);
         修改:session.update(account);
         删除:session.delete(account);
         根据ID来查询:
           session.get(Account.class, id);
              session.load(Account.class, id);
         根据指定参数来查询:
            Query query = session.createQuery("from Account where loginname=:loginname");
            query.setString("loginname", account.getLoginName());
            List list = query.list();
        g.Hibernate核心类和接口
  Configuration类:加载Hibernate配置,创建SessionFactory对象,Configuration接口负责管理Hibernate的配置信息并且根启动Hibernate:
  SessionFactory接口:初始化Hibernate,充当数据库源的代理,充当session对象
                      特点:
        线程安全,即同一个SessionFactory实例可以被应用的多个线程共享。
                            它是重量级的,因为它需要一个很大的缓存,用来存放预定义的SQL语句以及映射元数据等。所以,如果应用程序只访问一个数据库,则只需要创建一个SessionFactory实例。
         Session接口:也被称为持久化管理器提供了和持久化相关的操作(CRUD Create  Retrieve查询  ),负责查询,删除,修改,添加对象
  Transaction接口:管理事务
  Query和Criteria接口:执行数据库查询
                      Query包装了一个HQL(Hibernate Query Language)查询语句。
                             Criteria 接口完全封装了基于字符串形式的查询语句,比Query更加面向对象,Cirteria接口擅长于执行动态查询。
 调用代码:
                List list = session.createQuery("from User").list();
                List list = session.createCriteria(Student.class)
    .add(Restrictions.like("name", "张%"))
    .add(Restrictions.like("grade", "二%"))
    .addOrder(Order.desc("id"))
    .list();

 注意:使用Hibernate进行操作时(增、删、改)必须显示的调用Transaction(默认:autoCommit=false)。
4.Hibernate 的工作流程:
        开始
         |
Configuration con=new Configuration().configure();
    启动Hiberante
         |
 构建Configuration实例
         |
Configuration实例加载hiberation.cfg.xml文件至内存
        |
加载映射文件*。hbm.xml文件
        |
Configuration实例根据hibernate.cfg.xml文件加载映射文件(*。hbm.xml)至内存
        |
Configuration实例构建一个sessionFactory实例
SessionFactry sesssionFactory=con.buildSessionFactory();
        |
SesssionFactory创建session实例
Session session=sessionFactory.openSession();
        |
由Session实例创建Transaction的一个实例,开启事务
        |
通过session的各种接口提供的各种方法操作数据库
       |
 提交或回滚事务
        |
  关闭session
 |
      结束
5。session缓存(一级缓存)
   原理:当应用程序调用Session的crud方法时,如果session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中
         当清理缓存时,Hibernate会根据缓存中对象的状态变化来同步更新数据库
   作用:a。减少数据库的访问频率,(持久化上下文调整缓存)
         b. 保证缓存中的对象与数据库中的对应数据同步(自动脏检查)
     位于缓存中的对象称为持久化对象,当缓存中持久化对象发生变化时,Session并不会执行相关的sql语句,这使得session
     能够把几条相关的sql语句合并成一条sql语句,减少数据库的访问次数,提高效率
    
   清理缓存的时间点:当应用程序调用Transction的commit()方法时,
                      commit()方法会清理缓存,然后再向数据库提交事务
       当应用程序中显示调用session的flush()方法时。
                     还可以通过Session的setFushMode(FlushMode fm)方法来设定清理缓存的时间点。主要有四种模式:
                              FlushMode.ALWAYS:Session在执行查询前,总是先清理缓存。
                              FlushMode.AUTO:Session的查询方法,commit方法,flush方法都会清理缓存.(默认方式)
                              FlushMode.COMMIT:Session的commit方法,flush方法会清理缓存.
                              FlushMode.MANUAL:Session的flush方法会清理缓存.
6。持久化生命周期:
    6.0 Hibernate中的实体对象状态:瞬时状态(Transient没有纳入session的管理),持久化状态(Persistent 纳入session的管理)
                                  托管状态(detached不处于session的管理中,曾经与某个持久化上下文发生过关联,上下文已经关闭了)
                                  移除状态:(removed,如果在工作单元中要删除,他就处于移除状态)
 

  6.1 save()方法使一个瞬时状态的对象转变为持久化状态的对象
       get()和load()方法,加载一个持久化对象
  异同点:
            2. 缓存中不存在给定OID对应的持久状态对象:
                get方法:执行SQL从数据库获取。
                load方法:返回一个代理对象。(延迟加载,懒加载)
           3. 如果数据库不存在给定OID对应的记录:
               get方法:返回null
              load方法:抛出ObjectNotFoundException异常
6.4. delete()方法可以使一个持久化对象变成瞬时,从数据库中移除它的持久化状态。
      如果传入的参数是持久化对象,Session就计划执行一个delete语句
      如果传入的参数是脱管对象,先将脱管对象与Session关联使之变为持久化对象,再计划执行一个delete语句。
      此时对象处于移除状态。
      Session在清理缓存的时候才执行delete语句。
6.5 如果想要保存对脱管对象所做的修改,必须重附或合并它。
    update()方法可以使一个脱管对象重附到新的session中,成为持久化对象。
    计划执行一个update语句:只有当Session清理缓存时,才会执行update语句,此时才把此持久化对象的当前属性值组装到update语句中。程序中多次修改了持久化对象的属性值,在Session清理缓存时也只会执行一次update语句。
6.6 方法签名:
         public Object merge(Object object) throws HibernateException;
         将给定实例的状态复制到具有相同标识符的持久化实例上,并返回这个持久化实例。

                        第二篇 Hiberante基本查询
1。Hibernate查询方式:
      Query是Hibernate专门用来执行HQL语句的查询接口
      使用方式:Query query = session.createQuery("HQL语句");
   a.Hiberante查询语言(Hibernate query language):是面向对象的查询,具备继承,多态和关联的特性
       HQL基本用法
               a1. 投影查询     Query query = session.createQuery("from User");
               a2. where条件子句    a21.占位符的使用
                                    Query query = session.createQuery("from User where name=?");
                       request.setString(0,"www");
                                    a22.第二种方式:(:key)
                                      Query query = session.createQuery("from User where name=:name");              
                               query.setParameter("name","hello");
                      a23.第三种方式:(多个:key)
                                            Map<string,Object> m=new HashMap<String,Object>();
                                            m.put("占位符","占位符的值");
                                            query.setProperties(m);
                                           

        a3.调用标准函数
                a4. 参数绑定
                a5. distinct过滤重复值   “SELECT  destinct  s.age FROM Student  AS s"
                a6. 聚集函数               "SELECT  count(s)  FROM  Student   AS  s"

                a7. order by子句            FROM  Student  AS  s ORDER BY  s.id  DESC     
                a8. group by子句            SELECT  s.grade, COUNT(*)  FROM  Student  AS  s GROUP BY  s.grade
                a9. having子句              SELECT  s.grade  FROM  Student  AS  s GROUP BY  s.grade HAVING  COUNT(s.id) > 20
                a10. 分页查询
                        setFirstResult(int firstResult):设置检索返回的首个对象的位置。默认的起始位置是0。
                        setMaxResult(int maxResults):   设置每次检索返回的最大对象数
                              Query query = session.createQuery("FROM Student"); 
                              List list = query.setFirstResult(9).setMaxResult(10).list();

                       
                a11.  批量更新和删除
                       String hql = "DELETE  Student  AS s WHERE s.name LIKE :likeName";
                      Query query = session.createQuery(hql); 
                      query.setString(“likeName”, “%三%”);
                      int count = query.executeUpdate();   // 返回受此操作影响的记录数量

   注意:
    where和having的区别在于作用对象不同:where作用于类的属性
                                      having作用于分组后的组

   
    b.标准化条件查询(criteria queries):比sql语句更面向对象的查询语句
      QBC(Queries by criteria)主要由四部分组成:
       Criteria接口:一个查询条件存放容器。
                       通过Session的createCriteria(Class persistentClass)来获取实例。
       Criterion接口:代表一个查询条件。
              Restrictions类:提供了一系列用于产生具体查询条件实例的静态方法。
                  作为hibernte2中Expression的替代
              具体的查询条件通过Criteria的add()方法添加到Criteria实例中。
        Order类:提供对查询结果进行排序的静态方法。
               通过Criteria的addOrder()方法来添加。
        Projection接口:代表投影查询。
        Projections类:提供了一系列产生具体Projection实例的静态方法。
                 通过Criteria的setProjection()方法来添加。
  举例://通过session创建一个Criteria实例
           Criteria criteria = session.createCriteria(Student.class);
        //设定查询条件
            Criterion criterion1 = Restrictions.like("name", "张%");
            Criterion criterion2 = Restrictions.like("grade", "初三%");
        //把查询条件加入到Criteria中
            criteria.add(criterion1);
            criteria.add(criterion2);
             criteria.addOrder(Order.desc("id"));
        //执行查询语句,返回结果
             List list = criteria.list();
   a和b两种语言的区别:
   hql适用于静态查询和业务比较复杂的查询;在
   qbc适用于动态查询:只有在程序运行时才能明确要查询的字段
   c.高级查询:
      子查询:
            String hql = "from Account a where (select count(o) from a.orders o)";
            List<Account> list = session.createQuery(hql).list();
     连接查询:
     抓取连接

 

   d.原生sql查询(native sql Queries):直接使用sql语言或特定数据库的查询
       对原生SQL查询的控制是通过SQLQuery接口进行的
       通过执行Session.createSQLQuery()获取这个接口。
    例子:
      //创建一个SQLQuery接口实现类的实例(传入的是SQL语句),然后执行查询
       List<Account> list = session.createSQLQuery(
    "SELECT  *  FROM  ACCOUNT  WHERE id > :id limit 3")
   . addEntity(Account.class)  //加入要返回的实体
   .setLong("id", 1)    //给命名参数传值
   .list();    //执行查询

   e.调用存储过程:(没有使用过的)
  
     存储过程/函数必须返回一个结果集,作为Hibernate能够使用的第一个外部参数。
     DROP PROCEDURE IF EXISTS findAccounts;
     CREATE PROCEDURE findAccounts(IN idValue bigint(20))
     begin
     select * from account where id > idValue;
     end;

     在Hibernate通过命名查询来映射存储过程:
     </hibernate-mapping>
    ...
    <sql-query name="findAccounts">
        <return alias="acc" class="com.qiujy.domain.Account">
            <!-- 如果实体类的属性名和表的字段名相同,以下可省略 -->
            <return-property name="id" column="id"/>
            <return-property name="userName" column="userName"/>
        </return>
        <!-- 调用存储过程 -->
        {call findAccounts(:idVal)}
    </sql-query>
    </hibernate-mapping>

 

 

                           第三篇:集合映射
*集合映射
 set:元素存放没有顺序且不可以重复
 bag:
 list:元素有序且可以重复
 Map:键值对应
 排序集合和:在<set>和<map>元素上添加sort属性,指定排序规则
                     <set name="hobbies" table="student_hobby" sort="natural">
              <!-- key子元素:指定集合属性对应的表的外键列 -->
              <key column="student_id" />
              <!-- element子元素:映射集合内的元素 -->
              <element type="string" column="hobby_name" not-null="true" />
                     </set>
有序集合:有序集合是指在从数据库获取数据时就使用SQL语句的order by语句排好序,然后再封装到集合中存放。
          <set name="hobbies" table="student_hobby" order-by="hobby_name desc">
   <!-- key子元素:指定集合属性对应的表的外键列 -->
   <key column="student_id" />
   <!-- element子元素:映射集合内的元素 -->
  <element type="string" column="hobby_name" not-null="true" />
         </set>
集合映射的简单原则:
  大部分情况下用<set>。
  实体类中的某个属性用了List类别,可以使用<bag>来映射。
  很少情况下会使用到<list>和<map>
*关联关系映射  (详细请查看工程中的readme.txt,或者根据实例来理解)
 多对一(many-to-one)
 一对一(one-to-one)
 一对多(one-to-many)
 多对多(many-to-many)
 *高级关系映射
  继承关系映射
  组件映射
  复合主键映射<PIXTEL_MMI_EBOOK_2005>11                                                          </PIXTEL_MMI_EBOOK_2005>

posted on 2012-04-25 14:08  寒莎  阅读(288)  评论(0)    收藏  举报