Hibernate作为现在流行的持久化技术应用越来越广泛。打算利用几篇文章讲述一下Hiberante的应用。
Hibernate的核心机制是ORM(对象 关系影射),即通过操作对象的方式实现对象信息的持久化。对象即我们Java编程中普遍采用的JOPO(普通的JavaBean)类的对象。而关系体现的 是数据库中的表的结构。使对象和结构之间发生对应关系,当我们操作对象的时候,可以将对象中的状态信息持久化到数据库中的对应的表中。我们也可以把这样的 Java对象叫成持久化对象。
在我们对数据库持久化的时候,当然可以采作用Java的JDBC编程的方式,面向数据库中的表和字段。例如一个简单的增加操作代码如下:
而我们采用对象持久化的方式可以使我们按照面向对象的编程方式持久化对象,前提当然是对象能和数据库中的表发生联系,进而使用Hibernate所提供的API执行真正的持久化。Hibernate API封装了底层的JDBC操作(例如连接、指令发送、结果集获取)。
开发简单的Hibernate程序并不难,遵循一定的步骤,了解其中的核心概念就可以完成。在此使用一个简单的实例进行讲解。
首先建立普通的java project。在工程中生成路径中( build path)加入hibernate类库文件,在此我们使用hibernate3。下面就可以开始进行例子的开发了。
比如我们要对SQL Server2000数据库SampleDB中的UserInfo表进行记录增加操作,如何去做?
首先我们需要知道UserInfo表的结构 (Schema),这样在建立对象的时候可以按照此结构进行建立。假设表中包含3个字段分别为userid(identity类 型),username(varchar类型),userpass(varchar类型),那么我们建立的持久化对象类一般讲至少存三个数据成员。这样对 象种的数据成员才能和表中的字段产生具体的对应关系。类的建立如下:
将数据成员名称和字段名称定义的相同有助于日后的开发(当然,前提是数据库中的字段名应为小写开头)
日后的操作,就是对UserInfo类的对象 的操作。当你操作此对象的时候,Hibernate是如何知道到底去操作哪张表呢?那个数据成员对应着那些字段呢?现在当然不知道,它没有那么智能。所以 现在就要体现ORM的机制,通过建立XML格式的映射文件进行说明。这种文件就相当于一个说明书,在对象和数据库结构之间起到对应的作用。映射文件 以.hbm.xml为后缀,名称自己定义,但一般要定义的有意义。在此文件定义为UserInfo.hbm.xml。此文件可以通过IDE自动产生,但是 初学的时候建议能自己手写,这样可以熟悉文件中的元素的具体含义。UserInfo.hbm.xml定义如下:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Mapping file autogenerated by MyEclipse Persistence Tools --> <hibernate-mapping> <class name="com.frank.obj.UserInfo" table="UserInfo" schema="dbo" catalog="MyDB"> <id name="userid" type="java.lang.Integer"> <column name="userid" /> <generator class="identity" /> </id> <property name="username" type="java.lang.String"> <column name="username" length="20" /> </property> <property name="userpass" type="java.lang.String"> <column name="userpass" length="20" /> </property> </class> </hibernate-mapping>
映射文件的根元素 为<hibernate-mapping>,<class>元素代表一个对象关系映射。可以在一个hbm.xml文件中同时包含 多个<class>,但是建议将不同的映射描述放到不同的文件中。<class>中的name属性指名映射的类名,table属 性指名对应的表名称,schema属性指名对应的数据库。这样通过属性指名了对象和表的对应。下面就应该描述对象的数据成员到表的字段的对应关系。
在 Hibernate中必须要描述主键(如果表没有主键,需要建立主键类)。通过id元素进行配置。name属性指名主键名,子元素column指名所对应 的表列,子元素generator指名主键列的生成方式(在此为identity,SQL Server的自动增长)。
<property>元素描述对象的基本数据成员和表中基本列的对应关系,name属性指名类数据成员名,column子元素知名对应的列。如果数据成员名称和表列名称相同,可以省略column子元素的描述,例如
<property name=”username” type=”java.lang.String”/>
通过配置文件我们可知需要com.frank.obj.UserInfo类和表UserInfo产生对应关系。所以需要建立持久化类UserInfo,如下:
package com.frank.obj; /** * UserInfo entity. * @author MyEclipse Persistence Tools */ public class UserInfo implements java.io.Serializable { // Fields private Integer userid; private String username; private String userpass; // Constructors /** default constructor */ public UserInfo() { } /** full constructor */ public UserInfo(String username, String userpass) { this.username = username; this.userpass = userpass; } // Property accessors public Integer getUserid() { return this.userid; } public void setUserid(Integer userid) { this.userid = userid; } public String getUsername() { return this.username; } public void setUsername(String username) { this.username = username; } public String getUserpass() { return this.userpass; } public void setUserpass(String userpass) { this.userpass = userpass; } }
UserInfo类数据成员对应表中的各列。所以数据成员应该具有set和get访问方法。Hibernate利用set和get方法对数据成员进行读写访问。
Hibernate通过使用hibernate.cfg.xml配置文件配置数据库连接信息。并将映射文件加入配置文件,以便hibernate访问。
hibernate.cfg.xml文件内容如下:
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <!-- Generated by MyEclipse Hibernate Tools. --> <hibernate-configuration> <session-factory> <property name="show_sql">true</property> <property name="connection.username">sa</property> <property name="connection.url"> jdbc:jtds:sqlserver://localhost:1433/MyDB </property> <property name="dialect"> org.hibernate.dialect.SQLServerDialect </property> <property name="connection.driver_class"> net.sourceforge.jtds.jdbc.Driver </property> <mapping resource="com/frank/obj/UserInfo.hbm.xml" /> </session-factory> </hibernate-configuration>
Session-factory标记配置数据库连接信息,并通过<mapping>元素设定映射文件的位置。在此映射文件UserInfo.hbm.xml同样放到com.frank.obj包中
子元素<property>负责描述具体的属性设置,name指名描述的属性名称,主体内容为属性的值。
下面编写测试程序测试增加操作(采用控制台程序控制)
package com.frank.test; import org.hibernate.*; import org.hibernate.cfg.*; import com.frank.obj.UserInfo; public class Test { /** * @param args */ public static void main(String[] args) { try{ SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory(); Session session=sessionFactory.openSession(); UserInfo user=new UserInfo("tom","123456"); Transaction tx=session.beginTransaction(); session.save(user); tx.commit(); session.close(); sessionFactory.close(); }catch(HibernateException ex){ ex.printStackTrace(); } } }
附加讲解:
SessionFactory表示会话工厂,负责产生会话(Session)。会话工厂通过配置文件产生,默认情况下使 用配置文件hibernate.cfg.xml的配置信息产生会话工厂。如果采用的是其它名称的.cfg.xml配置文件,则需要在创建会话工厂的时候指 名:
SessionFactory ses=new Configuration().configure("other.cfg.xml").buildSessionFactory();
Session接口实现真正的持久化操作。负责增加、删除、修改和检索对象等操作。Session有会话工厂产生。 Session同时负责维护一个缓冲,放置当前操作所加载的对象,而且只能由当前的操作单元访问。在此例子中,通过调用session.save方法保存 所创建的对象user,实现对象的持久化。
Transaction接口负责对Session的操作实现事务管理。因为在此实例中,实现的是增加操作,需要对当前的session实现事务管理。通过调用commit方法实现提交。将对象真正持久化到所对应的数据库中。