Hibernate简介
Hibernate是一个ORM( 对象关系映射 Object Relational Mapping)的框架,对JDBC进行了轻量级的对象封装,让开发人员更方便地操作数据库。
Hibernate的优势
1.Hibernate对JDBC访问数据库的代码做了轻量级封装,可以直接通过hibernate api ,保存对象到数据库、且从数据库中查询到的就是对象!大大简化了数据访问层繁琐的重复性代码,并且减少了内存消耗,加快了运行效率。
2.Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现,它很大程度的简化了dao(Data Access Object,数据访问)层编码工作。
3.Hibernate使用Java的反射机制,而不是字节码增强程序类实现透明性。
4.Hibernate的性能非常好,映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系。
5.可扩展性强,当本身功能不够用时,可以自行编码进行扩展。
Hibernate的环境配置
1.下载并引入有关 Hibernate的jar包。
2.创建数据库及表。
3.写entity(实体类) User。
4.写实体类对应的映射文件 User.hbm.xml
5.写核心配置文件hibernate.hbm.xml
6.Api操作数据库
hibernate核心配置文件
<session-factory>
<!-- 数据库连接信息配置 -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate01</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
数据库方言配置:
作用: 告诉hibernate当前项目使用的数据库; hibernate会根据方言配置的数据库生成符合当前数据库语法特征的sql语句!
hibernate通过方言实现了跨数据库平台!
org.hibernate.dialect.MySQLDialect
mysql5或以下版本(不支持事务)
org.hibernate.dialect.MySQL5InnoDBDialect
mysql5.5以上版本
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- 显示hibernate在运行时期底层生成的sql语句! -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化sql语句 -->
<property name="hibernate.format_sql">true</property>
<!--
自动建表
update 如果表不存在则创建;表已经存在就不创建表,更新!
create 先删除表,再创建表!
create-drop 在创建SessionFactory的时候创建表,在执行sf.close()方法时候删除表!
validate 不创建表只做验证:验证映射文件与表是否一致,不一致报错!(注意,如果对象中的属性跟表中字段不一致则报错,个数不用也会报错,所以平时比较少用)
注意:
如果要用自动建表功能,必须加载映射文件!建表是根据映射文件创建的表!
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 加载映射文件(*.hbm.xml) -->
<mapping resource="cn/itcast/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
映射文件配置User.hbm.xml
存放位置
持久化的实体类对象,与映射文件,放到同一个目录!
<hibernate-mapping package="com.entity">
<!--
class 指定要映射的对象; table 指定对象对应的表
name 实体类对象名称;
table 对象对应的表名称;如果不写默认与对象名称一样!
-->
<class name="User">
<!--
2. id 表示表的主键映射 ; hibernate要求表必须要有主键,那么在映射中一定要配置主键!
主键生成策略:表示主键以何种方式生成!
class
identity mysql、sqlservlet等数据库自增长方式
sequence oracle中以序列方式实现自增长!
native 自增长: 会根据底层数据库支持的自增长方式自动选择identity或者sequence其中一种!
assigned 手动指定主键值! (必须要自己控制唯一!)
uuid 系统生成唯一的uuid作为主键
-->
<id name="id" column="tid">
<generator class="native"></generator>
</id>
<!-- 1. 非主键字段 -->
property
name javabean对象中的属性名称!
column 属性对应的表中的字段名称; 如果不指定,与属性同名!
type 数据库中字段的类型
方式1: 用hibernate提供的类型(大小写要区分)
如: string、int、float、double、date
方式2: java中类型 (建议) (大小写要区分)
如: java.lang.String 、java.util.Date
not-null="true" 字段非空; 默认是false,运行为NULL
unique="false" 字段默认不添加唯一约束; 如果需要设置为true
length="20" 字段字符最大长度为20; 如果不指定,默认是255!
<property name="name" column="name" length="20" type="java.lang.String"></property>
<property name="salary" column="salary"></property>
<property name="birth" column="birth"></property>
</class>
</hibernate-mapping>
<!--联合主键映射-->
<hibernate-mapping package="com.compositeId">
<class name="Person">
<!--
联合主键对象映射
name="primary" 指定联合主键对象
class=PersonPrimary 主键类型
key-property 联合主键中每一个属性、列名称!
-->
<composite-id name="primary" class="PersonPrimary">
<key-property name="name" column="name" length="20"></key-property>
<key-property name="address" column="address" length="200"></key-property>
</composite-id>
<property name="age"></property>
<property name="remark" length="300"></property>
</class>
</hibernate-mapping>
Hibernate中持久化对象的状态
- 瞬时状态(Transient )
使用new操作符初始化的对象不是立刻就持久化的,他们的状态是瞬时的。
(1) 不处于Session的缓存中。
(2) 在数据库中没有对应的记录。
(3) 瞬时状态的对象在内存中是孤立存在的,与数据库中的数据无任何关联,仅是一个信息携带的载体。不存在持久化标识OID(相当于主键值). - 持久化状态(Persist)
(1) 位于一个session实例的缓存中,持久化对象总是被一个session实例关联。
(2) 持久化对象和数据库中的相关记录对应。
(3) Session在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库。
(4)持久态的对象存在持久化标识OID ,每条记录只对应唯一的持久化对象,需要注意的是,持久态对象是在事务还未提交前变成持久态的。 - 游离/脱管状态(Detached )
(1)一般是指session关闭后对象的状态, 为脱管状态(脱离session的管制)
(2) 脱管状态的对象,在数据库中有对应的记录!
(3)脱管态对象存在持久化标识OID,并且仍然与数据库中的数据存在关联,只是失去了与当前Session的关联,脱管状态对象发生改变时Hibernate不能检测到。
Hibernate一级缓存的特点
- 缓存的作用:减少对数据库的访问次数从而提高效率!,Session缓存是由hibernate自身去维护,通常用户不能手动去自己维护Session缓存!
- 当应用程序调用Session接口的save()、update()、saveOrUpdate时,如果Session缓存中没有相应的对象,Hibernate就会自动的把从数据库中查询到的相应对象信息加入到一级缓存中去。
- 当调用Session接口的load()、get()方法,以及Query接口的list()、iterator()方法时,会判断缓存中是否存在该对象,有则返回,不查询数据库,如果缓存中没有要查询对象,再去数据库中查询对应对象。
- 当调用Session的close()方法时,Session缓存会被清空。
- Session 能够在某些时间点,按照缓存中对象的变化,执行相关的 SQL 语句来同步更新数据库,这一过程被称为刷出缓存(flush)。
数据库中多表之间的三种关联关系
- 一对多:在多的一方添加一的一方的主键作为外键。
- 多对多:产生中间关系表,引入两个实体的主键作为外键,两个主键成为联合主键。
- 一对一:在任意一方引入对方主键作为外键(开发中使用非常少)。
Cascade级联操作
级联操作是指控制权没有反转,当主控方执行保存、更新或者删除操作时,其关联对象(被控方)也执行相同的操作。在映射文件中通过对cascade属性的设置来控制是否对关联对象采用级联操作。
cascade定义的是有关联关系的对象之间的级联关系,cascade的相关属性可选值如下:
1. all :所有情况下均进行关联操作。
2. none:所有情况下均不进行关联操作。这是默认值。
3. save-update:在执行save、update或saveOrUpdate时进行关联操作。
4. delete:在执行delete时进行关联操作。
5. save-update,delete :在执行save、update或delete时进行关联操作。
Hibernate的检索方式
Hibernate的检索方式主要有5种,分别为导航对象图检索方式、OID检索方式、HQL检索方式、QBC检索方式和SQL检索方式。