hibernatetemplate局限性? 什么样需求的系统不适合用hibernatetemplate?

使用Hibernate开发租房系统_中华文本库
第1页/共4页
Oracle结构
服务器进程
数据库读写&DBWR&
日志&LGWR&
程序监视器&PMON&
程序统计器&SMON&
内存结构&300MB&
系统全局区&SGA&
共享池[共享编译命令]
数据缓冲区[缓冲数据库文件中查询到的数据]
日志缓冲区[临时状态记录器]
后台进程&PGA&
物理结构[可见的]
逻辑结构&隐藏的&
Oracle基本数据类型
固定长度字符串
最大长度2000
可变长度的字符串
最大长度4000
可做索引的最大长度749
根据字符集而定的固定长度字符串
最大长度2000
根据字符集而定的可变长度字符串
最大长度4000
日期(日-月-年)
DD-MM-YY(HH-MI-SS)
经过严格测试,无千虫问题
超长字符串
最大长度2G(231-1)
足够存储大部头著作
固定长度的二进制数据
最大长度2000
可存放多媒体图象声音等
可变长度的二进制数据
最大长度2G
二进制数据
最大长度4G
最大长度4G
根据字符集而定的字符数据
最大长度4G
存放在数据库外的二进制数据
最大长度4G
数据表中记录的唯一行号
********.****.****格式,*为0或1
二进制数据表中记录的唯一行号
最大长度4000
NUMBER(P,S)
P为整数位,S为小数位
DECIMAL(P,S)
P为整数位,S为小数位
浮点数类型
NUMBER(38),双精度
NUMBER(63),精度更高
nvl(comm,0)
max min avg sum count
select max(sal)
select ename ,job
where sal&(select avg(sal) from emp)
select ename,sal
update emp
set sal=sal+500
where sal&(select avg(sal) from emp)
and hiredate & '09-6月-81'
select ename,sal,hiredate
where hiredate & '09-6月-81'
Oracle操作
超级管理员登陆 sqlplus / as sysdba
学习账号[默认锁] 解锁 conn scott/tiger
创建表用户 create tablespace [名字]
datafile '位置' size 大小
封号 ; 结尾
表空间 自动扩充 autoextend on
上一行可复制
1.表名和列的命令规则:
  必须以字母开头,长度不能超过30个字符。不能使用Oracle保留字。只能使用A-Za-z0-9$#等。
  表 TABLE包括:分区表,TABLE PARTITION 簇CLUST
