Hibernate笔记.docx

上传人:b****5 文档编号:29744977 上传时间:2023-07-26 格式:DOCX 页数:20 大小:136.47KB
下载 相关 举报
Hibernate笔记.docx_第1页
第1页 / 共20页
Hibernate笔记.docx_第2页
第2页 / 共20页
Hibernate笔记.docx_第3页
第3页 / 共20页
Hibernate笔记.docx_第4页
第4页 / 共20页
Hibernate笔记.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

Hibernate笔记.docx

《Hibernate笔记.docx》由会员分享,可在线阅读,更多相关《Hibernate笔记.docx(20页珍藏版)》请在冰豆网上搜索。

Hibernate笔记.docx

Hibernate笔记

1.当Hibernate持久化一个临时对象时,在默认的情况下,它不会自动持久化所关联的其它临时的对象。

如果希望它那些做,则要设置cascade为”save-update”或”all”,默认值为”node”。

2.

在多的一端加入一个外键指向一的一端,它维护的关系是多指向一。

在多的一端加入一个外键指向一的一端,它维护的关系是一指向多。

这两种映射的数据库表的结构是一样的,所以同时用这两种标签来映射的时候,注意要把这两个标签的column设置为一样。

如:

一:

多:

3.Inverse:

是关联关系的控制方向,它的默认值为false。

在双向关联的情况下,当把两个尚没有关系的但已持久化的对象,建立双向关联,当保存时Hibernate会自己动清理缓存中的所有持久化对象,按照持久化对象状态的改变来同步更新数据库,由于上面两个对象都有改变,所以hibernate会发出两条SQL更新语句,但实际上,只是修改了一条记录,相当于操作多一条无用的SQL语句(这两条语句并不相同,但总的效果只相当于多一端变化时所操作的语句),这会影响性能。

解决方法:

元素的inverse属性设为true。

结论:

1)在映射一对多的双向关联关系时,应在一一端的映射配置文件中,把的inverse属性设为true。

2)在建立两个对象的双向关联时,应同时修改关联两端的对象的相应属性。

4.父子关系:

是指由父方来控制子方的持久化生命周期,子方对象必须和一个父方对象关联。

如果删除父方对象,应该级联删除所有关联的子方对象,如果一个子方对象不再和一个父方对象关联,应该把这个子方对象删除。

存在这种关系时,就可以把父方的cascade属性设为”all-delete-orphan”。

对于Customer中元素的cascade属性设为”all-delete-orphan”时,hibernate处理:

1)当保存或更新Customer对象时,级联保存或更新所有关联的Order对象,相当于cascade属性为”save-update”情形。

2)当删除Customer对象时,级联删除所有关联的Order对象,相当于cascade属性为”delete”的情形。

3)删除不再和Customer对象关联的所有Order对象。

5.Cascade级联的值有:

save-update、delete、all-delete-orphan和none。

操纵持久化对象:

1.Session具有一个缓存,位于缓存中的对象处于持久化状态,它和数据库中的相关记录对应,Session能够在某些时间点,按照缓存中持久化对象属性变化来同步更新数据库,这一过程被称为清理缓存。

2.当Session加载了一个对象时,它会为这个对象的值类型的属性复制一份快照。

当Session清理缓存时,通过比较对象的当前属性与它的快照,Session能够判断Customer对象的哪些属性发生了变化。

3.Session的缓存的两大作用:

1)减少访问数据库的频率。

先查缓存,没有再发SQL语句从数据库中读取。

还有,当缓存的数据发生改变时,Session并不会立即执行相关的SQL语句,这使得Session能够把几条相关的SQL语句合并为一条SQL语句,以便减少访问数据库的次数。

2)保证缓存中的对象与数据库中的相关记录保持同步(并不是实时同步)。

3)Session在清理缓存时,会按照一定的顺序去执行,来避免循环关联死循环。

4.在默认情况下,Session清理缓存的时间点。

1)当应用程序调用commit()方法的时候,commit()会先清理缓存,然后再调向数据库提交事务。

