Hibernate(五)——面向对象查询语言和锁
Hibernate做了数据库中表和我们实体类的映射,使我们不必再编写sql语言了。但是有时候查询的特殊性,还是需要我们手动来写查询语句呢,Hibernate框架为了解决这个问题给我们提供了HQL(Hibernate Query Language)面向对象的查询语言,和QBC(Query by Criteria)完全面向对象的查询,这里简单总结一下如何是面向对象来编写ql语句呢。
一,HQL,Hibernate框架中的查询语言,是一种面向对象查询语言,和sql语句还是非常类似的,就是将sql语句中的表改成实体名,字段改为属性名即可,其它基本都很相似的。主要用的是Query这个对象。返回值可以使用list,iterate(多值),uniqueResult(单值)等属性进行取值。下边看几个小例子:
1,模糊查询+list迭代:
String key = "san";
Query query = session.createQuery("FROM Student s where s.sname like ?"); //HQL语句。看里边都是使用类名和属性名代替了数据库中的表和字段
query.setParameter(0, "%"+key+"%"); //参数索引从0开始。
//query.setString(0, "%"+key+"%");
List<Student> sts = query.list();
for(Student s : sts){
System.out.println(s.getSname());
}
2,iterate相当于集合中的迭代器,Hibernate框架会先查询符合条件的所有id值,然后根据每个id去查询每一条记录,这样我们查询N条件记录时,框架帮我们发送了N+1条语句,这也就是大家经常讨论的N+1问题。这个我们可以通过实际的例子实验一下:
Query query = session.createQuery("from Student s");
Iterator<Student> it = query.iterate();
while(it.hasNext()){
Student s = (Student)it.next();
System.out.println(s.getSname());
}
3,返回结果是一个的话,可以使用uniqueResult值来获取:
public static void testSelect(Session session){
Query query = session.createQuery("from Student s where s.sid=1");
Student s = (Student)query.uniqueResult();
System.out.println(s.getSname());
}
4,当然Query对象也支持update,delete,insert,但是这些操作会立即对数据库的数据进行操作,而不对缓存中的数据进行操作,那么在支持缓存时,数据可能会出现冲突,所以使用要慎用
Query query = session.createQuery("update Student s set s.sname='张三123' where s.sid=1" );
int i = query.executeUpdate();
if(i==1){
System.out.println("更新成功");
}
5,这里说一下两者和缓存之间的关系吧:
iterate方法默认是支持缓存的,只要我们的框架配置了二级缓存的支持,iterate方法也是会支持的。
list呢?默认是不支持缓存的,如何让它支持缓存呢,这里需要我们的配置,这里简单看一下支持缓存的配置吧?
a,首先需要引入jar包和对应的xml配置文件,这里的jar包及配置文件和二级缓存的jar包是一样的:ehcache-1.2.3.jar,ehcache.xml
b,在hibernate.cfg.xml中启用查询缓存(注意不是二级缓存):
<!--启用查询缓存 -->
<propertynamepropertyname="hibernate.cache.use_query_cache">true</property>
c,让框架识别缓存组件,和二级缓存中是一样的:
<!--让框架识别ehcache缓存组件 -->
<propertynamepropertyname="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
这样配置了以后,list就支持缓存了,此查询缓存是支持一级查询和二级查询的。
二,QBC(Query by Criteria),是通过利用Criteria对象来进行查询的,更适合做不定参数查询的情况,这里举一个简单例子,
Criteria cra = session.createCriteria(Student.class);
// _ 匹配一个字符, % 匹配多个字符
cra.add(Restrictions.like("sname", "%s%"));
cra.addOrder(Order.desc("sid"));
List<Student> sts = cra.list();
for(Student s : sts){
System.out.println(s.getSname());
上边两项是Hibernate框架中,面向对象编写SQL语句的写法,总体上和sql语句的编写是类似的,但是更加面向对象,对一些功能的编写更加容易,我们可以根据不同情况进行不同的选择使用即可。
三,我们这里来看一下Hibernate中的锁机制吧,在此框架中锁机制包括悲观锁和乐观锁!
1,悲观锁:对于一些数据我们是不能同时去修改的,否则就会出现数据的错误,在数据库中我们可以通过行级锁select……for update进行对数据的锁定,避免的。而在框架中就是通过悲观锁的。为什么叫它悲观锁呢?因为发生这种同时修改数据的几率是非常非常小,而此种锁却一直加上了,所以它是一种悲观者的身份来做的事。所以称为悲观锁。看一下怎么使用吧!
设置LockMode.UPGRADE参数,那么只有当前事务提交后,另外的事务才能够查询这个数据。这种悲观锁的性能比较底。
Account account =(Account)session.get(Account.class, 1 , LockMode.UPGRADE);
2,乐观锁:其实就是以乐观人的态度来解决这种数据同时修改的问题。解决原理是,当事务不同时发生时,没有锁,如果事务同步发生了,它的锁就起作用了。所以来说,它只是在这种几率很小的情况发生时才会加锁,所以叫乐观锁。它的性能大大的提高了。
a,实现方式:时间戳和版本号(Hibernate框架实现的)
b,在我们需要加乐观锁对应的数据上,添加ptimistic-lock="version"属性:
<hibernate-mapping>
<!-- optimistic-lock="version" 使用乐观锁 -->
<class name="com.bjpowernode.hibernate.pojo.Account" table="t_account" optimistic-lock="version">
<id name="aid" column="aid">
<generator class="assigned"/>
</id>
<!-- 版本号字段 ,这里需要我们在对应的pojo类中添加对应的verget,set方法-->
<version name="ver" column="version"></version>
<property name="money"/>
</class>
</hibernate-mapping>
这样,框架会自动为我们调用版本号,来进行乐观锁的的管理。功能还是非常强大的。尤其对于一些特别需要安全的数据,例如银行卡的余额等等。
综上,为Hibernate中面向对象查询语句,与锁的简单总结。感觉Hibernate的功能还是非常强大的,需要我们不断的挖掘,钻研……
Hibernate(五)——面向对象查询语言和锁的更多相关文章
- Hibernate框架(五)面向对象查询语言和锁
Hibernate做了数据库中表和我们实体类的映射,使我们不必再编写sql语言了.但是有时候查询的特殊性,还是需要我们手动来写查询语句呢,Hibernate框架为了解决这个问题给我们提供了HQL(Hi ...
- 多线程(五) java的线程锁
在多线程中,每个线程的执行顺序,是无法预测不可控制的,那么在对数据进行读写的时候便存在由于读写顺序多乱而造成数据混乱错误的可能性.那么如何控制,每个线程对于数据的读写顺序呢?这里就涉及到线程锁. 什么 ...
- Python进阶(十五)----面向对象之~继承(单继承,多继承MRO算法)
Python进阶(十五)----面向对象之~继承 一丶面向对象的三大特性:封装,继承,多态 二丶什么是继承 # 什么是继承 # b 继承 a ,b是a的子类 派生类 , a是b的超类 基类 父类 # ...
- Hibernate五 HQL查询
HQL查询一 介绍1.HQL:Hibernate Query Language,是一种完全面向对象的查询语言.使用Hibernate有多重查询方式可供选择:hibernate的HQL查询,也可以使用条 ...
- hibernate(五) hibernate一对一关系映射详解
序言 之前讲解了一对多(单向.双向).多对多(双向),今天就讲解一下最后一个关系,一对一. 心情不错.状态也挺好的,赶紧写一篇博文造福一下大家把. --WH 一.一对一关系的概述 一对一关系看起来简单 ...
- hibernate的面向对象查询的效率有多低?
前言 老平台的查询速度很慢,需要进行优化(...说白了就是优化sql语句),老平台用的strus2+hibernate框架,查询基本都是使用的HSQL. 关于hsql HQL是Hibernate Qu ...
- 关于Hibernate基于version的乐观锁
刚刚接触SSH框架,虽然可能这个框架已经比较过时了,但是个人认为,SSH作为一个成熟的框架,作为框架的入门还是可以的. 马马虎虎学完了Hibernate的基础,总结一点心得之类的. 学习Hiberna ...
- Criteria——Hibernate的面向对象查询
提到Hibernate的查询.我们往往会想到HQL,他使我们的SQL语句面向对象话. 事实上细看,差点儿相同就是把SQL语句中的表和字段用所相应的实体和属性给取代了.事实上.Hibernate中还有还 ...
- 数据库进阶之路(五) - MySQL行锁深入研究
由于业务逻辑的需要,必须对数据表的一行或多行加入行锁,举个最简单的例子,图书借阅系统:假设id=1的这本书库存为1,但是有2个人同时来借这本书,此处的逻辑为: ; --如果restnum大于0,执行u ...
随机推荐
- Java IO教程 导读
Java IO是一套java 用来读写数据(输入和输出)的API.大部分程序都要处理一些输入,并有输入产生一些输出.Java为此提供了java.io包. 如果你浏览下java.io包,会对其中各样的类 ...
- 【转】Devexpress使用之:GridControl控件(合并表头)
Devexpress系列控件功能很强大,使用起来也不太容易,我也是边摸索边使用,如果有时间我会把常用控件的使用方法整理出来的. using System; using System.Collectio ...
- Pojo和JavaBean的区别(转载)
OJO(Plain Old Java Object)这个名字用来强调它是一个普通java对象,而不是一个特殊的对象. 2005年11月时,“POJO”主要用来指代那些没用遵从特定的Java对象模型,约 ...
- Android Studio编译好的apk放在哪里?
Eclipse中编译好的apk文件时在bin文件中面的,可是在Android Studio有一个比較大的修改了,编译好的apk在android studio里面是直接看不到了,并且apk文件所在文件夹 ...
- 在struts2的action中操作域对象(request、session)
在struts2的Action中,操作域对象一共有三种方式: 1.ActionContext(与servelt API无关联): //相当于request ActionContext.getConte ...
- Js得到radiobuttonlist选中值,设置默认值
JS 代码 var vRbtid=document.getElementById("rbtid"); //得到所有radio var vRbtidList= v ...
- 医院设置 codevs 2577
Floyd+二叉树 #include<iostream>#include<cstdlib>#include<cstdio>#include<cstring&g ...
- 慕课linux学习笔记(八)常用命令(5)
解压缩命令 常用压缩格式 .zip .gz .bz2 .tar.gz .tar.bz2 zip [压缩文件名] [ 原文件 ] #压缩文件 -r [压缩文件名] [ 源目录] #压缩目录 -r [压缩 ...
- IE attachEvent事件处理程序(事件绑定的函数)的this指向的是window不是执行当前事件的dom元素
IE attachEvent事件处理程序(事件绑定的函数)的this指向的是window不是执行当前事件的dom元素. attachEvent(type,listener); listener函数中的 ...
- 分数(有理数)的四则运算PAT1088
2015-02-05 PAT- B1088. Rational Arithmetic (20) http://www.patest.cn/contests/pat-a-practise/1088 #i ...