当前位置: 首页 > news >正文

Hibernate(五)——面向对象查询语言和锁

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

    Hibernate做了数据库中表和我们实体类的映射,使我们不必再编写sql语言了。但是有时候查询的特殊性,还是需要我们手动来写查询语句呢,Hibernate框架为了解决这个问题给我们提供了HQL(Hibernate  Query  Language)面向对象的查询语言,和QBC(Query by Criteria)完全面向对象的查询,这里简单总结一下如何是面向对象来编写ql语句呢。

   一,HQLHibernate框架中的查询语言,是一种面向对象查询语言,和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就支持缓存了,此查询缓存是支持一级查询和二级查询的。


  二,QBCQuery 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的功能还是非常强大的,需要我们不断的挖掘,钻研……

转载于:https://my.oschina.net/huangcongcong/blog/528723

相关文章:

  • 自定义view(使用EditTetx实现记事本特效)
  • 理解Load Average做好压力测试(转)
  • SQL Server 2008空间数据应用系列一:空间信息基础
  • mysql 触发器
  • ssh-keygen - 生成、管理和转换认证密钥
  • WPF笔记(2.9和2.10)——Layout
  • redis ins 调试
  • Oracle oradebug 命令 使用说明
  • 使用C#在VS中开发:未处理AccessViolationException “System.AccessViolationException”类型的未经处理的异常...
  • **PHP分步表单提交思路(分页表单提交)
  • mongodb 数据库操作--备份 还原 导出 导入
  • jboss部署出现MarshalOutputStream找不到错误
  • 于erlang依赖的linux调优
  • 集群RPC通信
  • session的存储方式和配置
  • (三)从jvm层面了解线程的启动和停止
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • 【知识碎片】第三方登录弹窗效果
  • 07.Android之多媒体问题
  • Linux gpio口使用方法
  • Linux中的硬链接与软链接
  • ng6--错误信息小结(持续更新)
  • React+TypeScript入门
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 利用jquery编写加法运算验证码
  • 如何设计一个比特币钱包服务
  • 使用SAX解析XML
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 小而合理的前端理论:rscss和rsjs
  • 学习HTTP相关知识笔记
  • 以太坊客户端Geth命令参数详解
  • 用Visual Studio开发以太坊智能合约
  • 原生Ajax
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • elasticsearch-head插件安装
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • #《AI中文版》V3 第 1 章 概述
  • ( 10 )MySQL中的外键
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (C语言)逆序输出字符串
  • (二)学习JVM —— 垃圾回收机制
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (三)终结任务
  • (算法)Travel Information Center
  • (未解决)macOS matplotlib 中文是方框
  • (学习日记)2024.02.29:UCOSIII第二节
  • (转)创业家杂志:UCWEB天使第一步
  • .DFS.
  • .gitignore文件_Git:.gitignore
  • .NET精简框架的“无法找到资源程序集”异常释疑