Hibernate高级

深入Hibernate

一、Hibernate数据查询

HQLHibernate查询语言,它是Hibernate提供的一种面向对象的查询语言。

(1)在查询语句中设定各种查询条件

(2)支持动态绑定参数

(3)支持投影查询、分页查询、连接查询、分组查询,子查询

(4) 内置了一些聚集函数

Hibernate中的Query接口就是专门用来执行HQL语句的查询接口。

1.创建查询对象

 

Query query=session.createQuery(“from Dept”);

2.执行查询列出结果

1)列出所有的结果

 

List<Dept> depts=query.list();
for(Dept dept:depts){…}

2)列出单个结果

 

Query query=session.createQuery(“from Dept where id=1”);
query.setMaxResults(1);
Dept dept=(Dept)query.uniqueResult();

3)迭代访问结果

 

Iterator<Dept> it=query.iterate();
While(it.hasnext()){
}

 二、HQL 基本语法:持久化类名区分大小写

1)选择要查询的持久化类。

 

String hql=“from Dept”
Query query=session.createQuery(hql);
String hql=“from Dept as d”;

2)投影查询

 

String hql="select id,name from Dept";
Query query=session.createQuery(hql);
List list=query.list();
int size=list==null?0:list.size();
for(int i=0;i<size;i++){
Object[] obj=(Object[])list.get(i);
System.out.println(obj[1]+“ ”+obj[2]);
}

针对选定属性创建一个类,提供以这两个属性为参数的构造方法,使用此类来封装查询结果。

3)where 条件子句

 

String hqlString="from Dept d where d.createdTime>='2010-01-01'";
Query query=session.createQuery(hqlString);
String hqlString="from Dept d where d.name like'java%' and d.employees is not empty and d.createdTime<current_date()";

 

4)绑定查询参数:

按参数名字绑定

 

String hql=“from Dept where id>:id and name like:likeName”
List<Dept> depts=session.createQuery(hql).setLong(“id”,new Long(ingputID)).setString(“likeName”,”%”+inputName+”%”).list();

按参数位置绑定

5distinct 过滤重复值

 

Select distinct createTime from Dept

6)聚集函数

 

select count(d) from Dept d

7order by 排序

 

From Dept d order by d.createdTime asc,d.name desc

8group by 对记录分组

 

Select count(e) from Employee e group by e.dept;

9having 对分组后数据进行条件过滤

 

Select e.dept.name from Eployee e group by e.dept having count(e)>1

 三、分页查询

Query接口提供两个用于分批显示查询结果的方法

 

setFirstResult(int firstResult):// 在记录集中从第几条记录开始取数据。默认是0。
setMaxResults(int maxResults)://设置每次查询返回的最大对象数。
session.beginTransaction();
String hql = "from Employee";
List<Employee> empls = session.createQuery(hql)
.setMaxResults(pageSize)
.setFirstResult((pageNo - 1) * pageSize)
.list();
session.getTransaction().commit();

批量修改和删除:直接通过SQL语句操作数据库,执行完后,当前session缓存中的数据与数据库中的数据不是同步的。

 

String hql=“delete Dept as d where d.name like:likeName”;
Query query=session.createQuery(hql).setString(“likeName”,”%三%”);
int count= query.executeUpdate();

 

四、连接查询

Inner join left outer join
Right outer join full join
String hql = "FROM Dept d JOIN d.employees e "
+ " WHERE d.name LIKE :likeName";

 

 

抓取连接查询 fetch

抓取:是指从数据库加载一个对象数据时,同时把它所关联的对象和集合的数据一起加载出来,以便减少SQL语句的数据,从而提高查询效率。

From Dept d left join Fetch d.employees e where d.name like “%web%”

 

子查询

From Dept d where (Select count(e) from d.employees e)>1

 

命名查询:是指将SQL查询语句编写在映射文件里,在程序中通过SessiongetNameQuery()方法来获取该查询语句。

<query name="findDeptsByCondition">
<![CDATA [from Dept d where d.name like :likeName ]]>
</query>
session.getNamedQuery("findDeptsByCondition")
.setString("likeName", "%a%")
.list();

 

命名查询:是指将SQL查询语句编写在映射文件里,在程序中通过SessiongetNameQuery()方法来获取该查询语句。

<query name="findDeptsByCondition">
<![CDATA [from Dept d where d.name like :likeName ]]>
</query>
session.getNamedQuery("findDeptsByCondition")
.setString("likeName", "%a%")
.list();

 五、Criteria Queries

Criteria叫标准化条件查询,是比HQL更面向对象的查询语句。称为QBC

