Hibernate调试——定位查询源头

为什么有时Hibernate会在程序某一部分生成一条指定sql查询?这个问题让人很难立刻理解,当处理不是我们本人编写的代码时更是如此。

本文将展示如何配置来产生Hibernate查询操作的日志。通过这些日志和一些小技巧来找出这些指定的查询为什么及在何处被执行。

Hibernate查询日志格式

Hibernate内建的查询日志格式如下:


1

2

3

4

5

select /* load your.package.Employee */ this_.code, ...

from employee this_

where this_.employee_id=?

TRACE [email protected]:06:02  BasicBinder - binding parameter [1] as [NUMBER] - 1000

为什么Hibernate不能记载最终的查询日志?

需要注意的是,Hibernate只记录从它发送到JDBC的准备语句(prepared statement)及参数。准备语句使用“?”作为查询参数的占位符,这些参数的实际值被记录在准备语句的下方。

这些准备语句和最终发送到数据库的sql语句是不同的,对于这些最终的查询操作Hibernate无法记录。出现这种情况的原因是Hibernate只知道它发送给JDBC的准备语句和参数,实际的查询是由JDBC构建并发送给数据库的。

为了产生实际查询的日志,像log4jdbc这种工具是必不可少的,这里不会讨论如何使用log4jdbc。

如何找到原始查询操作

上述的可记录查询包含一条标注,在大多数情况下它可以标识某条起始查询语句。如果一条查询是由加载引起的,那么标注便是/*load your.entity.Name*/。如果是一条命名查询,那么标注则包含查询的名称。

如果它是一个对应许多延迟加载的查询,标注则会包含对应类的名称和引发该操作的属性值等。

设置Hibernate的查询日志

为了获得查询日志,需要将如下标签加入会话工厂的配置文件中:


1

2

3

4

5

6

7

8

9

<bean id= "entityManagerFactory" >

  ...

  <property name="jpaProperties" >

  <props>

      <prop key="hibernate.show_sql" >true</ prop>

      <prop key="hibernate.format_sql" >true</ prop>

      <prop key="hibernate.use_sql_comments">true</prop>

  </props>

</property>

上面的示例展示了Spring实体管理工厂的配置。下面是对一些标签的解释:

  • show_sql:激活查询日志功能。
  • format_sql:优雅地输出Sql。
  • use_sql_comments:添加一条解释型标注。

为了记录查询语句的参数信息,log4j或者相对应的信息是需要的。


1

2

3

<logger name="org.hibernate.type">

    <level value="trace" />

</logger >

如果上述功能都不能运行

在大多数情况下,use_sql_comments创建的标注是足够用来标识查询的起始。但如果这还不够,我们可以标识和数据表名相关联的查询返回的实体,并在返回的实体构造函数中设置断点。

如果一个实体没有构造函数,我们可以创建一个构造函数并把断点设置在super()函数调用中。


1

2

3

4

5

6

7

@Entity

public class Employee {

    public Employee() {

        super(); // put the breakpoint here

    }

    ...

}

设置断点后,跳转到包含程序堆栈信息的Debug界面并从头到尾执行一遍。这样在调用栈中将会出现查询操作在何处被创建。

采集

#HUABAN_WIDGETS .HUABAN-red-normal-icon-button, .HUABAN-red-large-icon-button, .HUABAN-red-small-icon-button, .HUABAN-white-normal-icon-button, .HUABAN-white-large-icon-button, .HUABAN-white-small-icon-button { background-image: url({{imgBase}}/widget_icons_ie6.png)

时间: 2024-10-12 03:49:41

Hibernate调试——定位查询源头的相关文章

hibernate框架之-查询结果集返回类型

Hibernate支持HQL和SQL的查询,返回结果支持POJO类型或字段/数组的形式. 开发中用Hibernate进行数据库查询,用的是SQL.原来需要查询一个表的几乎所有字段,所以我使用了addEntity方法,将查询结果转换为映射的对象.后来需求变更,需要查询另外几个表的若干字段,不想继续用addEntity绑定新加的表(毕竟只有几个字段需要查询出来,将多余的字段都转换成映射对象,或只将需查询的字段转换为映射对象,从维护角度来说似乎都不太好),网上查了查:于是在addEntity后再使用a

