当前位置:首页 > 行业动态 > 正文

Hibernate使用hbm.xml配置映射关系

Hibernate通过hbm.xml文件配置实体与数据库表

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 | 字段类型(如intlongstring),需与数据库类型匹配 |
| generator | 主键生成策略(如nativeuuidassigned) |
| unsaved-value | 判断未保存对象的策略(如nullundefined) |

示例

<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 | 字段类型(如stringdate),需与数据库类型匹配 |
| 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属性名自动转换为下划线格式(如userNameuser_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-onlyread-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>
H
0