Hibernate的基本配置文件有两种:hibernate.cfg.xml和model.hbm.xml文件。
hibernate.cfg.xml包含了Hibernate与数据库的基本连接信息,在Hibernate工作的初始阶段,这些信息被先后加载到Configuration和SessionFactory实例;
model.hbm.xml包含了Hibernate的基本映射信息,即系统中每一个类与其对应的数据库表之间的关联信息,在Hibernate工作的初始阶段,这些信息通过hibernate.cfg.xml的mapping节点被加载到Configuration和SessionFactory实例。
这两种文件信息包含了Hibernate的所有运行期参数。下面我们用详细的例子来说明这两种文件的基本结构和内容。
一、hibernate.cfg.xml文件:
<!--该文件的开头信息,对Hibernate而言,该类文件基本都这么开头:)--> <?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"> <!-- 正文开始 --> <hibernate-configuration> <!--下面是数据库的基本连接信息,对一个应用来说,设置一个session-factory节点就够了,除非我们中间使用了多个数据库--> <session-factory> <!--用户名 --> <property name="connection.username">root</property> <!--url信息 --> <property name="connection.url">jdbc:mysql://localhost:3306/webases</property> <!--数据库方言信息--> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!--密码 --> <property name="connection.password">274507</property> <!--数据库驱动信息 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!--指定Hibernate映射文件路径 --> <mapping resource="com/Hibernate/test_products.hbm.xml" /> </session-factory> </hibernate-configuration>
由于Hibernate的关联关系包含了一对一、一对多、多对一和多对多等四种类型,因此,也就有分别与之对应的四种.hbm.xml文件。
下面我们就以比较常用的双向“一对多”型关联关系为例,介绍一下.hbm.xml文件的基本结构和内容。
有关Hibernate更详细的内容,请参考相关文资料。
该例中有两张数据库表:一张为“省”表,另一张为“市”表,所用的数据库为MySQL。二者的建表语句如下:
CREATE TABLE IF NOT EXISTS Province( Guid INT NOT NULL AUTO_INCREMENT, Provincename VARCHAR(16) NOT NULL, PRIMARY KEY (Guid) ) TYPE=InnoDB; CREATE TABLE IF NOT EXISTS City( Guid INT NOT NULL AUTO_INCREMENT, Cityname VARCHAR(32) NOT NULL, ProvinceID INT NOT NULL, PRIMARY KEY (Guid) ) TYPE=InnoDB; ALTER TABLE City ADD CONSTRAINT CityRFProvince FOREIGN KEY (ProvinceID) REFERENCES Province (Guid) ON DELETE CASCADE ON UPDATE RESTRICT;Province表为主控方,City表为被控方,两者之间存在双向的一对多的关系。表City通过外键ProvinceID与表Province进行关联:当表Province中有记录被删除时,表City中相关记录亦被删除;当表Province中有记录被保存或者更新时,表City中相关记录无任何变化。
<!--该文件的开头信息,对Hibernate而言,该类文件基本都这么开头:)--> <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <!-- 映射文件开始 --> <hibernate-mapping> <!-- 下面的class节点定义了Province类和对应数据库表之间的关联关系 --> <class name="com.xxx.hibernate.Province" table="Province"> <!-- 下面的两个节点定义了Province类中的属性和该类对应数据库表中的字段之间的关联关系,其中Guid为对应数据库表的主键 --> <id name="guid"type="int"column="Guid"> <generator class="native" /> </id> <property name="provincename" type="java.lang.String" column="Provincename" not-null="true" length="16" > </property> <!-- 下面的set节点定义了Province类和City类之间的”一对多“型关联关系 --> <set name="cities"<!-- 集合属性的名称 --> lazy="true"<!-- 是否允许延迟加载 --> inverse="true"<!-- 定义这个集合是否为双向关联关系中的方向一端 --> cascade="delete"<!-- 定义有关操作是否关联到子实体(此处指City类对象) --> > <key> <column name="ProvinceID" /><!-- 定义集合所对应的数据库表的外键 --> </key> <one-to-many class="com.xxx.hibernate.City"<!-- 定义集合所属的类--> /> </set> </class> </hibernate-mapping>
将Hibernate自带工具Middlegen生成的City.hbm.xml文件进行修改,内容如下: <!--该文件的开头信息,对Hibernate而言,该类文件基本都这么开头:)--> <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <!-- 映射文件开始 --> <hibernate-mapping> <!-- 下面的class节点定义了City类和对应数据库表之间的关联关系 --> <class name="com.xxx.hibernate.City" table="City"> <!-- 下面的两个节点定义了City类中的属性和该类对应数据库表中的字段之间的关联关系,其中Guid为对应数据库表的主键--> <id name="guid" type="int" column="Guid" > <generator class="native" /> </id> <property name="cityname" type="java.lang.String" column="Cityname" not-null="true" length="32"> </property> <!-- 下面的many-to-one节点定义了Province类和City类之间的”一对多“型关联关系 --> <many-to-one name="province"<!-- 属性名称 --> class="com.xxx.hibernate.Province"<!-- 属性所属的类 --> cascade="none"<!-- 指定哪些操作会从父对象(此处指City类对象)级联到子对象(此处指Province类对象) --> outer-join="auto"<!-- 设置父子对象之间是否存在外连接 --> not-null="true"<!-- 指定该属性是否一定为非空 --> > <column name="ProvinceID" /><!-- 定义父对象(此处指City类对象)所对应的数据库表的外键 --> </many-to-one> </class> </hibernate-mapping>
考试类别表:exam_sort_enum
id:integer
name:string
考试科目表:subject
id:integer
name:string
考试类别科目关联表
exam_sort_enum_id:integer 对应考试类别表的id
subject_id:integer 对应考试科目表的id
ExamSortEnum.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="model.ExamSortEnum" table="EXAM_SORT_ENUM" lazy="false" > <id name="id" type="integer" column="ID" length="22" > <generator class="increment" /> </id> <property name="name" type="string" column="NAME" length="255" /> <set name="subject" table="EXAM_SORT_ENUM_SUBJECT" lazy="true" cascade="save-update"> <key column="exam_sort_enum_id"/> <many-to-many column="subject_id" class="model.Subject"/> </set> </class> </hibernate-mapping>ExamSortEnum.java
package model; import java.io.Serializable; import java.util.HashSet; import java.util.Set; public class ExamSortEnum implements Serializable{ private static final long serialVersionUID = 1L; private Integer id; private String name; private Set subject = new HashSet(); public ExamSortEnum(){} public ExamSortEnum(Integer id){ setId(id); } public void setSubject(Set subject){ this.subject = subject; } public Set getSubject(){ return this.subject; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }关于映射文件:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="model.Subject" table="SUBJECT" lazy="false" > <id name="id" type="integer" column="ID" length="22" > <generator class="increment" /> </id> <property name="name" type="string" column="NAME" length="200" /> <set name="examSortEnum" table="EXAM_SORT_ENUM_SUBJECT" lazy="true" inverse="true" cascade="save-update"> <key column="subject_id"/> <many-to-many column="exam_sort_enum_id" class="model.ExamSortEnum"/> </set> </class> </hibernate-mapping>Subject.java
package model; import java.io.Serializable; import java.util.HashSet; import java.util.Set; public class Subject implements Serializable{ private static final long serialVersionUID = 1L; private Integer id; private String name; private Set examSortEnum = new HashSet(); public Subject(){} public Subject(Integer id){ setId(id); } public void setExamSortEnum(Set examSortEnum){ this.examSortEnum = examSortEnum; } public Set getExamSortEnum(){ return this.examSortEnum; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }关于映射文件:
测试类:
package model; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; public class ExamSortEnumTest { public static SessionFactory sf ; static{ try{ Configuration cfg = new Configuration().configure(); sf = cfg.buildSessionFactory(); }catch(Exception e){ e.printStackTrace(); } } public void insert1(){ Session sess = sf.openSession(); Transaction tx = sess.beginTransaction(); Subject sa = new Subject(); sa.setName("A1"); Subject sb = new Subject(); sb.setName("B1"); Subject sc = new Subject(); sc.setName("C1"); ExamSortEnum esea = new ExamSortEnum(); esea.setName("A"); esea.getSubject().add(sa); esea.getSubject().add(sc); ExamSortEnum eseb = new ExamSortEnum(); eseb.setName("B"); eseb.getSubject().add(sb); eseb.getSubject().add(sc); sess.save(esea); sess.save(eseb); tx.commit(); sess.close(); } public static void main(String[] args){ ExamSortEnumTest et = new ExamSortEnumTest(); et.insert1(); } }执行后的结果: