Hibernate概述、对象标识符映射、关系映射

Hibernate是一个自动ORM框架,位于Java应用程序的持久层,它提供了对象关系映射,使得开发者可以用面向对象的方式来操作数据库。通过Hibernate,程序员可以避免直接使用SQL,简化了数据库操作,同时增强了代码的重用性和提高了开发效率。配置文件包括hibernate.cfg.xml,其中包含<session-factory>和<class>等元素。持久化类需要遵循一定的规范,如提供getter和setter方法,以及用于唯一标识的oid属性。对象标识符映射配置通过<id>元素指定,如increment、identity等生成策略。关系映射中,一对一、一对多、多对多等关系可以通过Hibernate的映射文件实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hibernate概述

ORM

  • 全称:
    • Object Relational Mapping (对象 关系 映射)
  • 概念说明:
    • 对象是指面向对象思想中的对象,在java编程语言中就是指java对象
    • 关系是指数据关系模型,即关系数据库中的数据库结构
    • 映射是指实现实体对象和数据关系模型之间的相互转换
  • ORM技术:
    • ORM 技术在实体类对象和数据库表之间提供了一条桥梁,不需要和SQL语句打交道就可以通过操作实体对象来间接操作数据库。
  • 面向对象概念和面向关系概念的对应关系
    面向对象概念面向关系概念
    属性字段
    对象记录

Hibernate

  • Hibernate属于什么?

    • 在分层体系结构中Hibernate位于持久层,是完成对象持久化的持久层框架
    • Hibernate是连接Java应用程序和关系型数据库的框架,是一种自动ORM框架
    • JDBC的轻量级封装框架。
  • Hibernate做了什么?

    • 能够建立对象模型和关系数据模型之间的映射
    • 自动完成对象的持久化
    • 封装了JDBC的API
  • Hibernate给我们带来了什么?(优点)?

    • Hibernate实现了ORM,使Java程序员可以方便的运用面向对象的编程思想来操纵关系型数据库;
    • Hibernate是对JDBC的封装,增强了代码的重用性,简化了代码,提高了编程效率;
    • Hibernate是对JDBC的轻量级封装,必要时Java程序员可以绕过Hibernate直接访问JDBC API;
    • Hibernate不仅可以应用在独立的Java程序中,还可以应用在Java Web项目中,可以和多种Web服务器集成,并支持多种数据库平台。
  • 编写一个简单Hibernate程序的流程

  1. 安装Eclipse、mysql;
  2. 下载Hibernate,并解压缩(去下载Hibernate);
  3. 使用Eclipse创建新的项目;
  4. 引入Mysql数据库驱动包;
  5. 导入Hibernate所需的jar包(Hibernate目录下的lib / required);
  6. 编写Hibernate核心配置文件(后面作详细说明);
  7. 创建Java持久化类XXX.java(类似javaBean);
  8. 编写持久化类的映射配置文件XXX.hbm.xml;
  9. 使用Hibernate API 完成对象的持久化(即向数据库同步数据)。
  • Hibernate核心配置文件

◎ 核心配置文件在默认情况下放置在src目录下

◎ Hibernate的核心配置文件有两种形式:

  1. hibernate.properties (键=值方式)
  2. hibernate.cfg.xml

◎ 这里只对较复杂的hibernate.cfg.xml进行简单了解

  • hibernate.cfg.xml
   xml声明 标签:
<?xml version="1.0" encoding="UTF-8"?>
   xml文档类型定义 标签:
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

~ 备注:该标签可以在 hibernate-configuration-3.0.dtd文件中找到,该文件可在以下两个目录中找到:
1. hibernate解压包:hibernate-release-5.2.17.Final\project\hibernate-core\src\main\resources\org\hibernate\hibernate-configuration-3.0.dtd
2. hibernate的一个jar包:hibernate-core-5.2.10.Final.jar/org/hibernate/hibernate-configuration-3.0.dtd

   <> 根元素 标签
<hibernate-configuration></hibernate-configuration>
   <> 根元素下<session-factory>的常用配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<!-- 必要配置: -->
		<property name="hibernate.connection.driver_class">
			com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">
			jdbc:mysql://localhost:3306/MyDB</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">123456</property>
		<!-- 可选配置: -->
		<property name="hibernate.dialect">
			org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.show_sql">true</property>
		<property name="hibernate.format_sql">true</property>
		<!-- 映射文件的配置: -->
		<mapping resource="entity/Student.hbm.xml"/>
	</session-factory>