第1页/共4页
寻找更多 ""博客分类:
在我们的项目中,经常要从HibernateDaoSupport继承然后使用他的HibernateTemplate给我们封装好的方法。
我们以用户模块的持久层UserDao这个类的addUser(User user)方法为例:
第一种方法:userDao extends HibernateDaoSupport:(不推荐使用)
我们知道继承这个类,必须给他注入一个HibernateTemplate的对象,或者是SessionFactory对象但是HibernateDaoSupport这个类的所有的方法都是final的,无法重写他的setSessionFactory(SessionFactory sessionFactory)方法来注入,只能使用xml的方式来生成userDao这个对象的时候,使用&property id ="xxx" ref="xxx"&来注入这个对象,但是如果这样,如果我们的Dao层的类特别多,都需要在xml文件中进行配置我们的xml配置文件就会十分的庞大 臃肿
第二种方法:
public class BaseDao extends HibernateDaoSupport {
@Resource(name="sessionFactory")
public void setSF(SessionFactory sessionFactory) {
super.setSessionFactory(sessionFactory);
}
我们抽取出来一个Dao层的基类然后让这个类继承HibernateDaoSupport,然后我们自己随便写个方法参数是SessionFactory,然后再方法上面加入@Resource注解,把SessionFactory对象,注入到这个方法中来然后再这个方法中调用父类中也就是HibernateDaoSupport 中的setSessionFactory(SessionFactory sessionFactory)方法把sessionFactory给他注入进去。默认情况下@Resource注解是按照名称来注入的,但是这个时候我们自己写的这个方法无法与spring配置文件中的id名称匹配起来就会按照类型进行注入了。然后我们的UserDao类继承我们的BaseDao类就可以使用HibernateTemlate中的方法了。
第三种方法:
public class BaseDao {
private HibernateTemplate hibernateT
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateT
还是抽取出一个BaseDao的类,然后我不继承HibernateDaoSupport这个类了。我在这个类中,定义一个HibernateTemplate类型的属性,然后把这个类注入进来,UserDao等这些持久化类仍然是从这个类继承,就可以使用HibernateTemplate中的方法了。
论坛回复 /
(24 / 7991)
whaosoft 写道star022 写道这年头 还这么多人玩DAO啊~~!
为什么不玩DAO了啊?
DAO没什么意义。
1.我只用hibernate。
2.我不换数据库。
3.sql和hql大部分写配置文件里面。
如此为什么不直接把session注入到service里面直接操作?
ession注入到service里面直接操作????
ORM工具在简化单表动态查询和CRUD的时候作用很大
但是复杂查询用HQL之类的那就太过于麻烦了,还不如直接写SQL
至于一个业务逻辑里十几次操作数据库,这往往直接就写成存储过程了
对于很多遗留系统或者说设计时不是很考虑orm工具特性的系统,视图,存储过程等是不二法宝。处理非OO数据,java该歇一边去。
你认为DAO没有存在的必要性,主要是因为你做的项目还不够复杂。
在一个Service调用中,业务逻辑可能会包含十几次的数据库调用,其中有一半需要用HQL。你告诉我你把这些HQL全部写在Service层,那么你的Service层就会膨胀不堪,代码就会变得不可读。DAO层的出现,可以把这些HQL的数据库调用封装起来,让你的代码更加简洁。同时,这些被封装的函数,可以被反复调用。
HQL或者SQL写在配置文件里面是一种非常错误的做法。项目很大的时候,你会发现你的配置文件中充斥着非常类似的HQL或者SQL。同时,在你进行debug调试的时候,由于你拿到的是一个Key,增加了一个根据Key到配置文件去拿HQL的动作,从而给调试带来不便。
没看出来根据key拿hql那里麻烦了,除非key和对应的query命名非常混乱。如果合理运用named query,java代码和hql/sql相分离,将会大大减低维护工作的难度,拿sql来说,你说DBA喜欢看你java中拼出来的sql,还是单独配置文件中的sql?同样作为java程序员的我,在view代码的时候,看到一大串sql进来插入java中,我也非常无语。
slaser 写道aaa5131421 写道downpour 写道aaa5131421 写道
正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。
你的理解是错的。
DAO这层可以很薄,但是要有。把SQL和HQL写在配置文件里是一个非常差的实践。会为调试和问题定位带来极大的麻烦。
如果我不是需要经常再不改动代码的情况下改动hql的需求,我会直接放在业务逻辑类里面。这是最理想的位置
谁说hql是属于dao层的呢?hql是属于业务逻辑的,它经hibernate转换后成变成的sql才属于dao层里面的东西。而hibernate的这个转化过程就是你在“调用dao层”
我不会直接写sql的,这违背hibernate本意,如果hql等。。实在满足不了需求,写sql是必然,但一个项目中这样的位置不会超过两处,这是技术上的问题,如果非要为这两处封装一个dao,得不偿失,假如需要写很多hql满足不了的sql,也可以考虑自己写个补充hibernate的hql解释器,而不是直接写sql并将他放在代码里面。
hql确实是业务层的东西,这个应该写在service里面,必须的sql放配置没什么问题,这个比放代码里面更干净,更容易调试。dao是jdbc时代遗留产物,不过为每一个sql的执行和把执行结果放入对象这样的操作做一个命名而已。在使用hibernate,jpa同时大量使用dao,才是一个很差的实践。所谓很薄的dao,为什么不直接用session或者jpa里面的entityManager代替,封装一下减少功能很有意思么?
这个不是绝对的,还应该具体问题具体分析吧。
如果系统比较复杂庞大,并且以后有换数据库的可能性,还是写一个dao层对日后是有好处的。
如果只是一般的系统并且数据库不会换掉可以考虑写一个自己的BaseDao。
我是基于不换数据库,不换orm工具来说的。没有限定条件,一切都是空谈。
aaa5131421 写道downpour 写道aaa5131421 写道
正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。
你的理解是错的。
DAO这层可以很薄,但是要有。把SQL和HQL写在配置文件里是一个非常差的实践。会为调试和问题定位带来极大的麻烦。
如果我不是需要经常再不改动代码的情况下改动hql的需求,我会直接放在业务逻辑类里面。这是最理想的位置
谁说hql是属于dao层的呢?hql是属于业务逻辑的,它经hibernate转换后成变成的sql才属于dao层里面的东西。而hibernate的这个转化过程就是你在“调用dao层”
我不会直接写sql的,这违背hibernate本意,如果hql等。。实在满足不了需求,写sql是必然,但一个项目中这样的位置不会超过两处,这是技术上的问题,如果非要为这两处封装一个dao,得不偿失,假如需要写很多hql满足不了的sql,也可以考虑自己写个补充hibernate的hql解释器,而不是直接写sql并将他放在代码里面。
hql确实是业务层的东西,这个应该写在service里面,必须的sql放配置没什么问题,这个比放代码里面更干净,更容易调试。dao是jdbc时代遗留产物,不过为每一个sql的执行和把执行结果放入对象这样的操作做一个命名而已。在使用hibernate,jpa同时大量使用dao,才是一个很差的实践。所谓很薄的dao,为什么不直接用session或者jpa里面的entityManager代替,封装一下减少功能很有意思么?
这个不是绝对的,还应该具体问题具体分析吧。
如果系统比较复杂庞大,并且以后有换数据库的可能性,还是写一个dao层对日后是有好处的。
如果只是一般的系统并且数据库不会换掉可以考虑写一个自己的BaseDao。
你认为DAO没有存在的必要性,主要是因为你做的项目还不够复杂。
在一个Service调用中,业务逻辑可能会包含十几次的数据库调用,其中有一半需要用HQL。你告诉我你把这些HQL全部写在Service层,那么你的Service层就会膨胀不堪,代码就会变得不可读。DAO层的出现,可以把这些HQL的数据库调用封装起来,让你的代码更加简洁。同时,这些被封装的函数,可以被反复调用。
一个业务逻辑包含十来个数据库调用扥情况,如果你将这些业务逻辑只是写在一个service里面,没有进行横向的模块划分的话的确会很复杂,会膨胀不堪,会不可读,但这却不是因为没有dao层的原因,而是由于你设计的问题,安我的经验,一个业务逻辑中的十来次数据库操作,而且都是很复杂的数据库操作,通常这样的逻辑可以再拆分成更细化的逻辑,而且有一部分逻辑是属于其他模块的业务逻辑,完全可以抽象出来放在其他模块的services里面,这样也可以拿来复用。
因为services层的臃肿不堪就把业务层的东西放到dao层里面,也就是你所说把hql封装起来的函数级别的复用其实是低级的复用,把hql和此hql对应的方法逻辑封装到一起,形成services级别的复用才是最好的解决方案。
&bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"&
&property name="sessionFactory" ref="sessionFactory" /&
&bean id="transactionManager"&&&&&& class="org.springframework.orm.hibernate3.HibernateTransactionManager"&
& &property name="sessionFactory" ref="sessionFactory" /&
&tx:annotation-driven transaction-manager="transactionManager" /&
然后
&& @Resource protected HibernateTemplate hibernateT
&& 可以让BaseDAOImpl的子类也可以使用hibernateTemplate
this.hibernateTemplate.findByCriteria(DetachedCriteria.forClass(entityclass));
Hibernate提供的DetachedCriteria 可以在没有Session的情况下组装查询条件,这样将HQL转换为QBC,业务就可以脱离DAO,在Service层写好DetachedCriteria再统一使用hibernateTemplate.findByCriteria进行处理,感觉这样比较好
So,直接把hibernateTemplate放service里面好了,简单易用,维护方便。
downpour 写道aaa5131421 写道
正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。
你的理解是错的。
DAO这层可以很薄,但是要有。把SQL和HQL写在配置文件里是一个非常差的实践。会为调试和问题定位带来极大的麻烦。
如果我不是需要经常再不改动代码的情况下改动hql的需求,我会直接放在业务逻辑类里面。这是最理想的位置
谁说hql是属于dao层的呢?hql是属于业务逻辑的,它经hibernate转换后成变成的sql才属于dao层里面的东西。而hibernate的这个转化过程就是你在“调用dao层”
我不会直接写sql的,这违背hibernate本意,如果hql等。。实在满足不了需求,写sql是必然,但一个项目中这样的位置不会超过两处,这是技术上的问题,如果非要为这两处封装一个dao,得不偿失,假如需要写很多hql满足不了的sql,也可以考虑自己写个补充hibernate的hql解释器,而不是直接写sql并将他放在代码里面。
hql确实是业务层的东西,这个应该写在service里面,必须的sql放配置没什么问题,这个比放代码里面更干净,更容易调试。dao是jdbc时代遗留产物,不过为每一个sql的执行和把执行结果放入对象这样的操作做一个命名而已。在使用hibernate,jpa同时大量使用dao,才是一个很差的实践。所谓很薄的dao,为什么不直接用session或者jpa里面的entityManager代替,封装一下减少功能很有意思么?
aaa5131421 写道
正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。
你的理解是错的。
DAO这层可以很薄,但是要有。把SQL和HQL写在配置文件里是一个非常差的实践。会为调试和问题定位带来极大的麻烦。
如果我不是需要经常再不改动代码的情况下改动hql的需求,我会直接放在业务逻辑类里面。这是最理想的位置
谁说hql是属于dao层的呢?hql是属于业务逻辑的,它经hibernate转换后成变成的sql才属于dao层里面的东西。而hibernate的这个转化过程就是你在“调用dao层”
我不会直接写sql的,这违背hibernate本意,如果hql等。。实在满足不了需求,写sql是必然,但一个项目中这样的位置不会超过两处,这是技术上的问题,如果非要为这两处封装一个dao,得不偿失,假如需要写很多hql满足不了的sql,也可以考虑自己写个补充hibernate的hql解释器,而不是直接写sql并将他放在代码里面。
正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。
你的理解是错的。
DAO这层可以很薄,但是要有。把SQL和HQL写在配置文件里是一个非常差的实践。会为调试和问题定位带来极大的麻烦。
whaosoft 写道star022 写道这年头 还这么多人玩DAO啊~~!
为什么不玩DAO了啊?
DAO没什么意义。
1.我只用hibernate。
2.我不换数据库。
3.sql和hql大部分写配置文件里面。
如此为什么不直接把session注入到service里面直接操作?
正解,好多的书籍,视频都是这样、那样说,持久化一定需要分出个层来,然后很多人就以为非要自己写个dao代码,才算分个层出来,这样才解耦,殊不知hibernateDaoSupport就已经是一个dao层,在大部分并不是十分十分复杂的项目中,将hibernate再封装一下,给services使用,而每个dao方法里面却只有一行的代码。写方法头的代码和方法体的代码一样多,美名其曰这叫封装。。。。我很无语。。。
star022 写道这年头 还这么多人玩DAO啊~~!
为什么不玩DAO了啊?
DAO没什么意义。
1.我只用hibernate。
2.我不换数据库。
3.sql和hql大部分写配置文件里面。
如此为什么不直接把session注入到service里面直接操作?
这年头 还这么多人玩DAO啊~~!
为什么不玩DAO了啊?
& 上一页 1
longdechuanren
浏览: 186781 次
来自: 山东-东营-利津县
为什么会选择用拦截器,不用action呢
lz辛苦了,写的真详细,我正郁闷这些问题呢,学习了。
如果想要在虚拟机之外的 局域网机器中访问应用 ip需要设置成自 ...&使用Hibernate开发租房系统
秒后自动跳转到登录页
快捷登录:
举报类型:
不规范:上传重复资源
不规范:标题与实际内容不符
不规范:资源无法下载或使用
其他不规范行为
违规:资源涉及侵权
违规:含有危害国家安全等内容
违规:含有反动/色情等内容
违规:广告内容
详细原因:
任何违反下载中心规定的资源,欢迎Down友监督举报,第一举报人可获5-10下载豆奖励。
视频课程推荐
使用Hibernate开发租房系统
上传时间:
技术分类:
资源评价:
(0位用户参与评价)
已被下载&38&次
租房系统源码,数据库都有
本资料共包含以下附件:
使用Hibernate开发租房系统.zip
51CTO下载中心常见问题:
1.如何获得下载豆?
1)上传资料
2)评论资料
3)每天在首页签到领取
4)购买VIP会员服务,无需下载豆下载资源
5)更多途径:点击此处
2.如何删除自己的资料?
下载资料意味着您已同意遵守以下协议:
1.资料的所有权益归上传用户所有
2.未经权益所有人同意,不得将资料中的内容挪作商业或盈利用途
3.51CTO下载中心仅提供资料交流平台,并不对任何资料负责
4.本站资料中如有侵权或不适当内容,请邮件与我们联系()
5.本站不保证资源的准确性、安全性和完整性, 同时也不承担用户因使用这些资料对自己和他人造成任何形式的伤害或损失
相关专题推荐
本套视频教程共包含20个章节,包含源
本专题为MLDN培训机构李兴华老师主讲
本专题为Eclipse操作详解视频教程,视
浙江大学颜晖老师授课视频教程,共45
浙江大学张继昌教授授课视频教程,共
本专题为Spring MVC视频教程。Spring
Java开源优秀工作流框架,值得学习和
Qt是一个1991年由奇趣科技开发的跨平
C++是一种静态数据类型检查的、支持多
Java高级班全套视频教程,讲解全面系
本套教程含很多知识点的应用方案与经
我来说说面向对象第1季,Java俄罗斯方
巴巴运动网视频教程,传智播客黎活明
C++是一种语言,仅仅是它的语法、特性
C++是由C发展而来的,与C兼容。用C语
本视频为传智播客日~2013年
意见或建议:
联系方式:
您已提交成功!感谢您的宝贵意见,我们会尽快处理Hibernate的系统 学习
一、Hibernate的介绍
1.什么是Hibernate?
&&&&&&&&& 首先,是数据持久层的一个轻量级框架。数据持久层的框架有很多比如:iBATIS,myBatis,Nhibernate,Siena等等。
&&&&&&&&& 并且Hibernate是一个开源的orm(object relations mapping)框架,提供了查询获取数据的方法,用面向对象的思想来操作,节省了我们开发处理数据的时间。
2.那使用Hibernate的优点呢?
&&&&&&&&& 1.使用简介的hql语句(Hibernate query language)。可以不使用传统的insert,update等sql语句。比如insert一个对象,原来的做法是:insert into 表名称 alue(值1,值2,值3,……),而现在的做法是:save(对象)。
&&&&&&&&& 2.使用or映射。对象到关系数据库之间的映射。是从对象的角度操作数据库,再次体现了面向对象思想。原来的实体抽取方法:首先有了表,然后表映射实体对象。而现在Hibernate做法是:直接由对象映射到表。
&&&&&&&&& 3.没有侵入性,移植性比较好。什么是没有侵入性?就是Hibernate采用了pojo对象。所谓的pojo对象就是没有继承Hibernate类或实现Hibernate接口。这样的话,此类就是一个普通的类,所以移植性比较好。&&
&&&&&&&& 4.支持透明持久化。透明是针对上层而言的。三层的理念是上层对下层的依赖,只是依赖接口不依赖具体实现。而Hibernate中的透明是指对业务逻辑层提供了一个接口session,而其他的都封装隐藏。持久化是指把内存中的数据存放到磁盘上的文件中。
3.当然一个事物,不可能十全十美,即使如此优秀的Hibernate也有自己的弱点。比如:若是大量数据批量操作。则不适合使用Hibernate。并且一个持久化对象不能映射到多张表中。
4.Hibernate中核心5个接口
&&&&&&&1.Configuration接口:负责配置及启动Hibernate,用来创建sessionFactory
&&&&&&&2.SessionFactory接口:一个SessionFactory对应一个数据源存储,也就是一个数据库对应一个SessionFactory。SessionFactory用来创建Session对象。并且SessionFactory是线程安全的,可以由多个线程访问SessionFactory共享。
&&&&&&&3.Session接口:这个接口是Hibernate中常用的接口,主要用于对数据的操作(增删改查)。而这个Session对象不是线程安全的。不能共享。
&&&&&&&4.Query接口:用于数据库的查询对象。
&&&&&&&5.Transaction接口:Hibernate事务接口。它封装了底层的事务操作,比如JTA(;transcation architecture)所有的数据操作,比如增删改查都写在事务中。
基本的概念以及核心接口已经介绍,那Hibernate又是如何应用的呢?下篇博客将会介绍如何使用Hibernate?
&二、详解Hibernate的搭建及使用
&1.创建普通的项目。
&&&&&&&&&&&&&& 因为是一个轻量级的框架,不像servlet,还必须需要tomcat的支持,Hibernate只要jdk支持即可。
&&&&&& 2.引入jar包。
&&&&&&&&&&&&&& 可以在项目中直接引入jar包,在:项目---&属性---&然后如下图:
&&&&&&&&&&&&&&另一种办法就是引入库,相当于一个文件夹,把所有的jar包放到自己新建的文件夹中。在:窗体--&选项--&然后如下图:
&&&&&&3.提供Hibernate的配置文件。hibernate.cfg.xml文件。完成相应的配置。
&&&&& 在这里连接,解释一下上面的标签。按照顺序来依次解释:第一个是连接mySql的驱动;第二个是连接的url;url后面的hibernate_first是数据库名字;第三个是和第四个分别是用户名和密码。第五个是方言。因为 hibernate对数据库封装,对不同的数据库翻译成不同的形式,比如drp中的分页,若是使用数据库,则翻译成sql语句三层嵌套。若是使用mySql数据库,则翻译成limit语句。
&&& 4.建立实体User类:
package&com.bjpowernode.&&
import&java.util.D&&
public&class&User&{&&
&&&&private&String&&&
&&&&private&String&&&
&&&&private&String&&&
&&&&private&Date&createT&&
&&&&private&Date&expireT&&
&&&&public&String&getId()&{&&
&&&&&&&&return&&&
&&&&public&void&setId(String&id)&{&&
&&&&&&&&this.id&=&&&
&&&&public&String&getName()&{&&
&&&&&&&&return&&&
&&&&public&void&setName(String&name)&{&&
&&&&&&&&this.name&=&&&
&&&&public&String&getPassword()&{&&
&&&&&&&&return&&&
&&&&public&void&setPassword(String&password)&{&&
&&&&&&&&this.password&=&&&
&&&&public&Date&getCreateTime()&{&&
&&&&&&&&return&createT&&
&&&&public&void&setCreateTime(Date&createTime)&{&&
&&&&&&&&this.createTime&=&createT&&
&&&&public&Date&getExpireTime()&{&&
&&&&&&&&return&expireT&&
&&&&public&void&setExpireTime(Date&expireTime)&{&&
&&&&&&&&this.expireTime&=&expireT&&
&&& 5.建立User.hbm.xml,此文件用来完成对象与数据库表的字段的映射。也就是实体类的那些字段需要映射到数据库表中呢。&
&!DOCTYPE&hibernate-mapping&PUBLIC&&&
&&&&"-//Hibernate/Hibernate&Mapping&DTD&3.0//EN"&&
&&&&"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
&&&&&&&&&&&&
&&& 6.我们也映射完毕了,但是hibernate怎么知道我们映射完了呢,以及如何映射的呢?这就需要我们把我们自己的映射文件告诉hibernate,即:在hibernate.cfg.xml配置我们的映射文件。
&&& 7.生成数据库表。大家也看到了我们上述还没有新建数据表呢,在第三步我们只是新建了数据库而已。按照我们普通的做法,我们应该新建数据表啊,否则实体存放何处啊。这个别急,数据库表这个肯定是需要有的,这个毋庸置疑,但是这个可不像我们原来需要自己亲自动手建立哦,现在hibernate需要帮我们实现哦,如何实现嗯,hibernate会根据配置文件hibernate.cfg.xml和我们的映射文件User.hbm.xml会自动给我们生成相应的表,并且这个表的名字也给我们取好:默认是User。那如何生成表呢?
&&&&Configuration&cfg&=&new&Configuration().configure();&&
&&&&SchemaExport&export&=&new&SchemaExport(cfg);&&
&&&&export.create(true,&true);&&
&8.那我们就开始进行操作啦,我们添加一个用户对象,看看hibernate是如何添加的呢?跟我们以前的做法有什么不同呢?
public&class&Client&{&&
&&&&public&static&void&main(String[]&args)&{&&
&&&&&&&&&&
&&&&&&&&Configuration&cfg&=&new&Configuration().configure();&&
&&&&&&&&&&
&&&&&&&&SessionFactory&factory&=&cfg.buildSessionFactory();&&
&&&&&&&&&&
&&&&&&&&Session&session&=&&&
&&&&&&&&try&{&&
&&&&&&&&&&&&session&=&factory.openSession();&&
&&&&&&&&&&&&
&&&&&&&&&&&&session.beginTransaction();&&
&&&&&&&&&&&&User&user&=&new&User();&&
&&&&&&&&&&&&user.setName("张三");&&
&&&&&&&&&&&&user.setPassword("123");&&
&&&&&&&&&&&&user.setCreateTime(new&Date());&&
&&&&&&&&&&&&user.setExpireTime(new&Date());&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&
&&&&&&&&&&&&session.save(user);&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&
&&&&&&&&&&&&session.getTransaction().commit();&&
&&&&&&&&}catch(Exception&e)&{&&
&&&&&&&&&&&&e.printStackTrace();&&
&&&&&&&&&&&&
&&&&&&&&&&&&session.getTransaction().rollback();&&
&&&&&&&&}finally&{&&
&&&&&&&&&&&&if&(session&!=&null)&{&&
&&&&&&&&&&&&&&&&if&(session.isOpen())&{&&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&session.close();&&
&&&&&&&&&&&&&&&&}&&
&&&&&&&&&&&&}&&
&&&&&&&&}&&
&第八步,我们可以看到,没有我们熟悉的insert into表的sql语句了,那怎么添加进去的呢,到底添加了没?让我真实滴告诉你,确实添加进去了,不信的,可以自己尝试哦,这也是hibernate的优点,对jdbc封装的彻底,减少了我们对数据的操作时间哈。
&三、Hibernate的总结
看一下中整体的内容:
&&&我们一一介绍其中的内容。
Hibernate出现的原因上篇博客已经介绍,可以参考《Hibernate介绍》
Hibernate中的核心五大接口,在上篇博客中也已经介绍,可以参考《Hibernate介绍》
如何搭建Hibernate,请参考《八步详解Hibernate的搭建及使用》
持久化对象的三种状态。
分别为:瞬时状态(Transient),持久化状态(Persistent),离线状态(Detached)。三种状态下的对象的生命周期如下:
三种状态的区别是:瞬时状态的对象:没有被session管理,在没有;持久化状态的对象:被session管理,在数据库存在,当属性发生改变,在清理缓存时,会自动和数据库同步;离线状态:没有被session管理,但是在数据库中存在。
5.工具Juit。
测试类需要继承TestCase,编写单元测试方法,方法名称必须为test开头,方法没有参数没有返回值,采用public修饰。其中在测试中,查询对象时,使用get或者load两种方法进行加载,这种方法的区别:get不支持延迟加载,而load默认情况下是支持延迟加载。并且get查询对象不存在时,返回null;而load查询对象不存在时,则抛出ObjectNotFoundException异常。
6.悲观锁和乐观锁解释。
悲观锁为了解决并发性,跟中的进程中添加锁的概念一样。就是在整个过程中在事务提交之前或回滚之前,其他的进程是无法访问这个资源的。悲观锁的实现方式有两种:一种使用中的独占锁;另一种是在数据库添加一个锁的字段。中声明锁如下:
Account account = (Account)session.get(Account.class, 1, LockMode.UPGRADE);而net.sf.hibernate.LockMode类表示锁模式,当取值LockMode.UPGRADE时,则表示使用悲观锁for update;而乐观锁是为了解决版本冲突的问题。就是在数据库中添加version字段,每次更新时,则把自己的version与数据库中的version进行比较,若是版本相比较低,则不允许进行修改更新。
7.H ibernate中的缓存机制。
缓存是什么呢?缓存是应用程序和数据库之间的内存的一片区域。主要的目的是:为了减少对数据库读取的时间。当查询数据时,首先在缓存中查询,若存在,则直接取出,若不存在,然后再向数据库中查询。所以应该把经常访问数据库的数据放到缓存中,至于缓存中的数据如何不断的置换,这也需要涉及一种淘汰数据的。
谈到这个hibernate中的缓存,你想到了什么呢?刚才叙述缓存时,是否感觉很熟悉,感觉从哪也听过似的。嗯呢,是呢,是很熟悉,写着写着就很熟悉,这个刚才的缓存以及缓存的置换算法就和计算机组成中的cache类似。
好吧,来回到我们hibernate中的缓存。
hibernate中的缓存可以分为两种:一级缓存,也称session缓存;二级缓存,是由sessionFactory管理。
那一级缓存和二级缓存有什么区别呢?区别的关键关于:缓存的生命周期,也就是缓存的范围不同。
那首先介绍一下缓存的生命周期,也就是缓存的范围。
1.事务缓存,每个事务都有自己的缓存,当事务结束,则缓存的生命周期同样结束,正如上篇博客中我们提到,对数据库的操作,增删改查都是放到事务中的,和事务保持同步,若是事务提交完毕,一般是不允许是再次对数据库进行操作。所以session是属于事务缓存的。
2.应用缓存,一个应用程序中的缓存,也就是应用程序中的所有事务的缓存。只有当应用程序结束时,此时的缓存的额生命周期结束。二级缓存就是应用缓存。
3.集群缓存,被一台机器或多台机器的进程共享。
这下明白了一级缓存和二级缓存的区别了吧。那一级缓存和二级缓存的共同点是:都是缓存实体属性,
二级缓存一般情况都是由第三方插件实现的。第三方插件如:
EHCache,JbossCache(是由Jboss开源组织提供的),osCache(open symphony),swarmCache。前三种对hibernate中的查询缓存是支持的,后一种是不支持hibernate查询缓存。
那什么是hibernate查询缓存呢?
查询缓存是用来缓存普通属性的,对于实体对象而言,是缓存实体对象的id。
8.hql查询。
&&&query language。hql查询中关键字不区分大小写,但是类和属性都是区分大小写的。
& 1.简单属性查询。
& 单一属性查询,返回属性结果集列表,元素类型和实体类的相应的类型一致。
List&students&=&session.createQuery("select&name&from&Student").list();&&
for&(Iterator&iter=students.iterator();&iter.hasNext();)&{&&
String&name&=&(String)iter.next();&&
System.out.println(name);&&
&//返回结果集属性列表,元素类型和实体类中的属性类型一致
多个属性查询,多个属性查询返回数组对象,对象数组的长度取决于属性的个数,对象数组中的元素类型与实体类中属性一致。
List&students&=&session.createQuery("select&id,&name&from&Student").list();&&
for&(Iterator&iter=students.iterator();&iter.hasNext();)&{&&
Object[]&obj&=&(Object[])iter.next();&&
System.out.println(obj[0]&+&",&"&+&obj[1]);&&
2.实体对象查询
List students = session.createQuery("from Student").list();
当然这种hql语句,可以使用别名,as可以省去,如:from Student as s,若是使用select关键字,则必须使用别名。如:select s from Student as s.但是不支持select * from Student格式。
查询中使用list和Iterate区别:
list查询是直接运行查询的结果,所以只有一句sql语句。而iterate方法则有可能会产生N+1条sql语句。这是怎么回事呢?要理解N+1条语句,首先得弄明白iterate是如何执行查询的?
首先发出一条查询对象ID的语句,然后根据对象的ID到缓存(缓存的概念上篇博客已经提到)中查找,若是存在查询出此对象的其他的属性,否则会发出N条语句,此时的N语句,是刚才第一次查询的记录条数。这种现象就是N+1sql语句。
其中list是默认情况下都发出sql语句,查询出的结果会放到缓存中,但是它不会利用缓存,即使放进去,下次执行时,仍然继续发出sql语句。
而:iterate默认情况下会利用缓存,若是缓存中有则不会发出N+1条语句。
3.条件查询。
这种方式就是传入参数,使用参数占位符“?”。也可以使用“:参数名”
代码如下:
List&students&=&session.createQuery("select&s.id,&s.name&from&Student&s&where&s.name&like&?")&&
.setParameter(0,&"%0%")&&
.list();&&
List&students&=&session.createQuery("select&s.id,&s.name&from&Student&s&where&s.name&like&:myname")&&
.setParameter("myname",&&"%0%")&&
.list();&&
&4.使用原生sql语句。
&&&& 和咱们原先写入的sql语句一样。在此不介绍了。
&5.外置命名查询。
&&&&&&这个听起来有点晦涩,怎么理解呢?其实通俗的说就是把hql语句写在外面,写在映射文件中。使用标签:
&![CDATA[&
select&s&from&Student&s&where&s.id&&?&
&&&&那在程序中是如何使用此标签的呢?使用session.getNameQuery(),并进行赋值,代码如下:
List&students&=&session.getNamedQuery("queryStudent")&&
.setParameter(0,&10)&&
.list();&&
&6.查询过滤器。
&&& 这个是什么意思呢?过滤器大家很熟悉吧,不熟悉的可以参考我的以前博客&&.原来我们接触过编码过滤器,编码过滤器就是为了避免当时每个页面需要设置编码格式而提出的。这个查询过滤器其实也是这个意思。若是代码都需要某一句sql语句的话,可以考虑使用它。这样可以避免每次都写查询语句。
&&&&使用如下:首先在映射文件中配置标签:
&&然后程序中如下使用并进行赋值:
session.enableFilter("testFilter")&&
.setParameter("myid",&10);&&
7.分页查询。
&&& 分页查询,这个肯定不陌生,因为在做drp项目时,做的最多的是分页,当时使用,分页查询涉及到三层嵌套。直接传入的参数为:每页的大小(记录数),页号。
&&&& Hibernate中给我们已经封装好了,只要设置开始的页号以及每页的大小即可,不用亲自动手写嵌套的sql语句。
&&&&&代码如下:
List&students&=&session.createQuery("from&Student")&&
.setFirstResult(1)&&
.setMaxResults(2)&&
.list();&&
8.对象导航查询。
这个什么意思呢?这个只要是用于一个类的属性是另一个类的引用。比如:student类中有一个classes属性。其中的classes也是一个类Class的引用。
当我们查询的时候可以这样使用:
List&students&=&session.createQuery("from&Student&s&where&s.classes.name&like&'%t%'")&&
.list();&&
相当于:s.getClasses.getName(),直接使用get后面的属性,然后首字母小写。
&这种语法,是不是很熟悉?想想我们在哪是不是也用过?想起来了吗?估计你猜出来啦,呵呵,是JSTL(jsp standard tag library)中。若是想进一步了解,可以参考我的博客哈,当时是转载滴貌似。
9.连接查询。
&&& 连接分为:内连接和外连接,其中外连接分为左连接,右连接,完全连接。这个跟数据库中的左右连接其实是一样的。我们通俗解释一下:
&&& 左连接:以左边为准,右边即使没哟匹配的,也要把这条记录查询出来,此时没有匹配的右边以null填充。
&&&&右连接:以右边为准,左边即使没有匹配的,也要把这条记录查询出来,此时没有匹配的左边以null填充。
&&&完全连接:只要一方存在即可。
&& 内连接:必须两方都存在才可以查询提取此记录。
10.统计查询。
&&&& 其实就是查询count的记录数。其中查询出来的额count是long类型。
11.DML风格的操作。
&&&& DML?其实DML=Data Manipulate Language(数据操作语言),举个例子:
session.createQuery("update&Student&s&set&s.name=?&where&s.id&?")&&
.setParameter(0,&"王斌")&&
.setParameter(1,&2)&&
.executeUpdate();&&&
&&&&&&&&&&&
假若原来的名字是:李四,更新完数据库后变成王斌,若是我们此时取出数据,其姓名是李四还是王斌?按照道理应该是王斌,但是结果确实李四,若不信,可以自己去实践一下。
这个原因,是因为更新了数据库,但是缓存中没有更新,才会造成这种数据库和缓存不同步的问题。
所以,我们应该尽量不使用这种形式。扬其长避其短嘛。
阅读(...) 评论()

我要回帖

更多关于 hibernatetemplate 的文章

 

随机推荐