Hibernate使用hbm.xml配置映射关系
- 行业动态
- 2025-05-11
- 8
Hibernate使用hbm.xml配置映射关系详解
Hibernate作为Java领域最流行的ORM框架,支持多种方式定义对象与数据库表的映射关系。.hbm.xml
(Hibernate Mapping File)是一种基于XML的映射配置文件,适用于不依赖注解或需要集中管理映射的场景,本文将系统讲解.hbm.xml
的核心配置规则,并通过示例和表格帮助理解。
.hbm.xml
文件基础结构
每个实体类对应一个.hbm.xml
文件,文件需遵循以下结构:
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-配置内容 --> </hibernate-mapping>
核心元素说明:
| 元素名称 | 作用 |
|——————|———————————————————————-|
| <class>
| 定义一个实体类的映射 |
| <id>
| 配置主键字段 |
| <property>
| 配置普通属性与表字段的映射 |
| <many-to-one>
| 配置多对一关联关系 |
| <one-to-many>
| 配置一对多关联关系 |
| <many-to-many>
| 配置多对多关联关系 |
| <joined-subclass>
| 配置继承关系的子类(需独立表) |
主键映射配置(<id>
)
主键是必须配置的字段,常见属性如下:
| 属性名 | 说明 |
|——————|———————————————————————-|
| name
| Java实体类中的属性名(如userId
) |
| column
| 数据库表字段名(如user_id
),默认与属性名一致 |
| type
| 字段类型(如int
、long
、string
),需与数据库类型匹配 |
| generator
| 主键生成策略(如native
、uuid
、assigned
) |
| unsaved-value
| 判断未保存对象的策略(如null
、undefined
) |
示例:
<id name="userId" column="user_id" type="int" generator="native"> <generator-param name="sequence" value="user_seq"/> </id>
generator="native"
:自动选择数据库原生主键生成策略(如自增字段)。generator-param
:用于指定序列名(Oracle/PostgreSQL)或参数。
普通属性映射(<property>
)
用于映射非主键字段,关键属性包括:
| 属性名 | 说明 |
|——————|———————————————————————-|
| name
| Java属性名(如username
) |
| column
| 数据库字段名(如user_name
),默认与属性名一致 |
| type
| 字段类型(如string
、date
),需与数据库类型匹配 |
| length
| 字符串/文本长度限制(如length="50"
) |
| not-null
| 是否非空约束(默认true
) |
| update
/insert
| 是否参与更新/插入操作(如update="false"
) |
Java类型与数据库类型对照表:
| Java类型 | 数据库类型(MySQL为例) | Hibernate类型 |
|——————|—————————–|———————|
| String
| VARCHAR(255)
| string
|
| int
| INT
| int
|
| long
| BIGINT
| long
|
| Date
| DATETIME
| timestamp
/date
|
| boolean
| TINYINT(1)
| boolean
|
| float
| FLOAT
| float
|
关联关系映射
多对一(<many-to-one>
)
示例:用户与角色的多对一关系(一个用户对应一个角色)
<many-to-one name="role" class="com.example.Role" column="role_id" not-null="true"/>
name
:实体类中的属性(如role
)。class
:关联目标类的全限定名。column
:外键字段名(如role_id
)。not-null
:是否强制非空。
一对一(<one-to-one>
)
示例:用户与用户详情的一对一关系
<one-to-one name="userDetail" class="com.example.UserDetail" cascade="all"/>
cascade
:级联操作(如all
表示所有操作级联)。constrained
:是否添加外键约束(默认true
)。
一对多(<set>
/<bag>
/<list>
)
示例:角色与用户的一对多关系(一个角色对应多个用户)
<set name="users" inverse="true" cascade="delete-orphan"> <key column="role_id"/> <one-to-many class="com.example.User"/> </set>
inverse
:控制维护关联关系的端(通常设置为true
由对方维护)。cascade
:级联删除孤儿数据。<key>
:指定外键字段。
多对多(<many-to-many>
)
示例:学生与课程的多对多关系
<many-to-many class="com.example.Course" column="course_id"> <key column="student_id"/> </many-to-many>
- 中间表需手动创建(如
student_course
),包含双方主键字段。
继承关系映射
单表继承(<union-subclass>
)
所有子类共享同一张表,通过type
字段区分类型。
<union-subclass name="Student" extends="Person" discriminator-value="STUDENT"> <property name="school" column="school"/> </union-subclass>
discriminator-value
:用于区分子类的标识值。
多表继承(<joined-subclass>
)
每个子类使用独立表,通过外键关联父表。
<joined-subclass name="Employee" extends="Person" table="employee"> <key column="person_id"/> <property name="salary" column="salary"/> </joined-subclass>
table
:子类对应的数据库表名。key
:外键字段。
其他高级配置
命名策略(<regarding>
)
通过<regarding>
标签自定义字段命名规则,
<regarding name="propertyName" as="column_name"/>
可将Java属性名自动转换为下划线格式(如userName
→user_name
)。
动态SQL配置
通过<sql-insert>
、<sql-update>
等标签自定义SQL语句:
<sql-insert> INSERT INTO user (user_id, name) VALUES (?, ?) </sql-insert>
适用于复杂业务逻辑或存储过程调用。
缓存配置
在<class>
中配置二级缓存:
<class-cache usage="read-write" region="com.example.UserCache"/>
usage
:缓存策略(如read-only
、read-write
)。region
:自定义缓存区域名称。
FAQs
Q1:.hbm.xml
与注解映射的区别是什么?
A1:两者功能等效,但适用场景不同:
.hbm.xml
:适合集中管理映射关系,便于团队协作和维护,尤其适合 legacy 项目。- 注解:更贴近代码,开发效率高,但映射逻辑分散在实体类中。
建议优先使用注解,复杂场景可混合使用(如@Entity
配合XML配置关联关系)。
Q2:如何处理多对多关系的中间表字段?
A2:需手动创建中间表并定义额外字段,学生与课程的多对多关系中,若中间表student_course
包含create_time
字段,可通过<many-to-many>
的<property>
标签映射:
<many-to-many class="Course" column="course_id"> <property name="createTime" column="create_time" type="timestamp"/> </many-to-many>