</hibernate-configuration>
  • 创建持久化类

    • 持久化对象的规范
    1. 类是共有的(public)
    2. 属性是私有的(private)
    3. 提供getter与setter(getXxx或isXxx和setXxx方法)
    4. 必须提供公有的无参构造方法
    5. 类不能被finnal修饰
    6. 有一个属性(id)用于唯一标识每一个对象
    7. 如果属性是基本数据类型,最好使用包装类
    • 创建持久化类的映射配置文件(…hbm.xml)
   xml文档类型定义 标签:
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

~ 备注:该标签可以在 hibernate-configuration-3.0.dtd文件中找到,该文件可在以下两个目录中找到:
1. hibernate解压包:hibernate-release-5.2.17.Final\project\hibernate-core\src\main\resources\org\hibernate\hibernate-mapping-3.0.dtd
2. hibernate的一个jar包:hibernate-core-5.2.10.Final.jar/org/hibernate/hibernate-mapping-3.0.dtd

   <> 根元素 标签
<hibernate-mapping package="xxx">
</hibernate-mapping>
   <> 根元素下<class>的常用的基本配置
<?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 package="com.hibernate.entity">
    <class name="Student" table="STUDENT">
        <id name="id" type="int" >
            ...
        </id>
        <property name="name" type="java.lang.String">
            ...
        </property>
        ...
    </class>
</hibernate-mapping>
   <class> 元素简述

<class>元素用于指定类和表之间的映射。

  • 常用属性:

    • name:设定类名(默认路径是同级目录,如果在其它位置需要指明包名路径);
    • table:设定表名,不写则默认用类名当做表名。
  • 常用的子元素:

    • <id>,在<class>中只能有一个
      • 常用属性:
        • name:设定唯一标识(OID)在类中的属性名
        • type:设定类型
      • 常用的子元素:
        • <column name=“xxx” />:指定表中主键字段的名称;
        • <generator class=“native” />:元素指定OID(对象标识符)的生成器。
    • <property>,在<class>中可以有多个
      • 常用属性:
        • name:对应类中的属性名称;
        • type:指定属性的类型;
        • not-null:指定属性/字段是否允许为空。
      • 常用的子元素:
        • <column name=“xxx” />:指定该属性存储在表中的字段名称;
  • 对象标识符映射

    • 说明:在关系数据库存在主键的概念,主键用来唯一标识表中的每个记录,而在java中是使用地址来标识每个对象的;为了使主键概念能在面向对象中使用,Hibernate使用OID(Object Identifier:对象标识符)来唯一标识类的每个对象,OID将作为对象的主键属性以维持Java持久化类和数据库表的对应关系。
    • 怎么配置对象标识符映射?
      • 在映射配置文件(xxx.hbm.xml)中使用<id>配置OID;
      • 使用<generator>子元素指定OID的生成方式
<?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 package="com.hibernate.entity">
    <class name="Student" table="STUDENT">
        <id name="id" type="int" >
	    	<generator class="native" />
        </id>
    </class>
