第一部分:Hibernate入门
包括:ORMapping原理、Hibernate是什么、能干什么、有什么、体系结构、怎么做
1.什么是O/R Mapping?(object/relationalmapping,ORM)
对象-关系映射是一门非常实用的工程技术,它是为了让程序对数据库的访问变成面向对象式的访问,但是数据库本身是关系型的,为了解决这一难题, O/RMapping 工具就扮演着从面向对象的访问到关系型数据库存储的桥梁。
2. O/R Mapping的优点
A.它会自动地将对象的操作转换为SQL语句操作
B.提高学习和开发效率,降低开发成本
C.简化代码,减少bug数量
D.提高性能,对象级缓存可以避免不必要的数据存取,极大的提高数据读写的性能,节省时间和减少工作量
E.隔离数据源,可以很方面的转换数据库,只需修改配置文件
3.Hibernate是什么?提供了什么?过程是什么?工作原理及为什么要用?
Hibernate是:
Hibernate是非常优秀,成熟的O/R Mapping工具。它提供了强大的功能,让我们以面向对象的方式访问关系型数据库
提供了:
a.提供了访问数据库的操作接口(如保存,更新,删除)
b.内部封装了JDBC,对事务的控制(JTA)
c.提供了如下核心接口:
Configuration:配置和启动hibernate,创建SessionFactory对象
SessionFactory(会话工厂):初始化hibernate,创建session对象
Session:负责保存,更新,删除,加载和查询对象
Transaction:负责管理事务
Query和Criteria:执行数据库查询
注意:
A.configuration类负责管理hibernate的配置信息,如
a.hibernate运行的底层信息:数据库的URL,用户名,密码,JDBC驱动类,数据库Dialect,数据库连接池等
b.hibernate映射文件(*.hbm.xml)
c.调用代码 Xml文件(hibernate.cfg.xml)
Configuration cfg=newConfiguration().configure();
B.SessionFactory(会话工厂)缓存了生成的SQL语句和hibernate在运行时使用的映射元数据
调用代码:SessionFactorysf=cfg.buildSessionFactory();
C.Session不是线程安全的,它代表与数据库之间的一次操作回话
Session也叫持久化管理器,它是与持久化有关的操作接口
Session通过SessionFactory打开,所有工作完成后,需要关闭
Session缓存其管理的持久化对象
调用代码
Session session=sf.openSession();
D.Transaction将应用代码从底层的事务实现中抽象出来
Hibernate提供的事务提交模式默认为非自动提交模式(默认autoCommit=false),因此使用hibernate进行操作时(增,删,改)必须显示的调用Transaction的API
代码调用:
Transaction tx=session.beginTransaction();
tx.commit()/rollback();
E. Query接口封装了hibernate强大的对象查询能力,也数据库的更新操作。
提供了动态查询的参数绑定功能
提供了list(),iterator(),scroll()等对象导航方法
提供了uniqueResult()方法获取单独的对象
提供executeUpdate()方法来执行DML语句
过程是:
创建数据库与表
创建持久化类
创建类与表之间的关系映射文件
创建hibernate配置文件
使用hibernate API编写访问代码
运行测试
注意:持久化java类必须要遵循的原则:
要有getter或setter方法
实现一个默认的构造方法(constructor)
如果是集合类型的属性,它的类型必需定义为集合类接口。如List,Set
提供一个标识属性(identity property),并使用包装类
原理:
1.读取并解析配置文件
2.读取并解析映射信息,创建SessionFactory
3.打开Sesssion
4.创建事务Transation
5.持久化操作
6.提交事务
7.关闭Session
8.关闭SesstionFactory
为什么要用:
1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
2. Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作
3. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。
4. hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
第二部分:Hibernate的基本配置
包括:准备工作、mapping配置、日期配置等
准备工作:
1.创建表时将hbm2ddl.auto设置为create(删除老的表,创建新的表结构)。
测试时先在数据库中输入相关数据,并将hbm2ddl.auto设置为update,防止因为创建新的表删除了输入的数据,导致测试失败
2.将文件:${hibernate_home}\project\etc\log4j.properties 复制到工程的src目录下
3.每次进行配置后,根据配置创建一个Session对象,如:HibernateSessionFactory.getSession();这时程序会加载并验证配置文件,并生成相应的数据表。
mapping配置:
package:用于统一指定该元素内部所有<class>元素对应的持久化类的包名
<class>元素:用来定义一个持久化类和一个数据库表之间的映射关系。
常用属性:
Name:持久化类的类名
Table:对应的数据库表名
Dynamic-update:用于指定执行update操作时是否动态生成update语句,默认false。
Dynamic-insert:用于指定执行insert操作时是否动态生成insert语句,默认false。
<id>元素:在hibernate中必须给持久化类定义一个与对应的数据库表中主键相对应的属性,即对象标识符(OID)
<id>元素配置:
<idname=“” type=“” column=“”
access=“property|field”>
<generator class=“”/>
</id>
Generator指定OID的生成器类名,可使用hibernate内置的生成器类关键字,常用的内置生成器如下:
Increment:适用于long,short,int型的代理主键,由Hibernate以增量1的方式递增
Identity:适用DB2,MySQL,SQL Server,Sybase等支持标识字段产生的标识,用于long,short,int
Sequence:适用于DB2,Oracle中的序列产生的标识符,long,short,int
native 根据底层的数据库的情况选择identity,sequence中的一个来生成主键
Assigned :适用于业务主键,由java应用负责生成标识符
<property>元素:定义了一个持久化类的属性与数据库字段之间的映射关系
常用属性有:
Name:映射类属性名
Column: 映射数据库表字段名
Type:字段的类型,使用Java类型或Hibernate类型
Update:update时是否包含本字段,当某个字段不需要修改时使用, 默认为true
Insert: insert时是否包含本字段,当某个字段不需要插入时使用, 默认为true
Access: 访问属性的策略,property(getter/setter)|field(.)
Unique: 设置这个字段的值是否唯一,默认为false
not-null: 设置这个字段的值是否允许为空,默认为true
unique和not-null只有使用配置文件反向生成数据库表时才有用,用来指定该字段是否唯一以及是否允许为空
关于日期:
映 射 类 型 |
Java类型 |
标准SQL类型 |
描 述 |
date |
java.util.Date或者java.sql.Date |
DATE |
代表日期,形式为: YYYY-MM-DD |
time |
java.util.Date或者java.sql.Time |
TIME |
代表时间,形式为: HH:MM:SS |
timestamp |
java.util.Date或者java.sql. Timestamp |
TIMESTAMP |
代表时间和日期,形式为: YYYYMMDDHHMMSS |
calendar |
java.util.Calendar |
TIMESTAMP |
同上 |
calendar_date |
java.util.Calendar |
DATE |
代表日期,形式为: YYYY-MM-DD |
注:在标准SQL中,Date类型表示日期,time类型表示时间,timestamp类型表示时间戳,同时包含日期和时间信息
对类型为timestamp的列,当没有插入时,默认值是当前系统时间
第三部分:关系映射
包括:一对一,一对多,多对一,多对多等
一对一关系:
数据库表中的一对一设计分为两种形式:
A.外键关联:一个表中添加一个字段作为外键,值是与其相对应一对一关系表的主键值
B.主键关联:两张一对一关系的表共用一个主键,主外间是一个字段
在实体关系中:
A.单向关联:在任意一个实体类中添加另一个实体类型的属性
B.双向关联:在两个实例中都添加另一个实体类型的属性
实体映射文件的配置:
第一种形式(外键关联)
单项关联:主表映射文件不变,附表中使用<many-to-one>
附表:<many-to-one name=”” class=”” column=””unique=”true”/>
双向关联:主表中用<one-to-one>指定property-ref的值,附表中用<many-to-one>
主表:<one-to-one name="" class="" property-ref =" "/>
附表:<many-to-one name="" class=" " column=" " unique="true"/>
第二中形式(主键关联)
单向关联:主表映射文件不变,附表中id属性generator的使用变化,<one-to-one>使用
附表:
<id name=""column="">
<generator class=" foreign">
< param name="property">xxx</param>
</generator>
</id>
<one-to-onename="room" class="cn.zc.domain.Room"constrained="true"/>
双向关联:主表使用<one-to-one>,附表附表中id属性generator的使用变化
主表:<one-to-one name=”” classs=””/>
附表:
<id name=""column="">
<generator class=" foreign">
< param name="property">xxx</param>
</generator>
</id>
一对多,多对一关系:
数据库中一对多关系表现:
多的一方添加一个字段作为外键,字段的值是一的那一方的主键值
在实体关系中:
A.单向关联:多的一方设置一个私有属性,该属性是一的那一方的引用
B.双向关联:在单向关联的基础上,一的那一方添加一个集合set,类型是多的一方的引用(set<多的一方的类型>)
实体映射文件的配置:
单项关联:主表映射文件不变,附表中使用<many-to-one>
附表:<many-to-one name=”” class=”” column=”” />
双向关联:主表中用<set>,附表中用<many-to-one>
主表:
<set name="items">
<key column="orderid"></key>
<one-to-many class="Item"/>
</set>
附表:<many-to-one name=" " class=" " column=""/>
多对多关系:
一般多对的关联会拆分成两个一对多的关系来实现,hibernate的实现方式是通过中间表间接的实现了多对多关系,实际上也是将多对多拆分成两个双向的一对多关系,且中间表是没有实体类的。
实体映射文件的配置:
单项关联:
表一:
<set name="" table=" ">
<keycolumn=""></key>
<many-to-manyclass=""column=""/>
</set>
表二:
<many-to-many class=""column=""/>
双项关联:
表一:
<set name="" table=" ">
<keycolumn=""></key>
<many-to-manyclass=""column=""/>
</set>
表二:
<set name="" table="">
<key column=""></key>
<many-to-manyclass=""column=""/>
</set>
注:
Set接口类型映射:<set>通常代表“多”的一端。
<set>的属性如下:
Name:映射类属性的名字
Lazy:是否采用迟延加载
Inverse:标识双向关联中被动的一方,为“true”时表示控制方为对方
<key>元素:是<set>的子元素,必不可少,用于描述两者之间的关联关系。
<key>的常用属性:
Column:父元素所持有的类所对应表的外键字段名
On-delete:外键关联是否打开数据库级别的级联删除,noaction|cascade
not-null:表明外键字段是否可以为空,true|false
update:表明外键是否可以被更新,true|false
unique:表明外键是否有唯一性约束,true|false