作用:方便进行数据库操作
1.hql是基于实体属性进行查询的;sql是基于表实体进行查询的
2.hql区分大小写,关键字不区分大小写;sql不区分大小写
3.hql是面向对象的查询语言;sql是面向结构的查询语言
4.hql占位符下标从0开始(目前推荐使用:命名参数);sql占位符下标从1开始
这里以Book类为实例
/**
* 结果处理一:当结果集为集合,查单个也可以通过这种方式,只不过不需要遍历
*/
@Test
public void testList1() {
String hql = "from Book";
Query query = session.createQuery(hql);
List list = query.list();
for (Book book : list) {
System.out.println(book);
}
}
/**
* 结果处理二:当结果集为集合,并且只查询其中一列时
*/
@Test
public void testList2() {
String hql = "select bookName from Book";
Query query = session.createQuery(hql);
List list = query.list();
for (String bname : list) {
System.out.println(bname);
}
}
/**
* 结果处理三:当结果集为集合,并且查询两列及两列以上,使用Object[]
*/
@Test
public void testList3() {
String hql = "select bookId,bookName from Book";
Query query = session.createQuery(hql);
List
@Test
public void testList6() {
//此处的:bookIds相当于占位符,不要漏掉:
String hql = "from Book where bookId in (:bookIds)";
Query query = session.createQuery(hql);
List params = new ArrayList();
params.add(1);
params.add(2);
//为bookIds赋值,也可以使用下标,hql的下标是从0开始
query.setParameterList("bookIds",params);
List list = query.list();
for (Book book : list) {
System.out.println(book);
}
}
@Test
public void testList7() {
String hql = "select o.order_no,oi.product_id from Order o,OrderItem oi where o.order_id = oi.order.order_id";
//String hql = "select o.order_no,oi.product_id from Order o,OrderItem oi where o = oi.order";
Query query = session.createQuery(hql);
List
sum
avg
max
min
count
这里以count示例
@Test
public void testList8() {
String hql = "select count(*) from Book";
Query query = session.createQuery(hql);
Object obj = query.getSingleResult();
System.out.println(obj);
}
hql内部是有封装分页的,所以分页不需要我们自己写,只需要提供分页信息就行了
@Test
public void testList9() {
//数据库为mysql
String hql = "from Book where bookName like :bookName";
int rows = 3;//每页显示3条记录
int page = 1;//第一页
Query query = session.createQuery(hql);
query.setParameter("bookName", "%红%");//模糊查询
query.setFirstResult((page-1)*rows);//从第几条数据开始查,索引从0开始
query.setMaxResults(rows);
List list = query.list();
for (Book book : list) {
System.out.println(book);
}
}
示例:带条件的查询分页
public List list1(Book book,PageBean pageBean){
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
String hql = "from Book where 1=1";
if (StringUtils.isNotBlank(book.getBookName())) {
hql += " and book_name like :book_name";
}
Query query = session.createQuery(hql);
if (StringUtils.isNotBlank(book.getBookName())) {
query.setParameter("book_name", "%"+book.getBookName()+"%");
}
if (pageBean != null && pageBean.isPagination()) {
query.setFirstResult(pageBean.getStartPage());
query.setMaxResults(pageBean.getTotalPage());
}
List list = query.list();
return list;
}
注:setParameter方法是BaseDao封装的设置参数方法,所以代码中减少了赋值的代码,这也是BaseDao的一个好处,后面会有代码,这里主要看赋值以外的
从如上代码可以看到,随着查询条件的增加,那么对应的if判断就会很多,因此为了减少代码的冗余,可以对其进行封装
BaseDao封装:
package com.study.dao;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hibernate.Session;
import org.hibernate.query.Query;
import com.zking.util.PageBean;
/**
* BaseDao作用:
* 1.特定值赋值
* 2.分页
* 1.查总记录数
* 2.查询某一页纪录
* @author L
*
*/
public class BaseDao {
//1.参数赋值
public void setParameter(Query query,Map map) {
if (map == null || map.size() == 0) {
return;
}
Object value = null;
for (Map.Entry entry : map.entrySet()) {
value = entry.getValue();
if (value instanceof Collection) {
query.setParameterList(entry.getKey(), (Collection)value);
}
else if (value instanceof Object[]) {
query.setParameterList(entry.getKey(), (Object[])value);
}
else {
query.setParameter(entry.getKey(), value);
}
}
}
//2.1:统计记录数
public String getCountHql(String hql) {
int index = hql.toUpperCase().indexOf("FROM");
return "select count(*) " + hql.substring(index);
}
//2.2:分页
public List executeQuery(Session session,String hql,PageBean pageBean,Map map) {
if (pageBean != null && pageBean.isPagination()) {//是分页
String countHql = getCountHql(hql);
Query countQuery = session.createQuery(countHql);
setParameter(countQuery, map);
pageBean.setTotal(Integer.valueOf(countQuery.getSingleResult().toString()));
Query pageQuery = session.createQuery(hql);
setParameter(pageQuery, map);
pageQuery.setFirstResult(pageBean.getStartPage());
pageQuery.setMaxResults(pageBean.getTotalPage());
return pageQuery.list();
}
else {//不分页
Query query = session.createQuery(hql);
setParameter(query, map);
return query.list();
}
}
}
BaseDao封装好后,再进行上个案例的操作:要记得继承BaseDao
package com.study.dao;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;
import com.study.entity.Book;
import com.study.entity.TreeNode;
import com.zking.util.PageBean;
import com.zking.util.SessionFactoryUtils;
import com.zking.util.StringUtils;
public class BookDao extends BaseDao{
public List list2(Book book,PageBean pageBean){
Session session = SessionFactoryUtils.getSession();
Transaction transaction = session.beginTransaction();
String hql = "from Book where 1=1";
Map map = new HashMap();
if (StringUtils.isNotBlank(book.getBookName())) {
hql += " and book_name like :book_name";
map.put("book_name", "%"+book.getBookName()+"%");
}
List list = executeQuery(session, hql, pageBean, map);
transaction.commit();
session.close();
return list;
}
}
代码简洁了不少,至少我们成功去除了重复的代码
应用场景:当hql不满足需求,或者使用hql不再简化代码,想要使用sql代码时
将createQuery(hql)->createSQLQuery(sql)方法,就能使用sql代码了
例:
1.select * from book a,type b a.tid = b.tid where b.tname like '%玄%'
2.select * from book a,type b a.tid = b.tid where b.tid = 1
3.select * from book a,type b a.tid = b.tid where a.bname like '%完%'
以上是三条联表查询语句,因为业务不同,所以有时要对表进行不同的查询,如果联表的数量非常多,那么写sql时代码就会非常长,所以视图映射就是将重复sql代码封装,然后根据不同的业务,只需要写不同的条件即可
上述代码中重复的地方select * from book a,type b a.tid = b.tid
步骤
1.创建一个视图,将此代码进行封装
create view aaa
as
select * from book a,type b a.tid = b.tid
2.根据业务的不同,对视图添加不同的查询条件
假如我要根据书名查询
select * form aaa where bname like '%完%'
这样就可以达到简化代码的作用