目录
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程序的流程
- 安装Eclipse、mysql;
- 下载Hibernate,并解压缩(去下载Hibernate);
- 使用Eclipse创建新的项目;
- 引入Mysql数据库驱动包;
- 导入Hibernate所需的jar包(Hibernate目录下的lib / required);
- 编写Hibernate核心配置文件(后面作详细说明);
- 创建Java持久化类XXX.java(类似javaBean);
- 编写持久化类的映射配置文件XXX.hbm.xml;
- 使用Hibernate API 完成对象的持久化(即向数据库同步数据)。
◎ 核心配置文件在默认情况下放置在src目录下
◎ Hibernate的核心配置文件有两种形式:
- hibernate.properties (键=值方式)
- 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>
-
创建持久化类
- 类是共有的(public)
- 属性是私有的(private)
- 提供getter与setter(getXxx或isXxx和setXxx方法)
- 必须提供公有的无参构造方法
- 类不能被finnal修饰
- 有一个属性(id)用于唯一标识每一个对象
- 如果属性是基本数据类型,最好使用包装类
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” />:指定该属性存储在表中的字段名称;
- 常用属性:
- <id>,在<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" >
<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中配置映射文件的方法:
- 抽象描述为:某种类型的单个实体通过某种行为与其它类型的多个实体相关联,且“多方”的单个实体不会与“一方”的多个实体以同种方式相关联;
-
-
单向一对多:
- 说明:只有“一方”类的对象能够访问“多方”类的对象集合,而“多方”类的对象不能访问“一方”类的对象。
- 设计步骤:
- 给“一方”的类添加集合属性用于存储“多方”类的对象;
- 在“一方”对应的映射文件的<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>
-
单向多对一:
- 说明:只有“多方”类的对象能够访问“一方”对象,而“一方”类的对象不能访问“多方”类的对象。
- 设计步骤:
- 给“多方”的类添加“一方”类型的属性用于存储“一方”类的对象引用;
- 在“多方”对应的映射文件的<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>
-
双向一对多:
- 说明:“多方”类的对象能够访问“一方”对象,并且“一方”类的对象也能访问“多方”类的对象集合。
- 设计步骤:
- 给“多方”的类添加“一方”类型的属性用于存储“一方”类的对象引用;
- 在“多方”对应的映射文件的<class>中添加<many-to-one>元素,并指定存放“一方”对象的属性名、级联方式、“多方”表的外键字段名,“一方”的类名;
- 给“一方”的类添加集合属性用于存储“多方”类的对象;
- 在“一方”对应的映射文件的<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。
- ~ 例如:person表有两个字段:pid、name,idcard表有两个字段:cardid、pid,其中idcard表的pid是外键,参照person表的pid;
- 在Hibernate中配置映射文件的方法:
- 抽象描述为:某种类型的单个实体通过某种行为与其它类型的单个实体相关联;
-
外键关联
- 说明:指定其中“一方”使用额外的字段当作外键来关联两个表
- 设计步骤:
- 给两个需要关联的类都添加对方类型的对象作为属性;
- 在“主键方”对应的映射文件的<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>
- 在“外键方”对应的映射文件的<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>
- 给两个需要关联的类都添加对方类型的对象作为属性;
- 配置“主键方”对应的映射文件,在<class>中添加<one-to-one>元素,并指定存放“外键方”对象的属性名、所关联“外键方”的类名、级联方式,例如:
<class name="Person">
<id name="pid" ><generator class="native" /></id>
<one-to-one name="myIdCard" class="IdCard" cascade="all" />
</class>
- 配置“外键方”对应的映射文件,设置<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中配置映射文件的方法:
- 设计步骤:
- 在双方的类中都添加一个集合属性用于存放多个对方类的对象;
- 在两方对应的映射文件的<class>中添加<set>元素,并指定存放“对方”对象集合的属性名、中间表的表名、级联方式、“己方”在中间表的外键名,“对方”的类名、“对方”在中间表的外键名;例如:
- 抽象描述为:类型A的单个实体通过某种行为与类型B的多个实体相关联,而且类型B的单个实体通过反方向的同种行为的与类型A的多个实体相关联;
<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>