hibernate3(6)
2015-09-13 16:37
162 查看
1.二级缓存:SessionFactory
:在hibernate中默认关闭,且是需要手动安装。
:EhCache 独立的缓存组件
===============================================================================================
2.二级缓存使用:导入Ehcache依赖
2.1在hibernate中开启二级缓存
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 指定二级缓存的类别,添加provider -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
2.2在之后的所有操作(save,update,get,load,query)的数据,均会被存储到二级缓存中(SessionFactory)
存储规格{ID:Object};同样只有通过ID为条件的查询,才可以使用二级缓存中的数据:
get,load,iterate
2.3一级缓存时默认使用在所有的实体上,二级缓存是要在实体的映射中添加标记,二级缓存才会在此实体
被操作时,将其纳入缓存。
<class name="User" table="t_user35">
<!-- 进入二级缓存设置 -->
<cache usage="read-only"/>
<id name="id" column="id" type="java.lang.Integer">
<!-- id生成器(生成策略),保证在插入数据时id唯一
increment:递增策略
-->
<generator class="increment"></generator>
</id>
...
</class>
2.4缓存操作
/缓存操作
//Cache cache=HUtil.getSessionFactory().getCache();
//cache.evictEntityRegion(User.class);//将User的缓存移出
2.5缓存的:read-only read-write
只读 读写
*如果将实体的缓存属性设置成read-only的,则缓存的数据不允许有任何的修改
*read-write相反
=============================================================================================
3.延迟加载(查询时):当查询数据时,hibernate不会立即查询其中的某些属性,而是延迟,直到事务内
确实使用了该属性,才去查询。
*关系属性的延迟:
当查询User时,其中的关系属性不会被立即查询,而是一直到此关系属性真正被使用了,才会去
查询此关系属性
*细节:
1.并不是所有的关系属性都会被延迟加载
2.被<one-to-one>映射的关系属性,会别立即加载
3.但是如果<one-to-one>中有constrained="true" 也会被延迟加载
4.总结:
*1:1共享主键的主表方的关系属性 立即查询
*1:1唯一外键的主表方的关系属性 立即查询
*普通属性的延迟:
session.get(Class,ID);
session.load(Class,ID);
*load()方法在查询时会延迟普通属性的加载。
如果在事务内部没有使用普通属性,则不会去加载
*延迟加载异常:
在事务外部,初次使用了被延迟的属性。则会因为事务提交session关闭,而无法再查询,而跑出
org.hibernate.LazyInitializationException
*解决方案:
1.关闭hibernate的延迟加载属性
关闭了普通属性的延迟加载:<class name="Student" table="t_student35" lazy="false">
关闭关系属性的延迟加载:
<set lazy="false" name="orders" cascade="save-update,delete" inverse="true">
<!-- 映射关系中的外键的 -->
<key column="user_id"></key>
<one-to-many class="Order"/>
</set>
2.Action Service DAO
User user=get(User.class,1);
user.getOrders.size();
User
User
JSP:User Orders
3.OpenSessionInView :spring
=============================================================================================
4.连接池(数据库连接池):dbcp c3p0 proxool ...
4.1 导依赖并在配置文件中添加连接池相关配置
<!-- 连接池相关配置 -->
<!-- 池中最少有持有的连接数 -->
<property name="hibernate.c3p0.min_size">1</property>
<!-- 池中最多存放的连接数 -->
<property name="hibernate.c3p0.max_size">3</property>
<!-- 当连接不够用时,添加个数 -->
<property name="hibernate.c3p0.acquire_increment">1</property>
<!-- 连接获取超时 时间 毫秒-->
<property name="checkoutTimeout">2000</property>
<!-- 指定连接池种类 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
4.2 在配置连接池后,当再次获取Session时,其中需要的Connection就是连接池中获取的
=============================================================================================
5.锁
t_user35
id name age
1 c35 18
...
tx1:t_user35 age++
1>select age from t_user35 where id=1;
age35=18;
3>update t_user35 set age=(age35+1) where id=1;
commit;
tx2: t_user35 age++
2>select age from t_user35 where id=1;
age35=18;
4>update t_user35 set age=(age35+1) where id=1;
commit;
*悲观锁
tx1:t_user35 age++
1>select age from t_user35 where id=1 for update;
age35=18;
3>update t_user35 set age=(age35+1) where id=1;
commit;
tx2: t_user35 age++
2>select age from t_user35 where id=1 for update;
等待事务1提交
age35=19;
4>update t_user35 set age=(age35+1) where id=1;
commit;
*乐观锁:
t_user35
id name age version
1 c35 18 0
...
tx1:t_user35 age++
1>select age,version35 from t_user35 where id=1;
age35=18;
version35=0;
3>update t_user35 set age=(age35+1),version35=(version35+1)
where id=1 and version=version35;
commit;
tx2: t_user35 age++
2>select age,version35 from t_user35 where id=1;
age35=18;
version35=0;
4>update t_user35 set age=(age35+1),version35=(version35+1)
where id=1 and version=version35;
commit;
*为查询加锁,是为了防止【更新丢失】
*hibernate中如何使用锁
*使用悲观锁:
User user=(User)session1.get(User.class,2,LockOptions.UPGRADE);
*使用乐观锁:
create table lglock(
id number(5) primary key,
name varchar2(20),
version35 number(4)
);
<class name="LGLock" table="lglock">
<id name="id" column="id" type="java.lang.Integer">
<!-- id生成器(生成策略),保证在插入数据时id唯一
increment:递增策略
-->
<generator class="increment"></generator>
</id>
<!-- 映射version列 -->
<version name="version35" type="java.lang.Integer"></version>
<property name="name" type="java.lang.String"></property>
</class>
=============================================================================================
6.对象状态
1.持久化对象:在数据库有对应数据,且在session中有对应的缓存
User user=(User)session.get(User.class,1);
sesssion.evict(user);
session.close();
在脏数据监测时,hibernate只检测持久化的对象。
2.托管对象(游离):在数据库有对应数据,但在session中没有对应的缓存
Action Service DAO
tx
User user=(User)session.get(User.class,1);
user
tx.commit;
user
JSP:user
3.临时对象:在数据库没有对应数据,且session中没有对应缓存
User user=new User(1,"c35",18);
=============================================================================================
7.分页支持:
String hql="from User";
Query query=session1.createQuery(hql);
int pageSize=2;//每页展示行数
int pageNum=1;//展示的页号
//分页支持
query.setMaxResults(pageSize);//一共要查询多少条
query.setFirstResult((pageNum-1)*pageSize);//从第几条查起,从0开始
List<User> users=query.list();
=============================================================================================
:在hibernate中默认关闭,且是需要手动安装。
:EhCache 独立的缓存组件
===============================================================================================
2.二级缓存使用:导入Ehcache依赖
2.1在hibernate中开启二级缓存
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 指定二级缓存的类别,添加provider -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
2.2在之后的所有操作(save,update,get,load,query)的数据,均会被存储到二级缓存中(SessionFactory)
存储规格{ID:Object};同样只有通过ID为条件的查询,才可以使用二级缓存中的数据:
get,load,iterate
2.3一级缓存时默认使用在所有的实体上,二级缓存是要在实体的映射中添加标记,二级缓存才会在此实体
被操作时,将其纳入缓存。
<class name="User" table="t_user35">
<!-- 进入二级缓存设置 -->
<cache usage="read-only"/>
<id name="id" column="id" type="java.lang.Integer">
<!-- id生成器(生成策略),保证在插入数据时id唯一
increment:递增策略
-->
<generator class="increment"></generator>
</id>
...
</class>
2.4缓存操作
/缓存操作
//Cache cache=HUtil.getSessionFactory().getCache();
//cache.evictEntityRegion(User.class);//将User的缓存移出
2.5缓存的:read-only read-write
只读 读写
*如果将实体的缓存属性设置成read-only的,则缓存的数据不允许有任何的修改
*read-write相反
=============================================================================================
3.延迟加载(查询时):当查询数据时,hibernate不会立即查询其中的某些属性,而是延迟,直到事务内
确实使用了该属性,才去查询。
*关系属性的延迟:
当查询User时,其中的关系属性不会被立即查询,而是一直到此关系属性真正被使用了,才会去
查询此关系属性
*细节:
1.并不是所有的关系属性都会被延迟加载
2.被<one-to-one>映射的关系属性,会别立即加载
3.但是如果<one-to-one>中有constrained="true" 也会被延迟加载
4.总结:
*1:1共享主键的主表方的关系属性 立即查询
*1:1唯一外键的主表方的关系属性 立即查询
*普通属性的延迟:
session.get(Class,ID);
session.load(Class,ID);
*load()方法在查询时会延迟普通属性的加载。
如果在事务内部没有使用普通属性,则不会去加载
*延迟加载异常:
在事务外部,初次使用了被延迟的属性。则会因为事务提交session关闭,而无法再查询,而跑出
org.hibernate.LazyInitializationException
*解决方案:
1.关闭hibernate的延迟加载属性
关闭了普通属性的延迟加载:<class name="Student" table="t_student35" lazy="false">
关闭关系属性的延迟加载:
<set lazy="false" name="orders" cascade="save-update,delete" inverse="true">
<!-- 映射关系中的外键的 -->
<key column="user_id"></key>
<one-to-many class="Order"/>
</set>
2.Action Service DAO
User user=get(User.class,1);
user.getOrders.size();
User
User
JSP:User Orders
3.OpenSessionInView :spring
=============================================================================================
4.连接池(数据库连接池):dbcp c3p0 proxool ...
4.1 导依赖并在配置文件中添加连接池相关配置
<!-- 连接池相关配置 -->
<!-- 池中最少有持有的连接数 -->
<property name="hibernate.c3p0.min_size">1</property>
<!-- 池中最多存放的连接数 -->
<property name="hibernate.c3p0.max_size">3</property>
<!-- 当连接不够用时,添加个数 -->
<property name="hibernate.c3p0.acquire_increment">1</property>
<!-- 连接获取超时 时间 毫秒-->
<property name="checkoutTimeout">2000</property>
<!-- 指定连接池种类 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
4.2 在配置连接池后,当再次获取Session时,其中需要的Connection就是连接池中获取的
=============================================================================================
5.锁
t_user35
id name age
1 c35 18
...
tx1:t_user35 age++
1>select age from t_user35 where id=1;
age35=18;
3>update t_user35 set age=(age35+1) where id=1;
commit;
tx2: t_user35 age++
2>select age from t_user35 where id=1;
age35=18;
4>update t_user35 set age=(age35+1) where id=1;
commit;
*悲观锁
tx1:t_user35 age++
1>select age from t_user35 where id=1 for update;
age35=18;
3>update t_user35 set age=(age35+1) where id=1;
commit;
tx2: t_user35 age++
2>select age from t_user35 where id=1 for update;
等待事务1提交
age35=19;
4>update t_user35 set age=(age35+1) where id=1;
commit;
*乐观锁:
t_user35
id name age version
1 c35 18 0
...
tx1:t_user35 age++
1>select age,version35 from t_user35 where id=1;
age35=18;
version35=0;
3>update t_user35 set age=(age35+1),version35=(version35+1)
where id=1 and version=version35;
commit;
tx2: t_user35 age++
2>select age,version35 from t_user35 where id=1;
age35=18;
version35=0;
4>update t_user35 set age=(age35+1),version35=(version35+1)
where id=1 and version=version35;
commit;
*为查询加锁,是为了防止【更新丢失】
*hibernate中如何使用锁
*使用悲观锁:
User user=(User)session1.get(User.class,2,LockOptions.UPGRADE);
*使用乐观锁:
create table lglock(
id number(5) primary key,
name varchar2(20),
version35 number(4)
);
<class name="LGLock" table="lglock">
<id name="id" column="id" type="java.lang.Integer">
<!-- id生成器(生成策略),保证在插入数据时id唯一
increment:递增策略
-->
<generator class="increment"></generator>
</id>
<!-- 映射version列 -->
<version name="version35" type="java.lang.Integer"></version>
<property name="name" type="java.lang.String"></property>
</class>
=============================================================================================
6.对象状态
1.持久化对象:在数据库有对应数据,且在session中有对应的缓存
User user=(User)session.get(User.class,1);
sesssion.evict(user);
session.close();
在脏数据监测时,hibernate只检测持久化的对象。
2.托管对象(游离):在数据库有对应数据,但在session中没有对应的缓存
Action Service DAO
tx
User user=(User)session.get(User.class,1);
user
tx.commit;
user
JSP:user
3.临时对象:在数据库没有对应数据,且session中没有对应缓存
User user=new User(1,"c35",18);
=============================================================================================
7.分页支持:
String hql="from User";
Query query=session1.createQuery(hql);
int pageSize=2;//每页展示行数
int pageNum=1;//展示的页号
//分页支持
query.setMaxResults(pageSize);//一共要查询多少条
query.setFirstResult((pageNum-1)*pageSize);//从第几条查起,从0开始
List<User> users=query.list();
=============================================================================================
相关文章推荐
- 使用过滤器做页面静态化处理
- .hpp与.h的区别
- 利用python,简单的词语纠错
- iOS 静态库开发
- Spring MVC ResourceBundleViewResolver example
- 上转型对象
- leetcode Evaluate Reverse Polish Notation
- hibernate3(5)
- uva 10129
- 交叉环境下,配置ffmpeg的configure时指定交叉编译参数
- Single Number III
- hdu 3966 树链分割第一3遍
- 使用 CSS 媒体查询创建响应式网站
- 3d相册弹出效果02
- [原]MySQL哈希之哈希索引
- 中间件简介
- aix参考
- Python二分查找详解
- HTML基本语言规则
- HDU 5446 Unknown Treasure (2015年长春赛区网络赛J题)