基础部分:
ormapping框架:数据库的操作框架
优点
1、比较简单
2、数据缓存:一级缓存 二级缓存 查询缓存
3、移植性比较好
缺点
1、因为sql语句是hibernate内部生成的,所以程序员干预不了,不可控
2、如果数据库特别大,不适合用hibernate
jdbc的优点和缺点
缺点
1、查询代码特别繁琐
2、重复性代码特别多,频繁的try,catch
3、数据的缓存
4、sql的移植性不好
优点
速度比较快
把控性比较好
ormapping:对象关系映射
让关系型数据库和对象发生关联
*.hbm.xml(映射文件)
类与表的对应关系
类上的属性的名称和表中的字段的名称对应关系
类上的属性的类型和表中的字段的类型对应关系
把一对多和多对多的关系转化成面向对象的关系
hibernate的配置文件:
作用是用来连接数据库的
hibernate:
1、hibernate的加载流程
2、crud的操作
3、关系操作 重点
4、hibernate的优化 重点
数据缓存
懒加载
抓取策略
……
5、hql语句
hibernate配置文件两种加载方式
1、该配置文件必须放在classpath下
2、名称必须为hibernate.cfg.xml
hibernate.cfg.xml
1、描述数据库的链接的信息
2、加载映射文件
sessionFactory = configuration.buildSessionFactory();
1、hibernate把数据库的链接信息、把映射文件的信息、持久化类的信息
2、sessionFactory是由单例模式产生的
3、一般情况下一个hibernate应该有一个数据库链接
4、该类本身是线程安全的
5、是一个重量级类
sessionFactory.openSession();
打开了一个数据库的链接,准备进行数据库的操作
cud的操作
开启事务
session.beginTransaction();
进行cud的操作
……
提交事务,关闭session
注意事项:
1、一个类是否是持久化类
1、加载配置文件
2、在配置文件中加载映射文件
3、解析映射文件中class元素的name属性,找到对应的类
2、在客户端的参数的类必须是持久化类
对象的状态:
对象的状态
临时状态
new
持久化状态
get,save,update
脱管状态
clear close evict
关系操作:
多对多
1、关系操作
1、多对多,谁操作效率都一样
2、解除关系
把第三张表的一行数据删除掉
3、建立关系
把第三张表的数据增加一行记录
4、变更关系
先删除后增加
2、级联操作
都是对象针对集合的操作
性能部分:
性能:
发出的sql语句越少,性能越高
方法:
1、懒加载
2、抓取策略
3、缓存策略
4、HQL语句
懒加载
1、类的懒加载
1、利用session.load方法可以产生代理对象
2、在session.load方法执行的时候并不发出sql语句
3、在得到其一般属性的时候发出sql语句
4、只针对一般属性有效,针对标示符属性是无效的
5、默认情况就是懒加载
2、集合的懒加载
false 当session.get时,集合就被加载出来了
true 在遍历集合的时候才加载
extra
针对集合做count,min,max,sum等操作
3、单端关联的懒加载(多对一)
<many-to-one lazy="false/no-proxy/proxy"> no-porxy 默认值 true
根据多的一端加载一的一端,就一个数据,所以无所谓
总结:懒加载主要解决了一个问题:类、集合、many-to-one在时候发出SQL语句,加载数据
抓取策略:
1、研究的主要是set集合如何提取数据
2、在Classes.hbm.xml文件中
<set fetch="join/select/subselect">
join 左外连接
如果把需求分析翻译sql语句,存在子查询,这个时候用该策略不起作用
select 默认
先查询一的一端,再查询多的一端
subselect 子查询
如果需要分析翻译成sql语句存在子查询,这个时候用该策略效率最高
懒加载和抓取策略结合:研究对象是set集合
fetch lazy sql 什么时候发出sql 说明
join false 存在子查询 当查询classes时把
classes和student全部查询出来 这种情况下join没有用
join true 存在子查询 当遍历student时发出查询student join没用
join true 不是子查询 在session.get(classes)时全部查询出来 这时,lazy没有用
subselect true/false 存在子查询 发出两条sql语句 如果lazy为true,在遍历集合,如果lazy为false,在一开始就发出
select true/false 发出n+1条sql 如果lazy为true,在遍历集合,如果lazy为false,在一开始就发出
二级缓存:
二级缓存:存放公有数据
1、适用场合:
1、数据不能频繁更新
2、数据能公开,私密性不是很强
2、hibernate本身并没有提供二级缓存的解决方案
3、二级缓存的实现是依赖于第三方供应商完成的
ehcache
oscache
jbosscache
swamchache
4、二级缓存的操作
1、二级缓存存在sessionFactory中
2、生命周期:与sessionFactory保持一致
3、使用二级缓存的步骤
1、在hibernate.cfg.xml
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
2、让某一个对象进入到二级缓存中
* 在配置文件中
<class-cache usage="read-only" class="cn.itcast.hiberate.sh.domain.Classes"/>
* 在映射文件中
<cache usage="read-only"/>
3、使用
session.get/session.load
5、查询缓存
查询:
hibernate的查询方式
1、hql(hibernate query language) query
2、Criteria query
3、Native query
new source folder
session:
session.getCurrentSession的用法
1、在hibernate的配置文件中:
<property name="current_session_context_class">thread</property>
2、不需要写session.close方法,在事务提交的时候会自动关闭(由hibernate内部完成)
3、crud都需要事务
1、因为是一个线程,所以整个方法中一个session,一个事务
2、保证了整个业务操作的安全性
缓存
1、缓存的生命周期
2、数据库的数据是怎么样放入到缓存中的
3、缓存中的数据是怎么样放入到数据库中的
4、客户端怎么样从缓存中把数据取出来
5、客户端怎么样把一个数据放入到缓存中
6、怎么样把一个对象从缓存中取出
7、把缓存中所有的数据清空
页面缓存
session缓存:
1、生命周期就是session的生命周期
2、一级缓存存放的数据都是私有数据
把session存放在threadlocal中,不同的线程是不能访问的,所以保证了数据的安全性
3、怎么样把数据存放到一级缓存中
利用session.save/update/load/get方法都可以存放在一级缓存中
4、利用session.get/load方法可以把数据从一级缓存中取出
5、session.evict方法可以把一个对象从一级缓存中清空
6、利用session.clear方法可以把session中的所有的数据清空
7、利用session.Refresh方法把数据库中的数据同步到缓存中
8、session.flush
在session的缓存内部,会去检查所有的持久化对象
1、如果一个持久化对象没有ID值,则会发出insert语句
2、如果一个持久化对象有ID值,则会去检查快照进行对比,如果一样,则什么都不做,如果不一样,则发出update语句
3、检查所有的持久化对象是否有关联对象
检查关联对象的级联操作
检查关联对象的关系操作
9、批量操作
权限管理练习:
目标:
根据用户、角色、权限的概念,让用户登录以后获取用户能够访问到的权限,
根据用户的权限去检查有没有对页面上某一个元素的操作的功能
步骤:
1、建立持久化类和映射文件生成相应的表
2、在表中插入测试的数据
3、需求代码的步骤
1、在tomcat服务器启动的时候,执行一个ServletContextListener
把所有的用户和所有的用户能够访问到的权限值全部取出来
技术点:user,role,privilege三张表的多对多的查询 核心表示user:from User
把数据取出来以后可以采用转化成set集合的方式去重复
最后把权限的集合封装成为Map,将来用户登录以后,可以根据用户名很容易得取出权限
2、登录:
1、输入http://localhost:8080/struts_hiberante_access,跳转到登录页面,所以在web.xml中
欢迎页面设置成为login.jsp
2、先跳转到login.jsp
3、提交请求,跳转到LoginAction
1、利用模型驱动获取页面的数据
2、判断用户名和密码是否正确
正确的时候,根据username把该用户能够访问到的权限Set<Privilege>取出来
把Set<Privilege>放入到了session中
4、点击用户管理
用户列表页面,在页面上判断该用户是否有编辑、删除、查看的权限,如果有,才能显示其按钮,如果没有,则不显示
因为在数据库中已经规定了:"user_update"该字符串是编辑的权限
"user_show"该字符串是查看的权限
"user_delete"该字符串有删除的权限
所以得用s:if语句来判断用户的权限有没有这些字符串
5、判断的过程:
1、该用户的权限在session中,利用ognl表达式可以把权限的集合提取出来
<s:iterator value="#session.privilege_session">
2、<s:if test="">中test的内容能够直接跟ognl表达式,所以name可以直接出现在test中
<s:if test="name=='user_show'">