2)当应用程序调用Session的find()或者iterate()时,如果缓存中持久化对象的属性发生了变化,就会先清理缓存,以保证查询结果能反映持久化对象的最新状态。

3)当应用程序显式调用Session的flush()方法的时候。

4)如果对象使用native生成器来生成OID,那么当调用Session的save()保存该对象时,会立即执行向数据库插入该实体的insert语句。

Session的SetFlushModel()方法用于设定清理缓存的时间点:

清理缓存的模式session的查询|commit()|fush()

FlushMode.AUTO清理|清理|清理

FlushMode.COMMIT不清理|清理|清理

FlushMode.NEVER不清理|不清理|清理

其中利用FlushMode.NERVER模式,在大批量查询中,但只修改少数数据的情况下,能显著提高效率。

AUTO默认值,这也是优先考虑的清理模式,它会保证在整个事务当中,数据保持一致。

如果事务仅包含查询数据库的操作,而不会修改数据库的数据,也可以选项用COMMIT模式,这样可以避免在执行Session的查询方法时先清理缓存,以提高应用程序的性能。

大多情况下不需要显式调用flush()方法,flush()方法适用于以下情况:

1)插入、删除或更新某个持久化对象会引发数据库中的触发器。

2)在应用程序中混合使用HiberanteAPI和JDBCAPI。

3)JDBC驱动程序不健壮,导致Hibernate在自动清理缓存有模式下无法正常工作。

5.Hiberante中java对象的状态:

临时状态:

刚刚用new语句创建,还没有被持久化,不处于Session缓存中。

持久化状态:

已经被持久化,加入到Session的缓存中。

游离状态:

已经被持久化,但不再处于Session的缓存中。

注:

持久化类与持久化对象是不同的概念。

持久化类的实例可以处于临时状态,持久化状态和游离状态,其中处于持久化状态的实例被称为持久化对象。

6.临时对象的特征:

1)不处于Session的缓存中,也可以说不被任何一个Session实例关联。

2)在数据库中没有对应的记录。

持久化对象的特征:

1)位于一个Session实例缓存中,也可以说持久化对象总是被一个Session实例关联。

2)持久化对象和数据库中的相关记录对应。

3)Session在清理缓存时,会根据持久化对象的变化,来同步更新数据库。

游离对象的特征:

1)不再位于Session的缓存中,也可以说,游离对象不被Session关联。

2)游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录。

注:

当讨论对象的状态时,不要把它和数据库的记录对不对应纠缠起来,只要清楚它是否在Session的缓存中就可。

并和清理缓存的时间点结合起来考虑,来设计程序。

7.对象状态的转换图:

8.Session的save()方法是用来持久化一个临时对象的。

在应用程序中不应该把持久化对象或游离对象传给save()方法。

9.Hibernate通过持久化对象的OID来维持它的数据库相亲的记录的对应关系,当对象处于持久化状态时,不允许程序随意修改它的OID值,否则抛异常。

其实无论对象处于什么状态,程序都不应该修改它的OID值。

10.Save()是由(Hiberante或数据库)自动分配ID的,就算原来对象已有ID值,也没用。

而Update()要自己提供id的值才可。

所以不应把持久化对象或游离对象传给save()方法。

11.如果缓存中已经存在相同OID的持久化对象时,再想用Update()将一个游离对象持久化,这时就会报异常。

还有,当update()方法关联一个游离对象时,如查在数据库中不存在相应的记录,也会抛异常。

12.Session的saveOrUpdate()方法:

1)如果传入的是临时对象就调用save()方法。

2)如果传入的是游离对象就调用update()方法。

3)如果传入的是持久化对象就直接返回。

Hibernate把它当作一个临时对象的情况:

1)Java对象的OID取值为NULL。

或者OID的值与映射文件中元素的unsaved-value的属性值一致。

2)Java对象具有version属性并且取值为NULL,或者version的值与映射文件中元素的unsave-value属性值一致。

3)自定义了Hibernate的Interceptor实现类,并且interceptor的isUnsaved()方法返回true时。

13.Session中的load()和ger()方法:

