05 16 2008
JDBC:
功能的实现嵌入大量的SQL语句,维护困难。
Hibernate: 通过反射来构造对象,构造对象的时候需要调用无参的构造器.
(1)映射的需求:实现对象关系的映射:
ORM: object-Relational mapping
是应用程序中的对象自动的保存到数据库中的过程(对象的持久化的过程),采用元数据来描述(对象--关系映射)(类/类的结构---对应关系) xml
(2)提高效率: 不希望频繁的创建和销毁连接对象
具备缓存用于暂时存放我们经常访问的数据
(3)维护的需求:
自动生成SQL语句,便于维护,减少开发的调试工作.
(4)(提供)持久化的中间件。
作用: 1)映射关系的描许,具备完善的缓存(集合),维护简单。
2)专门实现和数据库交互的层次。(软件)
软件: 1.客户端(表示层):和用户交互,简单的有效性验证
1.业务逻辑层:具体的业务逻辑 UserService
3.持久化层:和数据库的交互 UserOper
4.数据库层:存放和管理数据
ORM特点:
1)提供了CRUD操作
C:create
R:retrieve
U:update
D:delete
2)提供特殊的查询方式:
面向对象的查询方式,通过SQL语句来实现
3)实现使用元数据来描述OR的对应关系.
4) dirty checking:自动脏检查.
中间件会自动检查缓存中的数据和数据库中的数据,尽量保证两方面数据的一致性.
lazy fetching:延迟加载.
根据具体的需求选择暂时不去加载不需要访问的主外键关系所对应的对象,直到访问的时候再去加载,以提高效率,减轻内存的压力.
5.什么是hiberbate:
(1)是开发源码的java实现的持久化中间件
(2)位于多层架构中的持久化层,专门负责和数据据交互,使业务逻辑层更加专注于系统的功能;
(3)对JDBC进行了轻量级的包装,必要的时候建议绕过hiberbate直接使用JDBC去实现某些功能(如批处理)
(4)是一种ORM工具,提供"面向对象"到"面向关系"对应的完善的描述方式.
6.涉及的文件:
(1)hiberbate.cfg.xml:提供数据库连接的基本配置信息
(2)fileName.hbm.xml:提供映射关系的描述
(3)POJO:plain and old java object:普通又古老的java对象.
1)必须具备一个id(建议为包装类类型 Long,Integer)
2)必须具备无参的构造器.
3)必须对所有的属性提供get/set方法
hiberbate在获得属性值或设置属性值通过调用set/get方法完成
4)建议:实现:java.io.Serializable接口,如果需要在网络中进行传输,POJO类必须实现该接口.
7.hiberbate的接口
(1)核心接口:提供对对象的操作,事务的控制
(2)回调接口:当应用程序需要检测某些操作的时候,可以实现在操作发生的时候接收到相关信息
(3)Tpye接口:支持用户自定义的类型
(4)扩展接口:允许用户通过该接口扩展特殊的功能
8.核心 的API
(1)Session:
1)持久化的管理器,实现CRUD操作
2)轻量级的:创建和销毁不需要耗费过多精力,建议销毁时根据需要创建和销毁session实例
* 3)非线程安全的:尽量避免多个线程操作同一个--session实例.
4)具备自己的缓存,该缓存被称为"第一级缓存",用于存放session所操作的对象
(2)SessionFactory:
1)对应一个数据存储源,产生session实例
2)重量级的,创建和销毁需要耗费多个资源,因此要尽量避免频繁的创建和销毁 SessionFactory实例
3)线程安全的
4)存在可配置的缓存.用于存放经常访问的数据,被称为"第二级缓存".
(3)Configuration:
用于读入数据库连接的配置信息(hibernate.cfg.xml),产生SessionFactory实例.
(4)Transaction:
hibernate的事务管理:
commit();
rollback();
(5)Query:
实现通过hql的查询
(6)Criteria:实现更高的面向对象的查询方式
05 19 2008
第二章:
1.映射文件以java的类的结构为核心,而不是以数据库的表的结构为核心.
在一个<hibernate-mapping>中可以并列配置多个<class>,但是如果需要配置<class>过多,会影响文件的可读性.建议一个class的配置对应一个配置文件(.hbm.xml)
3.配置id的生成策略
Hibernate中的clob,blob
save():
jdbc中:
insert into tableName values(empty_clob(),empty_blob());
select * from tableName where id=1;
再去获得输出流
load():select * from tableName where id=1;再获得输出流.
Hibernate中:
save():
Transaction trans=.....;
insert into....
手动的将数据强制的刷新到数据库中
select...
....
update...
....
trans.commit();
05 20 2008
hibernate第三章:关联关系映射
1.class面向对象 table面向关系 --->orm
单向关联和双向关联
2.一对一的关联关系
1)基于外键的一对一的单/双向关联关系
a.于外键的一对一的单向关联关系
2)基于主键的一对一的单/双向关联关系
a.基于主键的一对一的单向关联关系:
one2many or many2one
inverse="true":放弃维护的权力,可以使hibernate减少不必要的sql语句的执行提高效率,建议配置在one的一
端.
many2many
桥表:建立many2many对应两张表基础表的唯一的关系:
桥表的列由两张表的主键组成(主外键关系)组成,桥表的主键为所有列组成的组合主键
作业:
一个顾客可能有多张订单
(1)根据订单查找顾客
(2)查找顾客对应的所有的订单
(3)更新顾客信息
(4)添加顾客
(5)添加订单
(6)删除订单
(7)删除顾客
垃圾收集器:Thread
无用对象:被合理分配空间,被应用程序合法占用,却在应用程序中通过任何路径都无法到达.
session 自身具备缓存,称为第一级缓存,用于暂时存放在当前所操作的对象(持久化对象),session的缓存通过一个内部的集合来实现,session会保证缓存中数据和数据库的数据的一致性.
第二级缓存:
(1)Transient:临时状态
对象刚刚被创建好,还没有被hibernate保存
session中没有该对象,数据库中也没有对应的记录
(2)Persisent:持久化状态
被session保存的对象,或被加载等,位于session的缓存中
在数据库中"可以认为"也存在该对象所对应的记录.
(3)Detached:脱管状态,游离状态
被session删除(delete等).在session的缓存中不存在,在数据库中可能不存在.
get()/load()比较:
get()返回object对象 get(className.class,new Long(..))//session里的方法
首先从session的缓存中加载对象,如果session的缓存不存在该对象,将进入hibernate的二级缓存中进行加载,
如果还不存在,将和数据库进行通信进行查找,从数据库加载对象之后,立即对该对象进行初始化,如果从数据库中加
载不成功,将返回null,建议使用时先测试是否加载成功,以免发生空指针异常
load() load(className.class,new Long(..)) 如果缓存中一级缓存和二级缓存中存在要加载的对象,load
()和get()无区别,如果不存在,需要从数据库中加载时,load方法会创建一个代理对象,并且暂时不会对该对象进行
初始化,且直到用户访问的时候才进行初始化.如果从数据库中加载不成功将抛出异常.
建议:如果要保证要加载的对象在数据库中存在,使用load()效率比较高,如果要保证加载的对象在缓存中存在,两种
方法没有区别,如果不保证要加载的对象在数据库中存在建议使用get().
evict():将一个持久化的对象从缓存中删除,不建议使用该方法
update()/lock()比较:
将脱管状态的对象转化为持久化对象
update()会对对象在脱管期间所作的更新执行update(),lock()仅仅是将对象转化为持久化状态,不会对对象在
脱管期间发生的改变作update().
hibernate的批处理:
hibernate.jdbc.batch_size:批处理的数量.
在hibernate.hbm.xml中添加如下属性
(1)hibernate.jdbc.batch_size--->批处理的数量 N
(2)在循环中做
if(i%N==0){
session.flush();//将缓存中的数据强行写入到数据库
session.clear();//清空缓存
}
建议:hibernate做批处理需要占有缓存,为了提高效率只能定时清理缓存,效率底下,建议大量的批处理绕过
hibernate使用JDBC.
第五章 事务,并发
隔离级别设置:
(1)JDBC
获得Connection对象
conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
conn.setTransactionIsolation(int);
(2)hibernate
在表中增加int类型的一列
在pojo类中增加int类型的一个属性
在配置文件中<id>的后面紧跟<version name=" " column=" ">
flush();
session.setFlushMode();设置flush的方式
建议保持在提交的时候自动调用,除非在其他的时候手动的调用。
commit();提交前先调用flush();
(1)第一类丢失更新:
两个事务同时操作更新一条记录,如果一个事务失败回滚,很可能导致另一个成功提交的事务的结果被覆盖。
(2)脏读:
一个事务在操作的时候读到了另一个未提交事务的结果。
(3)不可重复读:
同一事务使用相同方式在不同时点读一条记录,但结果不一样,期间可能有其他的事务对记录作了update
(4)第二类丢失更新:
一个事务对另一个未提交的事务事务的结果作了更改。
(5)幻读:一个执行相同的查询两次,两次得到的结果集不同,可能在两次查询期间有其他事务做了插入或删除等
操作。
导致问题的原因:用户的操作情况--->需求分析
乐观锁:假定在一个事务操作一条记录的时候没有其他事务操作记录
悲观锁:假定在一个事务操作一条记录的时候还存在其他的事务操作记录。
set:无序但不能重复。
一个人有一个文件,文件都不同
不同的人可以有相同的文件。
表达设计
person 表 file 表
------------ --------------
id(pk) name p_id + filename=pk
bag:无序的list,可以还里重复的元素。
一个人可以有多个相同的文件
person 表 file 表
------------ ----------------------
id(pk) name id(pk) p_id filename
list:有序,但可重复
一个人可以有相同的文件,但文件要有序(position)文件的序号,即文件的索引
person 表 file 表
------------ ---------------------------------
id(pk) name p_id + position=pk filename
map:
类的设计:
person{
id
name
Map<String,String> map=new HashMap<String,String>();
}
Person{
id;
name
Address;
}
Address{
city;
street;
}
地址重复的几率很小
配置文件中Person的Address通过下面配置
<component>
<property name="city" column="city" type="string"></property>
</component>
继承的映射:
java:目的:代码的复用
多态:
(1)每一个“具体的类”(不包含interface,abstract class)对应一张表 不支持多态
**(2)每一棵继承关系书对应一张表
(3)没一个类对应一张表(interface,abstract class)
浙公网安备 33010602011771号