Hibernate的HQL

Hibernate的优缺点
优点:

  • 简化了JDBC繁琐的编码
  • 对面向对象特性支持良好
  • 可移植性好

缺点:

  • 不适合需要使用数据库的特定优化机制的情况
  • 不适合大规模的批量数据处理
    配置文件的小技巧:
    可以点开配置文件的可视化窗口,进行鼠标的点击选择 生成一些配置.
  • 持久化类应符合 JavaBean规范,建议使用包装类型

对象-关系映射文件

  • 类-表
  • 属性-字段
  • 主键生成方式

根据主键列获取数据的方法:
Object get(Class c,serializable id) ; 获取没有的数据时 返回 NULL
Object load(Class c,serializable id) ; 获取没有的数据时 抛异常ObjectNotFoundException

Hibernate中java对象的三种状态

状态描述

脏检查及缓存机制

脏检查
在Hibernate中,数据前后发生变化的对象,成为脏对象.
当对象被加入Session缓存中时,Session会给这个对象的值类型的属性复制一份快照.当这个对象的值发生改变时,这个对象就是脏对象, Hibernate会对Session中持久状态的对象进行检测,即比较这个对象的当前属性与它的快照进行对比检查,这种判断成为脏检查.

刷新缓存机制
当Session缓存对象中的属性发生变化时,Session并不会立即执行脏检查和执行相关的SQL语句,而是在特定的时间点,即刷新缓存时才执行. 提高了应用程序访问数据库的访问性能.
Session会在以下时间点刷新缓存:

  • 应用程序显示调用Session的 flush() 方法时.
  • 应用程序调用 Transaction 的 commit() 方法时.

HQL部分

HQL是完全面向对象的,它可以理解继承多态关联之类的概念.
HQL是面向对象的查询语言,其中没有表和字段的概念,只有类、对象和属性的概念,所以我们查询的就是类 ,条件就是属性.这里要注意下!!!

编写HQL语句

1.from子句

from  cn.hibernate.entity.Dept    //HQL语句中的查询所有语句不能 用 select(查询所有就直接 from)
from  Dept     //与上述的代码一致  省略了包名
from  Dept   dept  //取别名  效果一致( 也可以用 As 指定 别名) 这里省略了As 关键字

2.select 子句
select子句用于选取对象和属性.

select  dept.deptName from Dept as dept  //获取部门的名称  (Dept类的 deptName属性)

3.where子句
where子句用于查询表达查询的限制条件

from  Dept   where deptName='SALES'    

4.使用表达式
表达式一般用在 where子句中. 下面举两个例子

from   Dept  dept  where lower(dept.deptName)='sales'  //转化成小写进行条件对比
from Emp where year(hirDate)=1980    //获取1980年入职的员工   year()函数获取日期字段的年份

5.order by 子句
order by 子句用于按指定属性排序

from Emp order by hirDate  asc   //员工入职时间 升序 排序 (desc 降序)
执行HQL语句

步骤:

  1. 获取Session对象
  2. 编写HQL语句
  3. 创建Query对象
  4. 执行查询,得到查询结果

代码:

String  hql="from Emp";  //定义HQL语句
Query query=currentSession().createQuery(hql);//构建Query对象

两种方式执行查询语句并获取查询结果
Query对象的 list() 方法 //返回类型 list接口

list()方法

只会执行一条查询语句,查询所有符合条件的记录.
Query对象的 iterate() 方法 //返回类型 iterator 迭代器 ( 注意: 与list()方法不同的是 需要在会话关闭之前测试查询结果)

iterate()方法

会首先查询出所有符合条件的主键值,然后在需要某一个对象的其他属性时,才生成按主键查询的SQL语句.即iterate()方法可能生成1+N条SQL语句.(有点延迟加载的意思)

在HQL语句中绑定参数

SQL字符串拼接不出现SQL注入等安全问题,我们使用参数绑定的方式.
1.按参数位置绑定
使用 **"?"**占位符来定义参数的位置,代码如下:

Query query=currentSession().createQuery(" from Emp where job=? and sal>?");  //使用占位符?来实现参数绑定
query.setString(0,job);     //注意的是第一个参数的下标 是 0
query.setDouble(1,sal);  //可使用setParameter()代替 无需类型的指定

2.按参数名称绑定
在HQL语句中可以定义命名参数,命名参数以 " : " 开头,代码如下:

Query query=currentSession().createQuery(" from Emp where :empJob=? and sal>:empSal ");
query.setString("empJob",empJob);
query.setDouble("empSal",empSal);   //可使用setProperties()代替 

除了以上的用于绑定参数的方法,Hibernate还提供了 setParameter() 方法,用来绑定任意类型的参数,当不便指定参数的具体类型时,可以使用 setParameter() 为参数赋值.代码如下:
1. setParameter() 不推荐

public List<Emp> getEmpListByJobAndSal(Object[]params){
  String hql="from Emp where job=? and sal>?";
  Query query = currentSession().createQuery(hql);
  for (int i = 0; i < params.length; i++) {
   query.setParameter(i, params[i]);            //此方式对比上面的 ? 占位符省去了复杂的类型指定
  }
  return query.list();
 }

2.setProperties() 推荐(符合Hibernate面向对象宗旨)
setProperties(): 绑定命名参数与一个对象的属性值

3.uniqueResult() 获取唯一结果
只有当查询结果不是唯一时,不能使用 query.uniqueResult() 方法,否则会出错.

分页和投影

在以前的项目中要实现分页功能,需要复杂的SQL语句来实现.Hibernate提供了简便的方法实现分页,即通过Query接口的 setFirstResult(int firstResult) 方法和 setMaxResults(int maxResults) 方法实现.
1.分页实现
setFirstResult(int firstResult) 方法,设置起始位置.
setMaxResults(int maxResults) 方法,设置最大返回结果数.
2.使用投影查询
有时数据展示并不需要获取对象的全部属性,而是只需要对象的某一个属性或某几个属性,或者需要通过表达式聚合函数等方式得到某些结果,此时可以使用投影查询.投影查询需要使用HQL的select 子句.对于投影结果的封装,有以下三种常见情况.
封装成Object对象

// 投影 (1)每条查询结果仅包含一列
 public List<Object> findAllNames() {
  String hql = "select dname from Dept";
  return currentSession().createQuery(hql).list();
 }

封装成Object数组

// 投影 (2)每条查询结果包含不止一列
 public List<Object[]> findDeptList() {
  String hql = "select deptno,dname from Dept";
  return currentSession().createQuery(hql).list();
 }

通过构造方法封装成对象
得到的对象不是持久化状态,仅用于封装结果.

 // 投影 (3)希望以对象的方式使用查询结果
 public List<Dept> findAllDeptList() {
  // 这种方式 要求Dept类中必须包含 Dept(Byte deptno, String dname) 和Demp()构造方法
  String hql = "select new Dept(deptno,dname) from Dept";
  return currentSession().createQuery(hql).list();
 }

记录下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值