都是根据给定的OID从数据中加载一个持久化对象,这两个方法的区别在于:

当数据库中不存在与OID对应的记录时,load()方法会抛出异常,而get()返回NULL值。

由ge()、load()或其它查询方法返回的对象都位于当前的Session缓存中,因此接下来修改了持久化对象的属性后,当Session清理缓存时,会根据持久化对象的属性变化来同步更新数据库。

14.Session的delete()方法:

1)如果传入的是持久化对象,Session就计划执行一个delete语句。

2)如果传入的是游离对象,先使游离对象被Session关联使之变为持久化对象,然后计划执行一个delete语句。

3)在清理缓存时,才执行delete语句(更新数据库),但此时还没有把它从缓存中删除掉,只有在Session.close()时才把它从缓存中删除。

15.在使用级联时要小心,因为级联时都会根据配置,来更新所关联的对象,如果该对象不在内存中,hibernate则会发update语句去更新(即使它从来就没有修改过任何属性值),这样就会执行很多无用的update语句。

设置时最好把元素的cascade属性设为”save-update”,而在中设置cascade属性设为”none”。

16.当数据库与触发器协同工作时,会造成以下两种问题:

1)触发器使Session的缓存中的数据与数据库不一致。

原因:

触发器对数据库数据的修改不会反应到Session中。

解决:

在程序中先save()再flush()最后refersh()

2)Session的update()方法盲目地激发数据库。

原因:

当hibernate把用update()或saveOrUpdate()把一个游离对象重新和Session关联时,不管游离对象是属性是否和数据库的数据一致与否,都会发出一条update语句。

解决:

这样在把一个游离对象重新和Session关联时,hibernate先发一条select语句,当不一样时再发update语句。

17.为Session设置拦截器(Interceptor)。

(此法要每个实体类实现Auditable接口,太不方便了,不利于移用,虽然Auditabler接口很简单,但建议少用)

1)SessionFactory.openSession(Interceptor)Session范围内有效。

2)Configuration.setInterceptor(Interceptor)SessionFactory范围内有效。

Interceptor接口:

查API。

但使用这种方法时,每个实体要实现Auditable接口:

PublicinterfaceAuditable{

PublicLonggetId();

}

 

映射组成关系:

1.建立域模型和关系数据模型有着不同的出发点。

域模型:

是由程序代码组成,通过细化持久化类的粒度可提高代码可重用性,简化编程。

关系数据模型:

是由关系数据组成的,在存在数据冗余的情况直,需要把粗粒度的表拆分成具有外键参照关系的几个细粒度的表,从而节省空间;当在没有数据冗余的前提下,应该尽可能减少表的数目,简化表之间的参照关系,以便提高访问数据库的速度。

2.区分值类型和实体类型:

值类型:

没有OID,不能够被单独持久化,它的生命周期依赖于所属的持久化类对象的生命周期,组件类型就是一种值类型。

在数据库中没有相对应的表。

实体类型:

有OID,可以被单持久化。

3.组成映射:

4.复合组成映射:

Hibernate的映射类型:

1.Hibernate映射类型分两种:

1)内置映射类型:

内置映射类型负责把一些常见的Java类型映射到相应的SQL类型。

2)客户化映射类型:

允许用户实现UserType或CompositeUserType接口,来灵活地用户自定义的JAVA类型映射到数据库表的相应字段。

2.Hibernate映射类型与java对应表:

映射类型          java 类型               标准 sql 类型  

integer      int or Integer            INTEGER  

long            long or java.lang.Long    BIGINT  

short           short or java.lang.Short  SMALLINT  

float           float or java.lang.Float  FLOAT  

double          double or java.lang.Double DOUBLE  

big_decimal     java.math.BigDecimal       NUMERIC  

character       java.lang.String           CHAR

(1)  

string          java.lang.String           VARCHAR  

byte            byte or java.lang.Byte     TINYINT  

boolean         boolean or java.lang.Boolean BIT  

yes_no          boolean or java.lang.Boolean CHAR

(1)('Y' or 'N')  

true_false      boolean or java.lang.Boolean CHAR

