Hibernate的出现是为了解决面向对象编程与关系数据库之间的连接问题。Hibernate不仅管理java类到数据库表的映射关系,还提供数据库查询和获取数据的方法。它是一种ORM(Object/Relation Mapping),是先进的面向对象编程语言与底层的落后的关系数据库发展不协调的产物。ORM能够将数据库表中的一行信息映射成一个持久化类实例,而每一行的每一条数据就是实例的一个属性。有了ORM,应用程序只需要操作持久化对象即可,ORM会自动将这种操作转化恒底层数据库操作。


为project配置数据库

下载最新的Hibernate包,将lib下的required下的所有jar包、optional中的c3p0下的三个jar包添加到自定义的user library。然后使用MyEclipse为项目增加Hibernate Capacities。


简单操作搭建

我们只需要编写三个文件即可搭建一个简单的Hibernate环境。首先是hibernate.cfg.xml文件,该文件配置了数据库链接,持久化类映射等信息。

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
	<property name="connection.url">jdbc:mysql://localhost/cmdb</property>
	<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
	<property name="connection.username">root</property>
	<property name="connection.password">cm123</property>
		
	<property name="c3p0.acquire_increment">2</property>
	<property name="c3p0.idle_test_period">3000</property>
	<property name="c3p0.max_size">20</property>
	<property name="c3p0.max_statements">100</property>
	<property name="c3p0.min_size">1</property>
	<property name="c3p0.timeout">5000</property>
		
	<property name="hbm2ddl.auto">update</property>
	<property name="show_sql">true</property>
	<property name="format_sql">true</property>
		
	<mapping class="com.cm.table.Students" />

	</session-factory>

</hibernate-configuration>

配置文件中的property属性分为几个部分。首先是配置数据库链接的部分,包括大家熟知的url,driver,pass和user。注意在填写url的时候,最后我写的cmdb要换成你们自己的数据库名字。

然后是c3p0部分,此部分配置了使用c3p0数据源的有关信息。所谓数据源,就是一种以数据池为容器,动态地分配数据库链接的提高数据库连接性能的技术。它会在一开始创建出若干链接,放在连接池中。当某一程序需要连接,直接在池中获取,使用结束,无需关闭链接,而是返还给连接池。这种方式能够避免重复地获取数据库连接关闭而导致的性能下降。

下面我们来看持久化类文件。

@Entity
@Table(name="students")
public class Students {
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	
	private String name;
	private String sex;
	private int age;
	private String tel;

}

注意此处我省略了各个属性的set、get方法。持久化类实际上就是普通的java bean+注解。注解来与javax.persistence这个包。Entity表明这是一个持久化类,Table告诉架构这个类将映射到哪一个表格。Id用于指定该类的标识属性。GeneratedValue是主键生成策略。

下面我们来看测试类。

public class test {
    public static void main(String[] args){
	Configuration conf=new Configuration();
	conf.configure();
	ServiceRegistry sr= new ServiceRegistryBuilder().applySettings(conf.getProperties()).buildServiceRegistry();
		
	SessionFactory sf=conf.buildSessionFactory(sr);
	Session sess=sf.openSession();
	Transaction tx=sess.beginTransaction();
	Students s=new Students();
	s.setAge(10);
	s.setName("abcc");
	s.setSex("nan");
	s.setTel("202818");
	sess.save(s);
	tx.commit();
	sess.close();
	sf.close();
	}
}

这里的写法比较固定,首先是要获取Configuration以便加载xml文件。然后通过conf实例得到SessionFactory。打开session,打开事务。持久化操作后,保存持久化实例,按顺序关闭事务,session和SessionFactory。通过上述简单例子,我们可以发现,数据库中多了一行数据,但是我们并没有写sql语句,而这也就是Hibernate的最大作用,将我们程序员从蛋疼的sql语句中解放出来了!取而代之的是具有Context Assist的面向对象操作!


Hibernate的体系结构

Session是Hibernate中的重要对象,只有处在Session管理下的POJO才有持久化操作的能力(也就是有有能力将面向对象操作转为底层数据库sql持久化操作)。

Hibernate组件需要一个properties文件来指定数据库连接信息,需要持久化注解来修饰Persistent Objects,而Persistent Objects则是链接顶层Application与Hibernate的桥梁。PO需要Session的管理,Session由工厂产生,工厂则由configuration实例建造。Session能够开始事务,而事务则是一个原子操作,正是一系列事务,组成了持久化操作的转换。所以,从面向对象的操作一直向上,分别是transaction,session,sessionfactory,configuration。

Hibernate的持久化操作离不开SessionFactory对象,它是整个数据库映射关系经过编译后的内存镜像,该对象的openSession方法可以×××Session对象,进而开始事务。

Configuration代表了程序到SQL数据库的配置信息,它的buildSessionFactory方法能够产生一个不可变的SessionFactory(说白了就是解读了xml中的mapping部分,然后记住了哪个持久化类是哪个table)。


深入理解Hibernate的配置文件

Hibernate的持久化操作离不开SessionFactory对象,这个对象是整个数据库映射关系在内存中的镜像,该对象的openSession方法可以打开Session对象。SessionFactory对象由Configuration产生。每个Hibernate配置文件对应一个Configuration对象。我们常用的配置方式是xml文件。


JDBC连接属性

这是连接数据库的相关属性。如下四个属性是最基本的,包括驱动类,连接url,用户名密码。

<property name="connection.url">jdbc:mysql://localhost/cmdb</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">cm123</property>

此外我们还推荐使用c3p0连接池,设置连接池需要如下property:

<property name="c3p0.acquire_increment">2</property>
<property name="c3p0.idle_test_period">3000</property>
<property name="c3p0.max_size">20</property>
<property name="c3p0.max_statements">100</property>
<property name="c3p0.min_size">1</property>
<property name="c3p0.timeout">5000</property>


数据库方言

Hibernate底层仍然使用SQL语句来执行操作,因此Hibernate需要知道将面向对象操作转化为哪种SQL语句。虽然设置方言并不是必须的,但是对于优化持久层访问很有必要。

<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>


Hibernate事务属性

事务也是Hibernate持久层访问的重要方面,不仅提供了局部事务支持,也允许使用容器管理的全局事务。

外连接抓取属性

外连接抓取能够限制执行SQL语句的次数来提高效率,通过在单个select语句中使用outer join来一次抓取多个数据表的数据。将hibernate.max_fetch_depth设置为0可以禁止外连接抓取,设置为1或者更大能够急用N—1或者1—1的外连接抓取。除此之外还应该在持久化注解中通过fetch=FetchTyep.EAGER来指定这种外连接抓取。


其他常用的配置属性

hibernate.show_sql:是否在控制台输出持久化操作底层的SQL语句,true,false。

hibernate.format_sql:是否将SQL转为格式良好的SQL,true,false。

hibernate.use_sql_comments:是否在Hibernat生成的SQL语句中添加有助于调试的注解,true,false。

hibernate.jdbc.fetch_size:指定JDBC抓取数量的大小,实质是调用Statement.setFetchSize方法。

hibernate.jdbc.batch_size:指定Hibernate使用JDBC2的批量更新的大小,建议5-30整数。

hibernate.connection.autocommit:是否自动提交,不建议。

hibernate.hbm2ddl.auto:设置当创建SessionFactory时是否根据持久化类的映射关系自动建立数据库表。属性为validate、update、create和create-drop。通常设置为update,有表就插入或者更新,没有就新建。