正文

HibernateNote(2)2008-04-27 11:16:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/ghlat520/34596.html

分享到:

第二章:hibernate 入门
                        本章内容:
                         1)Hibernate核心接口的简介
    2)Hibernate的各个元素组成
                         3)开发Hibernate的基本步骤 
                         4)通过Hibernate ApI编写访问数据库
                         5)访问Session接口的方法
                         6)管理SessionFactory,Session对像
    7)Session与事务的关系
   

     
                             Hibernate核心接口的简介
 hibernate是java应用程序和关系数据库之间的桥梁,它负责java对像和关系数据库之间的映射。
 hibernate内部封装了大量的通过jdbc访问数据库的操作。所以在hibernate开发文档中说hibernate是  对jdbc的轻量级封装。而hibernate向业务层提供了面向对像的数据库访问接口,使我们能够用面向对  像的途径去操作关系型数据库。基本上hibernate的核心可以分成几类:
  1)提供访问数据库操作的接口(保存,更新,删除,查询对像)的接口。这些接口包括:
           Session,Transaction,Query接口
        2)用于配置hibernate的接口:Configuration
        3)回调接口:使用应用程序接受Hibernate内部发生的事件:Interceptor,Lifecycle
        4)用于扩展hibernate的功能的接口:UserType等.
        5)我们平常用得最多的就是前2个接口
        6)所有的hibernate应用中都会访问到hibernate的五个核心接口:
           A:Configuration接口:负责读取hibernate配置文件,从而创建SessionFactory对像
           B:SessionFactory接口:负责创建Session对像
           C:Session接口:负责保存,更新,删除,加载和查询对像。(与jsp中的session不一样)
           D:Transaction:管理事务
           E:Query和Criteria:执行数据库查询
        7)SessionFactory:它是重量级的,这意味着不能随意创建或销毁它的实例。如果应用只访问
          一个数据库,只需要创建一人SessionFactory实例。并且该实例一般是在Web应用程序初始
          化访问该实例。这所以称SessionFactory是重量级的,是因为它需要一个很大的缓存用来存
          放序定义的sql语句。
       8)Session接口是hibernate应用程序中使用最广泛的接口。Session也被称为持久化管理器。
         Session实例是轻量级的。所以它的创建和销毁不需要消耗太多的资源。这意味着在程序中可以经常
         创建或销毁Session对像。 
       
           
   Hibernate的各个元素组成           
   1:POJO(Plain Old Java Object)你可以把它看作是简单的JavaBean.一般说来一张数据库表对应一个          POJO也就是对象/关系的一一映射。
   2:DAO:对于每一个POJO,一般都有一个DAO与之对应,承担所有关于该POJO的访问控制。实际上也就是控制           了对数据库中一张表的访问控制。对表实现最基本的操作。增,删,改,查
   3:*.hbm.xml文件:这个文件定义了POJO和数据库中的表是如何映射的,比如POJO中的字段对应数据库表中            的哪个字段等等。一般每个映射都用单独的文件来描述,也就是有一个POJO就有一个*.hbm.xml文件
   4:Hibernate.cfg.xml文件:这个文件定义了Hibernate的基本信息,比如数据库驱动,用户名,密码等等连           接信息也包括了所有要用的*.hbm.xml文件,在初始化的时候,Hibernate会读取这个文件来找相应            的映射文件完成对象/关系


                       
    开发Hibernate的基本步骤
 1)创建Hibernate的配置文件。
             Hibernate配置文件用来指定Hibernate将与那个数据源进行连接。Hibernate配置文件名一般是        Hibernate.cfg.xml来命名的.值得注意的是这个Hibernate.cfg.xml配置文件不在WEB-INF下面而       在WEB-INF\classes下面。与struts-config.xml不同
             A:先创建一个数据源驱动
                  1:window-->preferences-->MyEclipse-->database explorer-->database drivers-->
                    db Browser(右边)
                  2:注意在添加oracle数据库,不要选择classes12.jar。要添加ojdbc14.jar
                            
             B:选中工程-->Myeclipse-->addHibernate cablit..
             C:在创建Hibernate.cfg.xml配置文件时,需要指定刚才创建的数据源
             D:在添加addHibernate cablit的过程中要指定所显示的数据库架构scheam,一定要从数据源中
               选择一个scheam。具体就是登录的用户名
             E:在配置Hibernate.cfg.xml时会"自动"产生一个dialect属性用来指定被访问数据库所使用sql          方言.尽管关系数据库都支持sql语言,但是它们往往还有各自的sql方言,就像不同地区的
                人既能说标准的普通话,还能讲各自的方言一样。这些方言是hibernate里面自动配置好了我
                们只需要使用就行了
                Oracle数据库的方言为:oracle 9/10g。sqlserver数据库的方言:Micrsoft sql server
       2)创建持久化类(pojo类)。只包括get..set方法的描述类,也就是实体域类
       3)创建对像-关系映射文件。
          1:Hibernate采用xml格式的文件来指定对像和关系数据之间的映射。对像-关系映射文件里面指定了            持久化类与数据表之间的关系,同时也指定了持久化类中的属性与表中字段的关系。以后在运行时            Hibernate将根据这个映射文件来生成各种sql语句
          2:每一个表必须有一个对像-关系映射文件,并且该映射文件的名字一般为:表名.hbm.xml
          3:创建持久化类与创建对像-关系映射文件都可以通过Myeclipse自动生成,并且持久化类一定
            要与其对应的映射文件在同一个文件夹下面
      4)通过MyEclipse自动产生pojo类与对像-关系映射(mapping)文件
         1)打开DB Browser-->选中要产生pojo类的表-->单右-->Hibernate reverser engineeing..
         2)在之后和向导中勾选:Hibernate mapping file(*.xml) for..与java data object(pojo)
         3)可以在DB Browser中一次性选择多个表。MyEclipse会同时生成多个表的pojo类与映射文件
         4)在向导中我们会选择表中主键的生成方式。一般选择"assigned"
      5)通过Hibernate ApI编写访问数据库的代码
     
                      

   访问Session接口的方法

    1)save:把java对像保存到数据库中
   2)update:更新数据库的java对像
       3)delete:把java对像从数据库中删除
  4)get:从数据库中根据OId加载java对像
  5)find:方法从数据库查询java对像
            

                             通过Hibernate ApI编写访问数据库
        1)通过Hibernate API访问数据库的步骤如下:
           A:创建一个Configuration对像(导入对应的包:org.hibernate.cfg.Configuration)
               Configuration  cfg=new Configuration();
           B:加载hibernate的配置文件
               cfg.configure("/hibernate.cfg.xml");或
        cfg.configure()这是一种默认加载方式。它会自动的加载hibernate.cfg.xml这个配置文件
               但是如果文件名不是"hibernate.cfg.xml"比如:"chen.cfg.xml"则只能用第一种加载方法
           C:通过Configuration对像创建一个SessionFactory(包:org.hibernate.SessionFactory)
             SessionFactory sessionFactory=cfg.buildSessionFactory();
           D:通过SessionFactory对像创建一个Session对像。(包:org.hibernate.Sessionw)
                 Session session=this.sessionFactory.openSession();
           E:通过Session的各种方法进行对数据库的操作
  public class deptDao
  {
   private static SessionFactory sessionFactory=null;
   static
   {
    Configuration  cfg=new Configuration();
    cfg.configure();
    sessionFactory=cfg.buildSessionFactory();
   }
 
   public static  Dept get(int id) //通过id获取对应的一个dept的实例
   {
    Session session=sessionFactory.openSession();
    Dept deptInstance=(Dept)session.get(Dept.class, new Long(id));
                                //一定要注意这里面不能写成
    Dept deptInstance=(Dept)session.get(Dept.class,id);
    session.close();
    return  deptInstance;
   }
 
   public  static void save(Dept deptInstance) //执行添加功能
   {  
    Session session=sessionFactory.openSession();
    Transaction tran=session.beginTransaction();
    session.save(deptInstance);  
    tran.commit();
    session.close();
   }
 
   public static  void update(Dept deptInstance) //执行修改功能
   {
    Session session=sessionFactory.openSession();
    Transaction tran=session.beginTransaction();
    session.update(deptInstance);  
    tran.commit();  
    session.close();  
   }
 
   public  static void del(Dept deptInstance) //执行删除功能,根据对像删除
   {
    Session session=sessionFactory.openSession();
    Transaction tran=session.beginTransaction();
    session.delete(deptInstance);  
    tran.commit();  
    session.close();
   }
 
 
  public static  void del(int id) //执行编号执行删除功能
   {
    Session session=sessionFactory.openSession();
    Transaction tran=session.beginTransaction();
    session.delete(get(id)); 
    tran.commit();  
    session.close();
   }
 
  public static List findByDeptLoc(String loc) //按部门位置查询
   {
  Session session=sessionFactory.openSession();
  List deptList=session.createQuery("from Dept where loc='"+loc+"'" ).list();
  session.close();
         return deptList;  
  }
        

               管理SessionFactory,Session       
       1)Session接口是Hibernate应用中使用最广泛的接口。Session也被称为持久化管理器,它提供         了和持久化相关的操作.如:添加,更新,删除,加载和查询对像
              2)Session不是线程安全的,因此应尽量避免多个线程共享同一个Session实例,也就是说每一个
                连接必须有属于自己的Session
              3)Session实例是轻量级的.所谓轻量级,是指它的创建和销毁不需要太多的资源.这意味着程序          中可以经常创建或销毁Session对像.一般都是为每一个客户请求分配一个Session实例.然后                 把Session与事务绑定在一起.开始执行事务时打开,事务执行完毕之后关闭.Session不是线程
                安全的,也就是说多个线程不能同时访问Session。
              4)那么如何能够保证为每一个客户端都会有属于自己的Session呢?我们可以通过一个java中的   一个类ThreadLocal(线程局部变量类,不是本地线程).这个类能够为每一个客户端的线程都创   建一个属于本客户端的变量.
              5)SessionFactory是重量级对像.它是线程安全的,也就是所有客户端可以共享一个                    SessionFactory,而且不能经常创建与销毁,所以可以做成为单例模式
              5)一般的格式:
   该类使用了饿汉单例模式,并把SessionFactory封装在类里面。只留一个Session接口
  public class SessionManager
  {
   //只有静态变量才能做为单例模式
   private static SessionFactory sessionFactory=null;
   private static ThreadLocal threadLocal=null;
   private static SessionManager sessionManager=null; //饿汉单例模式
   static //静态变量初始器,该初始器只会在类加载时执行一次
   {    
    Configuration cfg=new Configuration();//创建一个Configuration实例
    cfg.configure();//加载hibernate.cfg.xml文件
    sessionFactory=cfg.buildSessionFactory();
    threadLocal=new ThreadLocal();  
    sessionManager=new SessionManager();
   }
  
  public void closeSession() //关闭session
  {
   Session session=(Session)threadLocal.get();//从线程局部变量中获取session
   if (session!=null)
   {
    session.close();
   }
   threadLocal.set(null);//删除线程局变量中的session,释放资源
  }
 
  public static SessionManager newInstance() //饿汉单例模式
  {
   return sessionManager;
  }
 
  public Session getSession()
  {
   Session session=(Session)threadLocal.get();//从线程局部变量中获取session
   if (session==null)
   {
    session =sessionFactory.openSession();
    threadLocal.set(session);
   }
   return session;
  }

     }
  6)使用基于SessionManager的dao数据层做成如下的形式:
 //注意如果有方法之间相互调用的情况考虑session多次关闭的情况
 public class DeptDao
 {
  public static  Dept get(int id) //通过id获取对应的一个dept的实例
  {
   Session session=SessionManager.newInstance().getSession();
   Dept deptInstance=(Dept)session.get(Dept.class, new Long(id));
   SessionManager.newInstance().closeSession();
   return  deptInstance;
  }

  public  static void save(Dept deptInstance) //执行添加功能
  {  
   Session session=SessionManager.newInstance().getSession();
   Transaction tran=session.beginTransaction();
   session.save(deptInstance);  
   tran.commit();
   SessionManager.newInstance().closeSession();
 
  }

  public static  void update(Dept deptInstance) //执行修改功能
     {
   Session session=SessionManager.newInstance().getSession();
   Transaction tran=session.beginTransaction();
   session.update(deptInstance);  
   tran.commit();  
   SessionManager.newInstance().closeSession();  
    }

  public  static void del(Dept deptInstance) //执行删除功能,根据对像删除
  {
   Session session=SessionManager.newInstance().getSession();
   Transaction tran=session.beginTransaction();
   session.delete(deptInstance);  
   tran.commit();  
   SessionManager.newInstance().closeSession();
  }


  public static  void del(int id) //执行编号执行删除功能
  {
   Session session=SessionManager.newInstance().getSession();
   Transaction tran=session.beginTransaction();
   session.delete(get(id));
   //这里在调用本类中的get方法,会出现错误,因为
   //get方法已经关闭了session对像,导致下面的操作无法进行 
   tran.commit();  
   SessionManager.newInstance().closeSession();
  }

  public static List findByDeptLoc(String loc) //按部门位置查询
  {
  Session session=SessionManager.newInstance().getSession();
  List deptList=session.createQuery("from Dept where loc='"+loc+"'" ).list();
  SessionManager.newInstance().closeSession();
            return deptList;  
   }

      }

    Session与事务的关系
  1)hibernate规定每一个对pojo对像的持久化操作必须要与对应的事务联系到一起
  2)当要执行一个事务时,Session会打开
  3)事务执行完毕之后,为了释放对应资源,Session要关闭
  4)但是在执行事务的过程中可能会发生异常。所以要对pojo持久化操作进行事务处理
  6)事务只是对应于Pojo持久化对像的改变。pojo对像没有改变,则不用加事务.所以
    事务一般是是针对于。增,删,改。这些操作而言,对于查没由于不存在数据的修改
                  所以可以不用事务
  5)一般的格式是:
  Session session=SessionManager.newInstance().getSession();
  Transaction tran=session.beginTransaction();
  try
  {
   session.save(deptInstance);  
   tran.commit();
  }catch(Exception e)
  {
   tran.rollback();
  }
  finally
  {
   SessionManager.newInstance().closeSession();
  }

阅读(2491) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册