(1)('Y' or 'N') 

date            java.util.Date or java.sql.Date  DATE(YYY-MM-DD) 

time            java.util.Date or java.sql.Time  TIME(HH:

MM:

SS)

timestamp       java.util.Date or java.sql.Timestamp TIMESTAMP(全)

calendar        java.util.Calendar            TIMESTAMP(全)

calendar_date   java.util.Calendar            DATE(YYYY-MM-DD)   

class           java.lang.Class             VARCHAR  

locale          java.util.Locale            VARCHAR  

timezone        java.util.TimeZone          VARCHAR  

currency        java.util.Currency          VARCHAR  

binary          byte[]                      VARBINARY(BLOBBLOB)

text            java.lang.String            CLOB(TEXTCLOB)

serializable    java.io.Serializable        VARBINARY(BLOB BLOB)

clob            java.sql.Clob               CLOB(TEXTCLOB)

blob            java.sql.Blob               BLOB(BLOBBLOB) 

3.自定义的映射映射类型:

必须要实现UserType接口。

1)定义数据库的类型:

Privatestaticfinalint[]SQL_TYOES={Types.VARCHAR}//java.sql.Types

Publicint[]sqlTypes(){returnSQL_TYPES;}

2)定义java代码的类型:

PublicClassreturnedClass(){returnInterger.class;}

3)定义java代码的类是否为可变类,不可变则返回false;Hibernate在处理不可变类型时会采用一些性能上的优化。

PublicBooleanisMutable(){returnfalse;}

4)Hibernate调用deepCopy(Objectvalue)方法来生成java类型的快照。

PublicObjectdeepCopy(Objectvalue){returnvalue;}

5)Hibernate调用equals(Objectx,Objecty)方法比较java类的值是否和它的快照相同。

PublicBooleanequals(Objectx,Objecty)

6)Hibernate调nullSafeGet()方法:

数据库类型java代码类型

resultSet为JDBC查询结果集;name存放表字段名;owner为phone的宿主Customer。

PublicObjectnullSafeGet(ResultSetresultSet,String[]name,Objectowner)throwsHibernateException,SQLException{

If(resultSet.wasNull())returnnull;

Stringphone=resultSet.getString(name[o]);

ReturnnewInteger(phone);

}

7)Hibernate调用nullSafeSet()方法:

java代码类型数据库类型

PublicvoidnullSafeSet(PreparedStatementstatement,Objectvalue,intindex)throwHibernateException,SQLException{

If(value==null){

Statement.setNull(index,Types.VAECHAR);

}else{

Stringphone=((Integer)Value).toString();

Statement.setString(index,phone);

}

}

8)配置类的映射文件:

Hibernate的检索策略:

1.类级别和关联级别可选的检索策略(注:

这是hibernate2默认值,hibernate3的不同)

2.

3.Outer-join:

为了减少关联级别的立即检索时发出的SQL语句数量。

Batch-size:

对Outer-join不起作用,只减少了立即和延迟检索时发出SQL语句数量。

4.设置多对一关联的检索策略:

(类级别的选值)

5.类级别时,检索策略只对Load()方法影响。

关联级别的立即和延迟策略对所有方法都有影响,但关联级别的outer-join策略不对查询方法产生影响,这将会用立即策略。

6.几种策略优缺点的比较:

Hibernate的检索方式:

1.Hibernate提供以下几种检索方式:

1)导航对象图检方式:

根据已经加载的对象,导航到其他对象。

2)OID检索方式:

按照对象的OID来检索对象。

Get()和load()方法。

3)HQL检索方式:

使用面向对象的HQL查询语言。

createQuery()创建Query接口查询。

4)QBC检索方式:

使用QBCAPI来检索对象。

Criteria和Criterion接口,Expression类。

5)本地SQL检索方式:

使用本地数据库的SQL查询语句。

createSQLQuery()创建Query。

Hibernate事务:

1.使用Hibernate开发时,最好采用以下方式:

1)设置数据库的隔离级别为ReadCommitted:

Properties设置:

hibernate.connection.isolation=2

XML设置:

2

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1