</hibernate-mapping>
  • <generator>的类型有哪些?(class属性的值)
    • increment: 采用 Hibernate 数值递增的方式(适用于数值型主键)
    • identity: 采用数据库提供的自增长方式(适用于数值型主键)
    • assigned: 不设置自动生成主键,主键由程序员编写的程序生成;
    • native: 自动选择合适的标识符生成器(适用于数值型主键)
    • uuid: 通过uuid算法生成字符串型主键(适用于字符串型主键)
    • sequence: 采用数据库提供的序列方式;
    • hilo: 通过hi/lo算法 // Hibernate 5.0 以后不支持;
    • seqhilo: 通过hi/lo算法;
  • increment 标识符
    • 该机制是 Hibernate 以递增的方式为OID赋值。不依赖于底层数据库系统,适合所有数据库;
    • 适合单独的 Hibernate 应用使用,不适合在集群(多个数据库)情况下使用。
    • 基本原理:Hibernate 会获取当前最大的主键值,在此基础上+1作为新的主键值
  • assigned 标识符
    • 该机制依赖于底层数据库,需要数据库支持自动增长字段。
    • 例如:MySQL、MSSQL、DB2、Sybase等。
  • identity 标识符
    • 该机制是由外部程序负责生成 OID, Hibernate 不负责维护主键生成,与Hibernate和底层数据库都无关。
  • native 标识符
    • native由hibernate根据使用的数据库特性自行判断采用identity、hilo、sequence其中一种作为主键生成方式。
  • uuid 标识符
    • 通过uuid算法生成字符串型主键
    • uuid长度大(32位),占用空间大
    • 生成效率高
    • 全球通用唯一
  • 关系映射

    • 一对多
      • 抽象描述为:某种类型的单个实体通过某种行为与其它类型的多个实体相关联,且“多方”的单个实体不会与“一方”的多个实体以同种方式相关联;
        • ~ 例如:一个班级有多个学生,一个学生不会同时属于多个班级。
      • 在类中表现为:可以通过一个类的一个对象去访问其它相关联类的多个对象,“一方”的对象的属性存放了“多方”的多个对象;
        • ~ 例如:通过“班级类”的一个实例化对象的“班级成员属性”访问该班的多个“学生”对象,或者是通过任何一个该班的“学生”对象的“所属班级”属性访问该学生所属的“班级”对象。
      • 在关系数据库中表现为:“多方”的表有一个字段作为外键参照存储了“一方”的主键;
        • ~ 例如:class表(班级表)有两个字段:clno(班级号)、name(班级名称);student表有三个字段:sno(学号)、name(姓名)、clno(所属班级的班级号),其中学生表的clno是外键,参照班级表的clno;
      • 在Hibernate中配置映射文件的方法:
  • 单向一对多:
    • 说明:只有“一方”类的对象能够访问“多方”类的对象集合,而“多方”类的对象不能访问“一方”类的对象。
    • 设计步骤:
    1. 给“一方”的类添加集合属性用于存储“多方”类的对象;
    2. 在“一方”对应的映射文件的<class>中添加<set>元素,并指定存放“多方”的集合的属性名、级联方式、是否关闭外键更新、“多方”表的外键字段名、“多方”的类名,例如:
<class name="Classes">
	<id name="clno" type="int" ><generator class="native" /></id>
	<set name="studentSet" cascade="save-update" inverse="true">
	    <key column="clno"/>
	    <one-to-many class="Student" />
	</set>
</class>
  • 单向多对一:
    • 说明:只有“多方”类的对象能够访问“一方”对象,而“一方”类的对象不能访问“多方”类的对象。
    • 设计步骤:
    1. 给“多方”的类添加“一方”类型的属性用于存储“一方”类的对象引用;
    2. 在“多方”对应的映射文件的<class>中添加<many-to-one>元素,并指定存放“一方”对象的属性名、级联方式、“多方”表的外键字段名,“一方”的类名,例如:
<class name="Student">
	<id name="sno" type="int" ><generator class="native" /></id>
	<many-to-one name="myclass" column="clno" cascade="save-update" class="Classes"/>
</class>
  • 双向一对多:
    • 说明:“多方”类的对象能够访问“一方”对象,并且“一方”类的对象也能访问“多方”类的对象集合。
    • 设计步骤:
    1. 给“多方”的类添加“一方”类型的属性用于存储“一方”类的对象引用;
    2. 在“多方”对应的映射文件的<class>中添加<many-to-one>元素,并指定存放“一方”对象的属性名、级联方式、“多方”表的外键字段名,“一方”的类名;
    3. 给“一方”的类添加集合属性用于存储“多方”类的对象;
    4. 在“一方”对应的映射文件的<class>中添加<set>元素,并指定存放“多方”的集合的属性名、级联方式、“多方”表的外键字段名、“多方”的类名。
    • 一对一
      • 抽象描述为:某种类型的单个实体通过某种行为与其它类型的单个实体相关联;
        • ~ 例如:一个人有一张身份证,一张身份证只给一个人用。
      • 在类中表现为:两个类的中都存放了对方类的对象作为属性,或者只有一方存放了另一方的对象作为属性;
        • ~ 例如:“Person类”有一个“idCard”属性是“IdCard类”对象,或者“IdCard类”有一个person属性是“Person类”对象,或者两者都有。
      • 在关系数据库中表现为:“一方”的表有一个字段作为外键参照存储了另“一方”的主键,或者是“一方”的表的主键值参照了另“一方”的主键;
        • ~ 例如:person表有两个字段:pid、name,idcard表有两个字段:cardid、pid,其中idcard表的pid是外键,参照person表的pid;
          或者:person表有两个字段:pid、name,idcard表有一个字段:cardid,其中person表的pid参照(等值于)idcard表的cardid。
      • 在Hibernate中配置映射文件的方法:
  • 外键关联
    • 说明:指定其中“一方”使用额外的字段当作外键来关联两个表
    • 设计步骤:
  1. 给两个需要关联的类都添加对方类型的对象作为属性;
  2. 在“主键方”对应的映射文件的<class>中添加<one-to-one>元素,并指定存放“外键方”对象的属性名、所关联“外键方”的类中存放“主键方”对象的属性名、级联方式,例如:
