📄 hibernate_note.txt
字号:
hibernate day01
先讲理论在讲语法,然后基础语法。
基本理论:
1,对象持久化的概念。
2,orm的概念,不同的orm的方法。
3,hibernate结构和语法,基本语法。
理论:
对象持久化,orm,orm的选择。
什么叫对象持久化:把对象从非持久化设备上“转移 ”到持久设备上。
1、为什么要对象持久化:
a、对象持久化的主要原因有两个,内存只能使数据得到一个暂时的存储。
b、大规模的检索(sql,或者别的)。
×c、内存的大小受限。
×d、网络上传递。
(×表示非主要原因)
必要性:内存的数据,都在对象里面。编程语言都是面向对象的。和以上原因使得它使必要的。
2、对象持久化有那些方法:
a、对象序列化:
它功能实现是把对象变成二进制序列。对象在内存是以特殊的结构存储的。
对象编程序列之后,就可以用流的方式来传递了。
所以它适合于,网络传递,短时间的利用硬盘文件来持久化对象。
停机维护系统内容,进行对象序列化,从项目的角度这也要想到。
序列化是每个对象都是二进制的形势,铁板一块,如果要做检索需要把它恢复到内存。
网络传递的时候对少量的参数进行持久化,或者对少量的对象做物理文件的暂时持久化。
b、JDBC DB:
利用jdbc就是利用数据库来对象持久化。
从DB的结构可以进行大规模的检索。(SQL)
并且这个结构是易于关系的,R(db是基于集合论)。
数据库还支持事务,在企业应用里,对事务的要求是必须的。
所以我们使用数据库是比较适合我们大规模的对象持久化。
×大规模的对象,大规模检索,等等。
c、oodb:
面向对象的数据库,可以直接对对象进行存储。
现在是等待成熟。
以后肯定会转化到对象数据库
×d、jndi
为了在以个很大的范围内共享这个少量的对象。
不适合大规模存储。
所以对对象进行持久化,有很多种,但是每种都有自己适用的反问。所以这样我们选择关系型DB
问题:
怎么样用关系型数据库来做呢。
这就叫做用jdbc往数据库里面存东西。
ORM:
1:什么是orm
它的意思通俗的说就是把它存入数据库里面。
object relation(关系型数据库,元组,表就是个元组,元组之间有他们自己的关系。) mapping
对象和数据库里面的表的对应关系。
结论:目的明确的,系统的,结构合理的,把对象和数据库里面的数据进行互换。
2、手段:
a、JDBC,用它来实现。
好处:
它是java唯一访问数据库的接口。灵活性很强。
jdbc它是java访问数据库的最底层技术,所以它灵活,灵活带来的是效率高。
缺点:
代码量大,因为jdbc抽象程度低。
在项目级别上的重复,每个项目都要进行大量的代码开发。
难度大:
一个对象的状态一变化就马上把它存到数据库里面。
等等....
结果:大家要不然就是放弃,要不然代码的质量低,代码总是出问题。
统计数据:它占到了项目的30%到40%的代码。也就是1/3东西和自己的业务没有关系。
如果图形化界面40%的代码,那么业务只能占用20%的代码。
罗斯福:一些人挖坑,一些人把代码改好,最后大家都就业了。
现在小公司里面就是这样,一些人把代码写烂,另外一写人把代码在改好。
项目就在这里成为了薄弱的环节,在97年以前,不光是java所有系统都没有,
unix的主机,frame(巨型机)和corbor直接做成业务系统。所有的系统都是以中心计算为主。
用的最多的就是存储过程。项目是面向过程的,大量的存储过程在核心计算里面。
突然有一天sun退出了ejb。
b、ejb
刚刚退出的时候大家在盲目的使用,因为jdbc实在他类。认证,安全,声明事务,分布式,持久化。
它解决了在企业级应用平台上的很多事情,ejb以一种大而全的形势出现
关键是,分布式计算:在不同的机器之间可以调用其他机器上的组件。
持久化:jdbc太麻烦
分布式没有问题,ejb的分布式是有史以来最好的分布式。
持久化种的entitybean有问题,它的持久化操作很复杂,这样的一个周期下来大概要15分钟。
配置,部署,启动服务器,写测试用例。等等,我们调试程序很不方便。
而且功能也不全:对特定的对象之间的映射不支持,比如继承。实体bean不能随便地继承。
ejb的问题是:1,操作复杂,2,调试不方便,3,功能不全。但他就是特别持久化有点弱。
分布式:是它最强的一个项目。
程序员已经走投无路了,程序员用jdbc写了一个项目,后来就把jdbc代码做的通用一些,
c、ORM框架
通用的jdbc的代码,减少jdbc代码量,减少写jdbc代码的难度。
最后大家用了同一个思路,生成JDBC代码。
ORM框架如何生成JDBC代码:
1、由程序员来声明对象和表的映射关系。类之间的关系,继承关系,关联关系。
2、由程序员调用ORM API,将来就按照ORM来读和写数据库。其实就是生成了JDBC代码。
ORM的作用:
由了这个框架之后,从本质上来说就是对“JDBC API的封装和提升”。
反过来看:
解决JDBC的开发问题,JDBC开发的量大,难度大,封装之后达到简化的结果。
问题的实质是JDBC API太靠近底层。
机器语言,汇编,c语言,程序员现在叫做蓝领。
工具是人类解决问题的手段,计算机是人类解决问题的最有利工具。
问题解决不了的时候,是不是要解决工具的问题。
hibenrate 在orm框架里面是最早的,当今来看是最好的:
大同小异:都是为了封装jdbc API都是为了,他能增加你的知识。还有很多种框架。
今天的经验要可以转移。
ibatis 它的应用也很多,抽象成都低,更靠近底层。它的度比较合适。
HIBERNATE ARCHITECTURE 设计结构
Application 我们的应用程序
Persistent Objects 持久化对象,应用程序的一部分,还有持久层的一部分
Hibernate hibernate api
hibernate.properties hibernate本身的配置环境信息,主要包括连接数据库的内容。
XML Mapping 映射文件
Database 数据库
工作方式
1、应用程序决定那个po做持久化。我们能写的代码
2、调用hibernate api对po做操作。hibernate接到命令后查看映射文件。我们写的映射文件。
3、hibernate产生JDBC代码。
4、hibernate调用JDBC,完成持久化操作。完成以前我们用JDBC把PO存取DB。
jdbc代码是为了实现映射,以前的映射关系是在我们大脑里面的。
HIBERNATE框架比喻:
hiberneta就是搬运工,hibernate 配置文件就是搬运图。
图中物体在地方是PO,要放的地方是数据库的表。
要跟搬运工说话要用它的语言就是hibernate api
开发步骤:
OO为导向
ORM JAVA是面向对象的平台。所以它也是以对象为主导。
在有些遗留的系统里面,往往数据库表已经存在了。有的时候就需要通过表来创建对象。
1、面向对象的分析和设计。产出:java对象和类,就是PO。ENTITY(需求中的业务实体)->OBJECT。EO分析。
2、XML写映射文件,确定数据库的结构(Schema)。主要学习的内容,学习什么东西怎么映射。
3、写测试代码。来调用Hibernate的API。也需要花时间。
开发环境:
1、讲hibernate的类库需要配置到CLASSPATH里面。用eclipse来管理类路径。
2、给大家XML文件的模版。
×3、DTD文件,xml文档都跟着以个dtd,eclipse经常回到互联网上照dtd,所以我们有时候会去找dtd。给大家两个eclipse里面。
开发步骤2:
1,映射的原则。
1、类映射表。
2、属性映射字段。
3、对象映射记录。
4、类之间的关系映射表之间的关系或者表。
2,hiberante API。
几个类是最重要的:
1、Configuration 用来读取hibernate配置文件的。XML的解析程序。hibernate读的xml的解析结果。
2、SessionFactory 它是Session工厂,它相当于数据源。线程安全的。它有一个就够了。重量级对象开销大。
3、Session 相当于JDBC的Connection,Statement ResultSet 功能集。单线程使用的对象,多线程环境它不安全。
Session是线程不安全的,不要在线程之间传Session。Session的开销不是很大。
4、Transaction专门有这样的一个类,用它来做面向对象的事务管理。
5、利用Session.save()存对象。Student stu=new Student();Session.save(stu);
编写代码
1、pojo类,一般属性和oid对象的oid是由某种算法计算出来的,对象oid,对象的唯一标识符。它是由hibernate来赋值的。
2、添加相应的get和set方法。(isXXX boolean属性的变化)。
把setSId改成私有的。唯一标识的访问函数。hibernate可以访问。
提供无参构造和有参构造。
配置文件的头带有包名.
<hibernate-mapping package="com.haige.biz">
整个类的映射就在class里面
<class name="Student" table="T_STUDENT">
只有对象唯一标识符才用<id>标签
<id name="sid" column="ID">
<generator class="hilo">
<param name="table">t_hilo</param>
<param name="column">hi</param>
</generator>
</id>
它如果碰到sid属性就会把它的值插入到ID字段里面,实际上是从t_hilo表里面查询hi表把数据放入sid.
第二点:需要用某种算法把id算算出来
id不可以由业务含义,我们要求它是中性的,因为学号是可以改变的.
hilo是hibernate算的,
普通属性使用property标签.
<property name="name" column="name"/>
<property name="age" column="age"/>
<property name="stuId" column="stuId">
纵观整个hibernate,我们开发的是:
pojo类,我们业务中数据的实体
hibernate Api负责把业务实体通过映射文件生成JDBC
映射文件 描述类和表,字段和属性,类的关系和表的关系的映射
hibernate 执行JDBC代码完成数据库操作
hibernate是对底层jdbc的封装.
hibernate-mapping
<hibernate-mapping schema="schemaName"
default-cascade="cascade_style"默认的级联操作,一般在每个字段里面去写级联操作.
default-lazy="true|false"读取关联对象的时候是否要加载.true表示在使用的时候再加载.
>
<class
name
table
dynameic-update="true",只有非空字段才会出现
batch-size="N"
>
<id
name
column
type=""//映射的类型,不是java的类型.也不是数据库类型
unsaved-value="null|any|none|undefined|id_value"//和对象状态相关
access="field|property|ClassName"//
>
<generator
class="hiberante产生id的机制"
//icrement identity squence hilo seqhilo uuid
生成方式:
assigned 你要负责给id提供值
hilo 任何数据库里面都可以建立一个高低位的表,也和数据库无关.
seqhilo
identity(标识) 数据库里的自增字段,再mysql里面叫auto_increment,
sequence oracle里面的自增表,如果id产生方法是sequence那么hibernate就会使用,hibernate_sequence
native 表示hibernate会自己选择使用以上两种中的一种来做id生成机制.是从方言里面得到的.可以做一个兼容性的开发.
uuid 通过ip计算出一个128位的值.如果是真ip那么不会重复.表示成16进制的字符串.
>
<property
name
cloumn
type
access
lazy
>
hibernate的映射类型
基本映射类型基本都不用写.
由几个要写的是:
data
time
timestamp
java data
db data time timestamp
java的data映射成什么格式就使用
claendar
calendar_date
日历类在数据库里面也有两种所以要声明它
big_decimal big+integer 变成 number 不用写
....
一对一的都不用写.
第二章以后要用的东西.
hiberante 参考手册的附录.
对象关系映射:
po之间的关系.po的结构是固定的,po的关系近似于一个动态的东西.
如果一个对象a有一个对象b的引用.
那么在数据库里面就有在表之间产生一个约束关系,主外键关系,表之间也就只有主外键关系,没有别的.
阻抗不匹配:配合不到一起,两个完全不匹配.
表之间的关系很简单
对象之间的关系.
a类 和 b类,
有引用关系那么他们之间叫关联关系
有继承关系那么 继承
关联: use 普通的关联
聚合 b是a的一部分,b可以脱离a的环境存在,has a
组合 b是a的一部分,b不可以脱离a的环境存在,b part of a
把对象的关联关系从强度上分可以分成
关联,聚合,组合
把对象的关联关系按照方向性分成:
单向,双向,
把对象的关联关系按照数量关系分成:
一对多,多对多,一对一
关于关系映射我们只考虑方向和数量关系.
强度我们不考虑,它不影响数据库里的存储.
业务的含义使得他们之间在关系上有强度之分.
方向和数量合在一起,叫做"基数关系".基于数量的关联关系,hibernate里面叫做entity Associations 实体关联关系
我们研究基于数量的关联关系.
判断关系数量的时候就要判断引用的数量.
一对一:
在内存中怎么映射,在数据库里是怎么做.
内存:
a对象里面有个b对象的引用,b对象里面有个a对象的引用
java 数量关系的由引用的决定.
A里面由两个B的引用, A对B, 就是 1对2.
A 1:2 B
b a
b
对象里面引用的数目,是关系的另外一方的数目不是自己的树木.
双方都有对方的引用就是双向
只有一方由对方的一个引用叫做单项
表:
po1有po2的引用,那么po2这个属性怎么存到数据库里面.
解决方案是po1存到po1的表里面.po2存到po2的表里面
po1(po2)关系表示写法有两种:
唯一外键:
t_po1: oid1 oid2(froregin key)
t_po2: oid2
主键是唯一的外间不唯一,怎么体现一对一呢.
po1和po2并没有严格的表达出来我们的一对一.
"所以给外键加上unique唯一性约束,那么就表达了一对一的关系"
(主外键关系从本质上来说是一对多,加上唯一性约束后,从表的层次把一对一表达了出来.)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -