1.注意session.clear()的应用,尤其在不断分页循环的时候
(1)在一个大集合中进行遍历,遍历msg,取出其中的含有敏感字样的对象
(2)另外一种形式的内存泄露 //Java有内存泄露么?语法上没有,但是在写程序时,打开的资源要记得关闭。比如调文件的输出流等,java调用C,C调用window的api,这是就需要进行关闭
2. 1+N问题(由于多的一方的fetch默认为lazy,所以在取多的一方的时候,会带出一的一方)
解决方案:(1)将@manytoone(fetch=FetchType.LAZY)
(2)使用@BatchSize注释:在一的一方的实体类上加:@Entity
@BatchSiez(size=5)
(3)join fetch
3.list_iterate
List-->一下子将数据库中所有的字段取出,且不能够使用session缓存(大多数的情况下使用list已经足够)
iterate-->先取id,如果有需要,再取出相关的字段,且能够使用session缓存
4.一级缓存和二级缓存和查询缓存
(1)一级缓存:session级缓存
(2)二级缓存:sessionFactory级缓存
在主配置文件中hibernate.cfg.xml :
<!-- 使用二级缓存 --> <property name="hibernate.cache.use_second_level_cache">true</property> <!--设置缓存的类型,设置缓存的提供商--> <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mappingResources"> <list> <value>com/lp/ecjtu/model/Employee.hbm.xml</value> <value>com/lp/ecjtu/model/Department.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.OracleDialect hibernate.hbm2ddl.auto=update hibernate.show_sql=true hibernate.format_sql=true hibernate.cache.use_second_level_cache=true hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider hibernate.generate_statistics=true </value> </property> </bean>配置 ehcache.xml:
<?xml version="1.0" encoding="UTF-8"?> <ehcache> <!-- 缓存到硬盘的路径 --> <diskStore path="d:/ehcache"></diskStore> <!-- 默认设置 maxElementsInMemory : 在內存中最大緩存的对象数量。 eternal : 缓存的对象是否永远不变。 timeToIdleSeconds :可以操作对象的时间,最大带在内存中没人操作的时间。 timeToLiveSeconds :缓存中对象的生命周期,时间到后查询数据会从数据库中读取。 overflowToDisk :内存满了,是否要缓存到硬盘。 --> <defaultCache maxElementsInMemory="200" eternal="false" timeToIdleSeconds="50" timeToLiveSeconds="60" overflowToDisk="true"></defaultCache> <!-- 指定缓存的对象。 下面出现的的属性覆盖上面出现的,没出现的继承上面的。 --> <cache name="com.suxiaolei.hibernate.pojos.Order" maxElementsInMemory="200" eternal="false" timeToIdleSeconds="50" timeToLiveSeconds="60" overflowToDisk="true"></cache> </ehcache>
使用二级缓存需要在实体类中加入注解:
需要ehcache-1.2.3.jar包:
还需要 commons_loging1.1.1.jar包
在实体类中通过注解可以配置实用二级缓存:
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
(1) | usage: 给定缓存的并发策略(NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL) |
(2) | region (可选的):缓存范围(默认为类的全限定类名或是集合的全限定角色名) |
(3) | include (可选的):值为all时包括了所有的属性(proterty), 为non-lazy时仅含非延迟属性(默认值为all) |
Load默认使用二级缓存,就是当查一个对象的时候,它先会去二级缓存里面去找,如果找到了就不去数据库中查了。
Iterator默认的也会使用二级缓存,有的话就不去数据库里面查了,不发送select语句了。
List默认的往二级缓存中加数据,假如有一个query,把数据拿出来之后会放到二级缓存,但是执行查询的时候不会到二级缓存中查,会在数据库中查。原因每个query中查询条件不一样。
也可以在需要被缓存的对象中hbm文件中的<class>标签下添加一个<cache>子标签:
<hibernate-mapping> <class name="com.suxiaolei.hibernate.pojos.Order" table="orders"> <cache usage="read-only"/> <id name="id" type="string"> <column name="id"></column> <generator class="uuid"></generator> </id> <property name="orderNumber" column="orderNumber" type="string"></property> <property name="cost" column="cost" type="integer"></property> <many-to-one name="customer" class="com.suxiaolei.hibernate.pojos.Customer" column="customer_id" cascade="save-update"> </many-to-one> </class> </hibernate-mapping>存在一对多的关系,想要在在获取一方的时候将关联的多方缓存起来,需要再集合属性下添加 <cache> 子标签,这里需要将关联的对象的 hbm 文件中必须在存在 <class> 标签下也添加 <cache> 标签,不然 Hibernate 只会缓存 OID 。
<hibernate-mapping> <class name="com.suxiaolei.hibernate.pojos.Customer" table="customer"> <!-- 主键设置 --> <id name="id" type="string"> <column name="id"></column> <generator class="uuid"></generator> </id> <!-- 属性设置 --> <property name="username" column="username" type="string"></property> <property name="balance" column="balance" type="integer"></property> <set name="orders" inverse="true" cascade="all" lazy="false" fetch="join"> <cache usage="read-only"/> <key column="customer_id" ></key> <one-to-many class="com.suxiaolei.hibernate.pojos.Order"/> </set> </class> </hibernate-mapping>
默认情况下,Load()会使用二级缓存,iterator()默认使用二级缓存
list默认会往二级缓存加数据,但是查询的时候不使用
查询缓存:
(1)
<!-- 使用查询缓存 --> <property name="cache.use_query_cache">true</property>(2)
调用Query的.setCachable(true)方法指明使用二级缓存
5.缓存算法
LRU --> Least Recently Used -->最近最少使用
LFU --> Least Frequently Used -->最近不常被使用(命中率高低)
FIFO --> 先进先出
设置:MemoryStoreEvictionPolicy="LRU" (ehcache) ===>在
<cache name="com.suxiaolei.hibernate.pojos.Order" maxElementsInMemory="200" eternal="false" timeToIdleSeconds="50" timeToLiveSeconds="60" overflowToDisk="true"></cache>中的一个参数