Hibernate第六章知识点总结——第六章--高级查询

时间:2021-05-24 07:39:09

Hibernate第六章知识点总结——第六章--高级查询

 

关联映射回顾

 

事务管理概述

ACID/三种问题/四种隔离级别

Hibernate事务API

JDBC实现/JTA实现

锁机制

悲观锁/乐观锁

 

目标

 

熟练应用CriteriaQuery

掌握Criteria查询表达式

熟练应用HQL进行各种查询

掌握分页查询方式及机制

 

知识点预览

 

CriteriaQuery

Criteria查询表达式

HQL

分页查询方式

 

Criteria

 

1.       Criteria

a)         Criteria面向对象化查询接口,将数据查询条件封装为一个对象,可以把它看成传统SQL的对象化表示

 

 

Hibernate第六章知识点总结——第六章--高级查询

 

 

Hibernate第六章知识点总结——第六章--高级查询

 

Criteria查询表达式

 

1.       Criteria表达式

a)         Criteria本身只是个查询容器,具体的查询条件需要通过Cretiria.add方法添加到Criteria实例中。

b)        Expression具体描述查询条件,针对SQL语法,Expression提供了对应的查询限定机制。

 

2.       查询限定机制

 

Hibernate第六章知识点总结——第六章--高级查询

 

Hibernate第六章知识点总结——第六章--高级查询

 

 

Hibernate第六章知识点总结——第六章--高级查询

 

a)         Expression各方法属性名参数,为POJO中所对应的实际库表字段属性名(

大小写敏感),而非库表中实际字段名。

 

3.       Criteria 查询示例

a)         查询年龄大于18的用户:

Criteria c=session.createCriteria(User.class);

c.add(Expression.gt(“userAge”,18));

b)        查询年龄大于20小于30的用户:

Criteria c=session.createCriteria(User.class);

c.add(Expression.between(“userAge”,new Integer(20),new Integer(30)));

c)         或者:

c.add(Expression.gt(“userAge”,new Integer(20)));

c.add(Expression.lt(“userAge”,new Integer(30)));

 

4.       Criteria 复合查询

 

UserAddress属于一对多的关联关系,根据地址条件查询用户:

Criteria c=session.createCriteria(User.class);

Criteria c1=c.createCriteria(“addr”);

 

c1.add(Expression.like(“city”,”%shanghai%”));

 

SQL

Select  * from t_user user inner join t_addr addr on user.id=addr_user_id

 where addr.city like ‘%shanghai%’

 

5.       Criteria 分页和排序

a)         分页:

Criteria.setFirstResult(100);

Criteria.setMaxResults(20);

b)        排序:

Criteria.addOrder(Order.asc(“”));

Criteria.addOrder(Order.desc(“”));

 

6.       Criteria 分组与统计

 

Hibernate3新引入Projections Class进行封装分组、统计表达式。

Projections.groupProperty(“age”);

Projections.avg();

Projections.count();

Projections.max();

Projections.min();

……

 

HQL

 

1.       HQL概述

a)         HQLHibernate Query Language)提供更加丰富灵活、更为强大的查询能力;

b)        HQL更接近SQL语句查询语法;

[select/delete/update…][from…][where…][group by…][having…][order by…]

 

2.       实体查询—概述

a)         1String hql=from User;

b)        2hql=from com.oracle.entity.User;

Query q=session.createQuery(hql);

List userList=q.list();

c)         注意:

1、应用中存在同名类(包不同),要注意使用全类名方式

2HQL子句本身大小写无关,但是其中出现的类名和属性名必须注意区分大小写

 

3.       实体查询—多态查询

a)         查询对象存在继承关系时查询

String hql=“from Account”;

b)        查询数据库中所有库表记录

String hql=“from java.lang.Object”;

 

4.       实体查询—where子句

a)         语法

String hql=“from User  as u where u.userName like ‘z%’ ”;

as/where

b)        比较操作符

=,<>,<,>,>=,<=,between,not between,in,not in,is,like

c)         示例

String hql=“from User u where u.userAge>20”;

String hql=“from User u where u.userAge between 12 and 30”;

String hql=“from User u where u.name is null”;

 

5.       属性查询

a)         语法

List list=s.createQuery(“select  u.userName from User u”).list();

返回每个条目都是Obiect[ ]

b)        面向对象查询结果封装

List list=s.createQuery(“select new User(u.userName,u.userAge) from User  u”).list();

返回每个条目都是User对象,但是它只是内存状态下新对象,并不是持久化对象

c)         原生SQL函数支持

String hql=“select upper(u.userName) from User u”;

String hql=“select distinct u.userName from User u ”;

 

6.       实体更新与删除

a)         Hibernate3新功能,Hibernate2之前HQL仅用于数据查询,若想更新及删除,只能先查询出实体,在进行基于实体的操作

b)        语法

String hql=“update User set  userAge=18”;

String hql=“delete User where userAge>18”;

 

7.       分组与排序

a)         Order by

语法:String hql=from User u order by u.userAge desc

选项:asc/desc

b)        Group by

语法:String hql=select count(u) ,u.userAge from User u group  by u.userAge;

条件过滤:having

示例:查询超过10个人的年龄组

String hql=“select count(u),u.userAge from User u group by u.userAge having count(u)>10”

