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就先说到这里,在以后项目中更加详解的说明一下。