HibenateMinute(三)

hiberate 一般而言,ORM的数据包含如下几个

1.       事务级缓存(Transcation Layer Cache)

2.       应用级/进程级缓存(Application/Process Layer Cache)

3.        分布式缓存(Cluster Layer Cache)

Hibernate数据缓存(Cache)分为两个层次,以Hibernate语义加以区分,

可分为:

1.       内部缓存(Session Level,也称为一级缓存)

2.       二级缓存(SessionFactory Level,也称为二级缓存)

Hibernate中,缓存将在以下情况中发挥作用:

1.       通过id[主键]加载数据时每个实体唯一的OID

2.       延迟加载

 

@ Cache缓存:

1.        Session level (一级缓存):

         主要作用于:主键获得的数据, 延迟初始化(Lazy Initialization)起作用.

         状态依赖于:Session的建立而建立(销毁而销毁).// Session是个Map容器!

         清除Session对象:  Session.Save()也是交给Session level来管理,很多的时候会发生OutOfMemoryError异常,所以要及时发送给数据库session.flush(),清除session.clear()或session.evict(user1);

        SQL ServerOracle, Hibernat定属性hibernate.jdbc.batch_size多少数据发送

 <hibernate-configuration> <session-factory>

<property name="hibernate.jdbc.batch_size">100

</property> // MySQL是不支持的,

</session-factory>

<hibernate-configuration>

 

2.     SessionFactory level(二级缓存)

       二级缓存是SessionFactory级别的全局缓存, 是进程范围或者集群范围的缓存, 存放的对象的松散数据,可能出现并发问题, 需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别。缓存适配器用于把具体的缓存实现软件与Hibernate集成。第二级缓存是可选的,可以在每个类或每个集合的粒度上配置第二级缓存。

           可以使用不同的缓存类库,比如ehcache、oscache等,需要设置hibernate.cache.provider_class,之后,需要在映射文件中指定各个映射实体(以及collection)的缓存同步策略。Hibernate提供了一下4种内置的缓存同步策略:
      1. read-only
         只读。对于不会发生改变的数据,可使用只读型缓存。
      2. nonstrict-read-write
         如果程序对并发访问下的数据同步要求不是非常严格,且数据更新操作频率较低,可以采用本选项,获得较好的性能。
      3. read-write
         严格可读写缓存。基于时间戳判定机制,实现了“read committed”事务隔离等级。可用于对数据同步要求严格的情况,但不支持分布式缓存。这也是实际应用中使用最多的同步策略。
      4. transactional
         事务型缓存,必须运行在JTA事务环境中。

如果使用查询缓存,加上hibernate.cache.use_query_cache=true,只有当经常使用同样的参数进行查询时,这才会有些用处。该设置将会创建两个缓存区域 - 一个用于保存查询结果集(org.hibernate.cache.StandardQueryCache); 另一个则用于保存最近查询的一系列表的时间戳(org.hibernate.cache.UpdateTimestampsCache)。 请注意:在查询缓存中,它并不缓存结果集中所包含的实体的确切状态;它只缓存这些实体的标识符属性的值、以及各值类型的结果。 所以查询缓存通常会和二级缓存一起使用。 绝大多数的查询并不能从查询缓存中受益,所以Hibernate默认是不进行查询缓存的。如若需要进行缓存,请调用 Query.setCacheable(true)方法。这个调用会让查询在执行过程中时先从缓存中查找结果, 并将自己的结果集放到缓存中去。

Hibernate的二级缓存策略的一般程如下:

 

1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。

2) 把获得的所有数据对象根据ID放入到第二级缓存中。

3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。

4) 删除、更新、增加数据的时候,同时更新缓存。

  Hibernate的二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query缓存。

 

HibernateQuery存策略的程如下:

 

1) Hibernate首先根据些信息成一个Query KeyQuery Key包括条件查询求一般信息:SQL, SQL需要的参数,记录(起始位置rowStart,最大记录个数maxRows),等。

2) Hibernate根据Query Key到Query存中对应果列表。如果存在,那返回果列表;如果不存在,查询数据果列表,把整个果列表根据Query Key放入到Query存中。

3) Query Key中的SQL及到一些表名,如果些表的任何数据生修改、除、增加等操作,些相Query Key都要从存中清空。

 

么样的数据适合存放到第二级缓存中?

1 很少被修改的数据

2 不是很重要的数据,允的数据

3 不会被并发访问的数据

4 参考数据

不适合存放到第二级缓存的数据?

1 常被修改的数据

2 财务数据,绝对不允

3 与其他用共享的数据

,当save()、update()或 saveOrUpdate()方法传递一个,或使用load()、 get()、list()、iterate() 或scroll()方法得一个, 该对象都将被加入到Session的内部存中。

当随后flush()方法被象的状会和数据取得同。 如果你不希望此同操作生,或者你正理大量象、需要有效管理内存,你可以evict() 方法,从一级缓存中去掉象及其集合。如若要把所有的象从session存中底清除,需要Session.clear(),不最好先Session.flush()

SessionFactory也提供了移除存的方法,些方法是:
sessionFactory.evict(Cat.class, catId); //evict a particular Cat
sessionFactory.evict(Cat.class);  //evict all Cats
sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections

 

于事物管理的确定:

 hibernate.cfg.xml :

   <hibernate-configuration>

    <session-factory>

        ....

        <!-- 設定事務管理的工廠類 -->
        <property name="hibernate.transaction.factory_class">

            org.hibernate.transaction.JDBCTransactionFactory  </property>

</hibernate-configuration>

try {

    session = sessionFactory.openSession();  

    Transaction tx = session.beginTransaction();

    ....

    tx.commit();  // 必須commit才會更新資料庫

} catch(HibernateException e) {

    tx.rollback();

}

Postil: 对于MySQL处理机制要建立事物表类型的

类型的对照表:

Java

Hibernate

SQL

byte、java.lang.Byte

byte

TINYINT

short、java.lang.Short

short

SMALLINT

int、java.lang.Integer

integer

INGEGER

long、java.lang.Long

long

BIGINT

float、java.lang.Float

float

FLOAT

double、java.lang.Double

double

DOUBLE

java.math.BigDecimal

big_decimal

NUMERIC

char、java.lang.Character

character

CHAR(1)

boolean、java.lang.Boolean

boolean

BIT

java.lang.String

string

VARCHAR

boolean、java.lang.Boolean

yes_no

CHAR(1)('Y'或'N')

boolean、java.lang.Boolean

true_false

CHAR(1)('Y'或'N')

java.util.Date、java.sql.Date

date

DATE

java.util.Date、java.sql.Time

time

TIME

java.util.Date、java.sql.Timestamp

timestamp

TIMESTAMP

java.util.Calendar

calendar

TIMESTAMP

java.util.Calendar

calendar_date

DATE

byte[]

binary

VARBINARY、BLOB

java.lang.String

text

CLOB

java.io.Serializable

serializable

VARBINARY、BLOB

java.sql.Clob

clob

CLOB

java.sql.Blob

blob

BLOB

java.lang.Class

class

VARCHAR

java.util.Locale

locale

VARCHAR

java.util.TimeZone

timezone

VARCHAR

java.util.Currency

currency

VARCHAR

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值