Criteria接口:代表一个查询。它是一个查询条件的容器,通过add()方法向其实例中添加查询条件。

Criterion接口:代表一种面向对象的查询条件。它的实例是作为Criteria接口add()方法的参数添加到Criteria实例中的。

Restrictions类:是用来创建查询条件Criterion实例的工具类,它提供了一系列的静态方法用来设定查询条件并作为Criterion实例返回。

Criteria criteria = session.createCriteria(Employee.class);
Criterion criterion1 = Restrictions.ge("salary", new Double(4000.00));
Criterion criterion2 = Restrictions.like("loginName", "z%");
criteria.add(criterion1);
criteria.add(criterion2);
criteria.addOrder(Order.desc("id"));
List<Employee> list = criteria.list();
List<Employee> list2= session.createCriteria(Employee.class)
.add(Restrictions.ge("salary", new Double(4000.00)))
.add(Restrictions.like("loginName", "z%"))
.addOrder(Order.desc("id"))
.list();

 六、离线查询

DetachedCriteria类支持离线查询。所谓离线查询就是指一个Session范围之外创建好一个查询,然后在需要使用是再附加到一个Session实例上来执行它。

对于分层的web应用程序来说,web层需要传递一个查询条件列表给业务逻辑层,业务层对象获得这个条件后依次取出条件值,然后拼装出SQL查询语句。这里的一个难点是如何将用户的多项查询条件传入业务逻辑层。

 

Criteriasession是绑定的。

 

web层,使用DetachedCriteria来构造查询条件,然后将这个DetachedCriteria作为方法调用参数传递给业务逻辑层对象。而业务层对象获得DetachedCriteria之后,可以在session范围内直接构造Criteria,进行查询。这样,查询语句的构造脱离了session范围,完全被移植到web层实现。

//StudentDAO.java

public List findStudents(DetachedCriteria detchedCriteria){

List list=null; 

//打开session,开启事务

Criteria Criteria=detachedCriteria.getExecutableCriteria(session);

list=criteria.list();

//提交事务,关闭session

return list;

}
DetachedCriteria detchedCriteria=DetachedCriteria.forClass(Student.class);

String name=“获取名字”;

String age=“获取班级”;

if(name!=null&&name!=“”){ //如果填写了名字,添加查询名字的条件

detchedCriteria.add(Restrictions.like(“name”,name));

}

If(classes!=null&&classes!=“”}{

detchedCriteria.add(Restrictions.eq(“classes”,classes));

}

detchedCriteria.addOrder(Order.asc(“name”);

List list=StudentDAO.findStudents(detchedCriteria);

for(){…}

 七、示例查询(QBE

根据一个给定的实例类实例来构建一个条件查询的方式。

先创建一个对象样板,然后检索出所有和这个样板相同的对象。

在查询表单中填写的项,可以封装成一个对象,这就是对象样板。

 

public static void testQBE(Employee employee){
//开启事务
//根据传入的employee实例来创建查询条件
Example example = Example.create(employee)
.excludeZeroes() //排除0值的属性
.excludeProperty("color") //排除指定的属性
.ignoreCase() //对所有的字符串类型的属性值忽略大小写比较
.enableLike(); //对所有的字符串类型的属性值使用like比较
List<Employee> results = session.createCriteria(Employee.class)
.add(example) .list();
for (Employee empl : results) {
System.out.println(empl.getLoginName() + "," + empl.getSalary()); }
//提交事务 //关闭Session }
Employee empl=new Employee();
empl.setLonginName(“%z%”);
testQBE(empl);

 

 

八、Native SQL Queries

原生SQL查询,就是指直接使用标准SQL语句或特定数据库的SQL进行查询。对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过Session上调用createSQLQuery()来获取这个接口。

1.实体查询

Hibernate执行原生SQL查询后,自动把查询到的表格式的数据集封装到实体对象中。

 

 

九、小结

HQL功能最强大,适合各种情况,但动态查询构造起来不方便。

Criteria最适合动态条件查询,不太适合统计查询,QBE还不够强大,只适合相当简单的查询。

NativeSQL可以实现特定数据库的SQL,但可移植不好。

针对Web应用来说,动态查询,首先Criteria,但是涉及统计查询和非常复杂的关联查询,Criteria就无能为力了,这种情况下选择HQL

HQL常用来进行实体检索,要注意返回的list中的元素是实体还是实体数组

QBC 不会忽略配置文件中的预先抓取策略。

猜你喜欢

转载自zhangxing119.iteye.com/blog/1775097