Hibernate六 HQL查询

HQL查询一 介绍1.HQL:Hibernate Query Language,是一种完全面向对象的查询语言.使用Hibernate有多重查询方式可供选择:hibernate的HQL查询,也可以使用条件查询,甚至使用原生的SQL查询语句.Hibernate还提供了一种数据过滤功能,这些都用于删选目标数据.2.查询步骤:(1)获取Hibernate Session对象(2)编写HQL语句(3)以HQL语句为参数,调用Session的createQuery()方法创建查询对象(4)如果HQL语句包含

Hibernate(九)HQL查询

一.Hibernate提供的查询方式 OID查询方式:主键查询.通过get()或者load()方法加载指定OID的对象查询结果为一个 HQL查询方式:通过Query接口使用HQL语言进行查询 QBC查询方式:通过Criteria等接口和类进行是查询 本地SQL查询方式:使用原生的SQL语言进行查询 对象导航查询方式:通过已经加载的对象,导航到其关联对象 其中HQL和QBC是Hibernater提供的专业的查询方式 HQL查询方式为官方推荐的标准查询方式 二.HQL查询简述 HQL:Hiberna

hibernate中带查询条件的分页

所谓分页,从数据库中分,则是封装一个分页类.利用分页对象进行分页. 但,分页往往带查询条件. 分页类的三个重要数据:[当前页码数],[数据库中的总记录数],[每页显示的数据的条数] 原理:select * from  [表名] where   [字段名]  like   ['%条件%']    limit  [开始查询的索引],[每页显示的数据] 带查询条件的分页分两步 (1)第一步:查询出符合条件的数据的总条数 ---->select count(*) from [表名] where  [字段

使用hibernate原生sql查询,结果集全为1的问题解决

问题如下: String sqlTest ="select summary,summaryno from F_Summary"; List<Map<Object, Object>> listTest = this.getService().getListBySql(sqlTest); for (Map<Object, Object> m : listTest) { for (Object k : m.keySet()) { System.out.pr

hibernate的各种查询

Hibernate Query Language(HQL)Criteria QueryNative SQL下面对其分别进行解释select子句:有时并不需要取得对象的所有属性,这时可以使用select子句进行属性查询,如select s.name from Student s.例: void HQLselectDEMO()    {        TRegister user = new TRegister();        Session session = HibernateUtil.cu

hibernate N+1 查询

hibernate N+1 查询hibernate N+1 查询 2016-2-16 by Damon 在Session的缓存中存放的是相互关联的对象图.默认情况下,当Hibernate从数据库中加载Customer对象时,会同时加载所有关联的Order对象.以Customer和Order类为例,假定ORDERS表的CUSTOMER_ID外键允许为null,图1列出了CUSTOMERS表和ORDERS表中的记录. 以下Session的find()方法用于到数据库中检索所有的Customer对象:

js调试-定位到函数所在文件位置

原文:http://www.cnblogs.com/52cik/p/js-console-show-source.html 在控制台输入要查找的函数名如votePost 然后回车: 函数源码粗显啦,并且在右下角有个链接 blog-common.js?v=WE8o1xrgcTu07QVvwYqERqD7AA8fdJp_dgoE-crAT3k1:1 这个是什么意思呢?后面的 v=WE8o1xrgcTu07QVvwYqERqD7AA8fdJp_dgoE-crAT3k1 直接忽略好了这是版本号,防止缓存

Hibernate 笔记 HQL查询 条件查询,聚集函数,子查询,导航查询

本笔记继续使用dept部门表,emp员工表,一对多多对一双向映射. 1 条件查询 1.1    查询 员工表emp中 年龄eage小于30,月薪esal大于20000的员工姓名ename sql:select ename from emp where eage<? and esal >?; hql: select ename from Emp where eage<? and esal >? 1.2 问号的设置与别名 问号(?)的设置使用.setParameter(位置, 属性值)