<class name="Person">
	<id name="pid" ><generator class="native" /></id>
	<one-to-one name="myIdCard" property-ref="myPerson" cascade="all" />
</class>
  1. 在“外键方”对应的映射文件的<class>中添加<many-to-one>元素,并指定存放“主键方”对象的属性名、外键字段名、唯一性、级联方式,例如:
<class name="IdCard">
	<id name="cid"><generator class="native" /></id>
	<many-to-one name="myStudent" column="mypid" unique="true" cascade="all" />
</class>
  • 主键关联
    • 说明:指定其中“一方”主键值是参照“另一方”的主键生成的
    • 设计步骤:
  1. 给两个需要关联的类都添加对方类型的对象作为属性;
  2. 配置“主键方”对应的映射文件,在<class>中添加<one-to-one>元素,并指定存放“外键方”对象的属性名、所关联“外键方”的类名、级联方式,例如:
<class name="Person">
	<id name="pid" ><generator class="native" /></id>
	<one-to-one name="myIdCard" class="IdCard" cascade="all" />
</class>
  1. 配置“外键方”对应的映射文件,设置<id>的生成方式为参照外键,并指定参照的表,在<class>中添加<one-to-one>元素,并指定存放“主键方”对象的属性名、主键受约束、级联方式,例如:
<class name="IdCard">
	<id name="cid" >
		<generator class="foreign">person</generator>
	</id>
	<one-to-one name="myPerson" constrained="true" cascade="all" />
</class>
  • 多对多
    • 抽象描述为:类型A的单个实体通过某种行为与类型B的多个实体相关联,而且类型B的单个实体通过反方向的同种行为的与类型A的多个实体相关联;
      • ~ 例如:一个学生可以选修多个课程,一个课程也可以被多个学生选修。
    • 在类中表现为:两个类里都有一个集合属性存放了多个对方类对象;
      • ~ 例如:通过“学生类”的一个实例化对象的“选修课程属性”访问已选修的多个“课程”对象,或者是通过一个“课程”对象的“选修的学生”属性访问选修了该课程的所有“学生”对象。
    • 在关系数据库中表现为:使用一个中间表存放双方表的主键,以此建立多对多关联;
      • ~ 例如:student表有两个字段:sno、name;course表有两个字段:cno、name,建立起多对多关联的st_co表有两个字段:sno、cno;
    • 在Hibernate中配置映射文件的方法:
    • 设计步骤:
    1. 在双方的类中都添加一个集合属性用于存放多个对方类的对象;
    2. 在两方对应的映射文件的<class>中添加<set>元素,并指定存放“对方”对象集合的属性名、中间表的表名、级联方式、“己方”在中间表的外键名,“对方”的类名、“对方”在中间表的外键名;例如:
<class name="Student">
	<id name="sno" >
		<generator class="native"/>
	</id>
	<set name="myCourses" table="st_co" cascade="save-update">
	    <key column="mysno"/>
	    <many-to-many class="Course" column="mycno" />
	</set>
</class>
<class name="Course">
	<id name="cno" >
		<generator class="native"/>
	</id>
	<set name="myStudents" table="st_co" cascade="save-update">
	    <key column="mycno"/>
	    <many-to-many class="Student" column="mysno" />
	</set>
</class>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值