List list=s.createQuery(hql).list()

 

8.       参数绑定—直接书写

a)         直接写在HQL

String hql=“from User u where u.userAge>”+age;

b)        缺点

编码凌乱,可读性低

多个可变查询参数,HQL字符串的组合拼装代码将显得无序

难以进行性能优化

JDBC每次执行SQL时,数据库将对SQL进行解析和优化,并保存在缓存中,之后参数不同、语法相同sql,则直接将此缓存加以执行,避免SQL分析及优化开销,如果把参数直接写到SQL中,导致每次都是不同的SQL,增加数据库性能开销

安全风险(SQL  Injection

from User where name=‘zz’ or  ‘x’=‘x’ and pwd=‘123’

 

9.       参数绑定—占位符

a)         顺序占位符

Session方法填充

Query接口填充

b)        示例

 

s.find(“from User u where u.userName=?”,”zz”,Hibernate.STRING)

Query q=s.createQuery(“from User u where u.userName=? And u.userAge=?”);

q.setString(0,”zz”);

q.setInteger(1,21);

 

c)         引用占位符

Query接口填充

javaBean封装查询参数

d)        示例

Query q=s.createQuery(“from User u where u.userName=:name ”);

q.setString(“name”,”zz”);

Query q=s.createQuery(“from User u where u.userName=:name  and u.userAge=:age”);

user.setUserName();user.setuserAge();

q.setProperties(user);

 

10.   参数绑定—动态绑定优点

a)         性能优化

参数单独绑定,使得查询语法与参数数值相互独立

b)        安全优化

有效避免SQL注入

 

11.   引用查询—概述

a)         SQL语句混在代码中将破坏代码可读性,使得系统的可维护性降低

b)        实现SQL可配置化操作

 

12.   引用查询—配置文件

 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.oracle.entity.User" table="T_USER“ >
<id name="userId" type="java.lang.Integer">
<generator class="native" />
</id>
<property name="userName" type="java.lang.String"></property>
<property name="userAddress" type="java.lang.String"></property>
<property name="userAge" type="java.lang.Integer"></property>
</class>

<query name="queryByName">
<![CDATA[
from User u where u.userName=:name
]]>
</query>
</hibernate-mapping>


 

 

 

13.   引用查询—持久化代码片段

 

public class Test {
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
SessionFactory sf = null;
Session s1 = null;
Session s2 = null;
try {
sf = cfg.buildSessionFactory();
s1 = sf.openSession();
Query q=s1.getNamedQuery("queryByName");
q.setString("name", "zz");
System.out.println(q.list().size());

} catch (HibernateException e) {
e.printStackTrace();
}finally{
if(s1!=null){s1.close();}if(sf!=null){sf.close();}
}
}
}


 

 

14.   联合查询—概述

a)         inner join

b)        left outer join

c)         right outer join

d)        full join

 

Hibernate第六章知识点总结——第六章--高级查询

 

15.   联合查询—inner join

a)         语法

From User u inner join fetch u.addr

b)        结果集

 

 

Hibernate第六章知识点总结——第六章--高级查询

 

c)         fetch

表示Addr读出后立即填充到User对象(addr属性)中

若无,则返回Object[ ]包含UserAddr对象

 

16.   联合查询—left outer join

a)         语法

b)        From User u left outer join fetch u.addr

c)         结果集

 

Hibernate第六章知识点总结——第六章--高级查询

 

d)        SQL

e)         Select  * from T_USER user left outer join T_ADDR addr on user.id=addr.user_id

 

17.   联合查询—right outer join

a)         语法

From User u right outer join u.addr

b)        结果集

 

 

Hibernate第六章知识点总结——第六章--高级查询

 

 

c)         SQL

d)        Select  * from T_USER user right outer join T_ADDR addr on user.id=addr.user_id

 

18.   联合查询—full join

a)         语法

From User u full join fetch u.addr

b)        结果集

 

Hibernate第六章知识点总结——第六章--高级查询

 

 

c)         SQL

Select  * from T_USER user full outer join T_ADDR addr on user.id=addr.user_id

 

19.   子查询

a)         在当前查询中利用另外一条查询语句的结果

b)        示例

查询拥有两条及以上地址的用户

From User u whereselect count(*) from u.addr>1

c)         SQL

Select  * from T_USER u where ( (select count(*)  from T_ADDR addr where user.id=addr.user_id)>1)

 

20.   SQL查询—概述

a)         Hibernate提供了对原生SQL及存储过程(Hibernate3)的支持;

b)        HibernateSQL进行封装(与JDBC比较)

c)         只需要指定别名,ResultSet和实体的映射由Hibernate自动完成

 

21.   SQL查询

 

 

Hibernate第六章知识点总结——第六章--高级查询

 

Hibernate第六章知识点总结——第六章--高级查询

 

Hibernate第六章知识点总结——第六章--高级查询

 

Hibernate第六章知识点总结——第六章--高级查询

总结

 

Hibernate数据检索

Criteria

HQL

实体查询

属性查询

实体更新与删除

分组与排序

参数绑定

引用查询

联合查询

子查询

SQL查询

 

问题

 

比较几种连接查询

完善课堂案例熟练应用HQL查询语句