您的位置:首页 > 其它

Hibernate配置文件详解

2011-08-26 18:23 246 查看
Hibernate的基本配置文件有两种:hibernate.cfg.xml和.hbm.xml文件。前者包含了Hibernate与数据库的基本连接信息,在Hibernate工作的初始阶段,这些信息被先后加载到Configuration和SessionFactory实例;后者包含了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>

二、.hbm.xml文件:

由于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自带工具Middlegen生成的Province.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节点定义了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>

多对多的双向关联关系(中间表)

在多对多的关联关系中,可拆分为两个一对多的关联关系,即在两个表中间增加一个关联表,记录这两个表之间的关联关系。若抛开关联表,则原2个表之间看不出任何的关系。

以为考试类别和考试科目为例,详细讲解在添加关联表的情况下两个表之间的hibernate设置。

考试类别表: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;

}

}

关于映射文件:

映射文件要设置set,

name=subject为ExamSortEnum.java文件中定义的Set对象,存储多个Subject类型的容器。

table="EXAM_SORT_ENUM_SUBJECT"为对应的中间表的表名,由于两个业务表之间不能直接打交道,只能通过中间表来进行关联。

lazy="true"延迟加载

cascade="save-update"级联保存更新,若设置为all,delete,all-delete-orphans,则在删除一个ExamSortEnum对象时,关联的Subject对象也被删除,而此关联的subject对象可能被其他的为ExamSortEnum对象所引用。

<key column="exam_sort_enum_id"/>指定中间表中参照为Exam_Sort_Enum表的外键为exam_sort_enum_id

<many-to-many>

column="subject_id" Exam_Sort_Enum表参照Subject表的外键为subject_id,即Exam_Sort_Enum表通过subject_id与Subject表关联

class="model.Subject"指定set中name=subject中存放的是model.Subject对象。

Subject.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.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;

}

}

关于映射文件:

内容与ExamSortEnum.hbm.xml差不多,只是多了一个inverse="true",告诉hibernate控制权不在此处,两个映射文件只能设置一个。

测试类:

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();

}

}

执行后的结果:

考试类别表:exam_sort_enum

id name

3 A

4 B

考试科目表:subject

id name

3 C1

4 A1

5 B1

考试类别科目关联表

exam_sort_enum_id subject_id

3 3

3 4

4 3

4 5
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: