详解Hibernate

来源:互联网 发布:红牛快消品网络商学院 编辑:程序博客网 时间:2024/06/05 05:07

Hibernate

hibernate框架,它对JDBC进行了非常轻量级的封装,使得我们可以用对象编程的思想来操作数据库,完成数据的持久化。我主要从以下几个方面来说说hibernate的原理,构造,用途,遇到什么样的问题,我们应该怎么去解决?(主要通过代码的形式来进行详解)


如果我采用上述的代码形式操作数据库,这么做有什么缺点吗,缺点如下:
1,如果我们改动customer的属性,那么相应的CustomerDao,表结构,测试APP都要发生改动,代码改动量大,不利于程序的维护。
2,代码繁琐。
 
那么这个时候,我们来比较一下运用hibernate之后,就能避免上述的缺点
    第一步:配置hibernate.hbm.xml映射文件
     ...
    <class name="Customer" table="customers">
        <id name="id" type="integer">
            <column name="id"/>
            <generator class="increment" />
        </id>
        <property name="name" type="String">
           <column name="name"></column>
        </property>
       <property name="age" type="Integer">
           <column name="age" />
       </property>
       <property name="des" type="String">
          <column name="des" />
       </property>
    </class>
 
第二步:配置hibernate.cfg.xml
    ...
    <hibernate-configuration>
       <session-factory>
          <property name="hibernate.connection.uesrname">root</property>
          <property name="hibernate.connection.password">root</property>
          <property name="hiberante.connection.driver_class">com.mysql.jdbc.Driver</property> 
                                <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
          <!--数据库方言-->
          <property name="hibernate.dialect">org.hibernate.dilect.MySQL5Dialect</property>
          <!--如果表存在,直接插入,如果表不存,创建表之后了,在插入-->
          <property  name="hibernate.hbm2ddl.auto">update</property>
          <!-- 显示hibernate生成的sql语句-->        
          <property name="hiberante.show_sql">true</property>
          <!--显示格式化得sql语句-->
          <property name="hibernate.format_sql">false</property>
       </session-factory>
    </hiberante-configuration>
第三步:
    建立测试app类
    public class App{
       private static SessionFactory  sf= null;
       static{
          Configuration config = new Configuration();
          config.configure(".....hiberate.cfg.xml");
          sf = config.buildSessionFactory();
       }
       publoic void initData(){
            Session session = sf.openSession(); 
            Transaction tx =session.beginTransaction();
    
            Customer  c = new Customer();
            c.setName("张三");
            c.setAge("12");
  
            session.save(c);
            tx.commit();
            session.close();
       }
    }
上述代码,让我们爽了一把,怎么用hibernate,\(^o^)/~,其实这不是重要的地方,重要的是关系映射,主机生成策略就一笔带过了,映射关系
     @`````一对多的映射
     举个例子来总结一下: 客户和订单关系,一个客户可以有多个订单,多个订单可以对应一个客户,他们是一对多关系,反过来说也是多对一的关系,那么我们用hibernate应该如何表示他们的关系,以及对应数据库表呢
     public class Customer{                                public class Order{
       private Integer id;                                    private Integer id;

       private String name;                                   private String orderNumber;

     }                                                    private Double price;

      配置Customer.hbm.xml,Order.hbm.xml                       //建立从订单到客户多对一的关联

                |                                         private Customer customer;}

      

一对多,多对一关系映射,双向关联

这里主要写一些映射文件  多得一段就如上所示了,在这里我就不写出来了。

<class name="...Customer" table="customers">

    <id name="id" type="Integer">

     <column name="id"></column>

     <generator class="increment" /> 

   </id>

   <property name="name" type="String>

     <column name="name"></column>

   </property>

   <Set name="orders" type="orders">

      <key>

         <column name="coutomer_id"></column>

      </key>

      <one-to-many  class="......orders"></one-to-many>

   </Set>

</class>

第二个就是多对多关联,这里我们把其拆开成2个一对多的关联,建立有中间表。举个例子来说:学生和课程之间就是明显的多对多的关联

  

除了关系映射外,下面的内容也还是很重要的,例如:继承映射,一级缓存,二级缓存,快照等等。

下面来说一下,继承映射

举一个例子可以来说明,员工,钟点工, 正式员工。我们通过Employee.hbm.xml来体现

<class  name="...Employee" table="e_emp">

    <id name="id" type="Integer">

      <column name="id" />

      <generator class="increment" />

    </id>

    <property name="name" type="String'>

       <column name="name" />

    </property>

    <joined-subclass name="...HourEmployee" table="h_emp">

       <key column="hid">

       <property name="rate" column="rate" type="double" />

    </joined-subclass>

    <joined-subclass name="...SalaryEmployee" table="s_emp">

       <key column="sid" />

       <property name="salary" column="salary" type="double" />

   </joined-subclass>

</class>

操作持久化对象,下面如图表示了流程


说道一级缓存,简单的说,它是在session里面的,当我们操作持久化对象的时候,相应的session中,和快照中就会引用到对象,当与快照中某个属性值不一样时,就会执行更新操作,之后删除游离对象。如下图,可以很好的说明这一点。


二级缓存,也就说sessionFactory的缓存,分为:外置缓存,内置缓存,其中内置缓存是只读的,一般我们放链接数据库信息,映射文件的信息,以及预定义的sql语句,二级缓存(分为四个部分)

                  1.类级别的缓存,对象实体放在这里(时间区域 T1)

                  2.集合级别的缓存(存放的永远是查询条件,不能存放实体,实体永远存放在类级别缓存中  时间区域

                  3.查询缓存(同样存放的是查询条件  时间区域)

                  4.更新时间戳缓存(时间区域 T2)

Hibernate就先说到这里,在以后项目中更加详解的说明一下。