Hibernate之HQL

一、HQL入门

1、HQL的含义:

        HQL是Hibernate Query Language(专属于hibernate框架的一个查询语言)的缩写 

2. hql和sql区别/异同
           HQL                                                                            SQL
   类名/属性                                                                   表名/列名
   区分大小写,关键字不区分大小写                                 不区分大小写
   别名                                                                                  别名
   ?,从下标0开始计算位置(hibernate5之后不支持)          ?,从顺序1开始计算位置
   :命名参数                                                                     不支持:命名参数
   面向对象的查询语言                                                    面向结构查询语言

3、处理返回的结果集 
    ① 、单个对象—— select没有逗号 
    ② 、Object[]—— b.bookId, b.bookName 
    ③、 Map——new Map(b.bookId as bid, b.bookName as bname) 
    ④、 new  构造方法(attr1,attr2) String/long——new Book(b.bookId, b.price)            单个列段

4、展示

package lv.com.three.test;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

imort org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import lv.com.two.entity.Book;
import lv.com.two.util.SessionFactoryUtil;


public class HqlTest {
    private Session session;
    private Transaction transaction;
    
    @Before
    public void before() {
        session = SessionFactoryUtil.getSession();
        transaction = session.beginTransaction();
    }
    
    @Aftern   public void after() {
        transaction.commit();
        session.close();
    }
    
    /**
     * 返回对象(多个)
     */
    @Test
    public void testList1() {
        Query query = session.createQuery("from Book");
        List<Book> list = query.list();
        for (Book b : list) {
            System.out.println(b);
        }
    }
    
    /**
     * 返回单个列段,用字符串就可以接受
     */
    @Test
    public void testList2() {
        Query query = session.createQuery("select b.bookName as ss frogm Book b");
        List<String> list = query.list();
        for (String b : list) {
            System.out.println(b);
        }
    }
    
    /**
     * 查两个列段及以上,默认返回的是Object【】
     */
    @Test
    public void testList3() {
        Query query = session.createQuery("select b.bookId,b.bookName as ss from Book b");
        List<Object[]> list = query.list();
        for (Object[] b : list) {
            System.out.println(Arrays.toString(b));
        }
    }
    
    /**
     * 注意map是函数,所n以不区分大小写,返回的是map集合
     */
    @Test
    public void testList4() {
        Query query = session.createQuery("select new mAp(b.bookId,b.bookName) from Book b");
        List<Map> list = query.list();
        for (Map b : list) {
            System.out.println(b);
        }
    }
    
    /**
     * 查两个列段及以上,也可返回对象,前提是有对应的构造函数
     */
    @Test
    public void testList5() {
        Query query = session.createQuery("select new Book(b.bookId,b.bookName) from Book b");
        List<Book> list = qouery.list();
        for (Book b : list) {
            System.out.println(b);
        }
    }
    
    /**
     * HQL语句支持占位符

     *query对象相当于preparestatement
     */
    @Test
    public void testList6() {
//        Query query = session.createQuery("from Book where bookId = :bookId");
//        query.setParameter("bookId", 1);
//        Book b = (Book) query.getSingleResult();
//        System.out.println(b);
        
        Query query = session.createQuery("from Book where bookId in (:bookIds)");
        query.setParameterList("bookIds", new Integer[] {1,2,4});
//        List<Integer> params = new ArrayList<Integer>();
//        params.add(1);
//        params.add(2);
//        params.add(4);
//        query.setParameterList("bookIds", params);
        List<Book> list = query.list();
        for (Book b : list) {
            System.out.println(b);
        }
    }
    
    /**
     * HQL支持连接查询
     */
    @Test
    public void testList7() {
        Query query = session.createQuery.println(singleResult);

    }
    
    /**
     * HQL分页

     * FirstResult:代表起始下标;
     * MaxResults:一页展示的数据条数

     */
    @Test
    public void testList9() {
        Query query = session.createQuery("from Book");
        query.setFirstResult(2);
        query.setMaxResults(3);
        List<Book> list = query.list();
        for (Book b : list) {
            System.out.println(b);
        }
    }
}

二、Hibernate的BaseDao

自定义mvc的BaseDao思路:

①、完成一个基础版本的查询方法

②、分析共同之处(代码重复、思想重复)

③、解决方案,代码重复的抽取到父类,思想重复的用反射

        难点:通用分页的处理;思想重复的用反射

写Hibernate的BaseDao使用一样的思路:

1、完成一个基础版本的查询方法

public void testList10() {
        String hql="from Book where 1=1";
        Book book=new Book();
        if(book.getBookId() !=0) {
            hql+=" and bookId = :bookId";
        }
        if(book.getBookName() !=null) {
            hql+=" and bookName =: bookName";
        }
        Query query = session.createQuery(hql);
        if(book.getBookId() !=0) {
            query.setParameter("bookId", 1);
        }
        if(book.getBookName() !=null) {
            query.setParameter("bookName", "%圣墟%");
        }
        Book b = (Book) query.getSingleResult();
        System.out.println(b);
        }

2、分析共同之处

        ①、都有非空判断

        ②、都有query对象

        ③、具体值从对象/map

        ④、都需要分页:

                query.setFirstResult(2);//起始下标
                query.setMaxResults(3);//偏移量

        注意:分页是与PageBean的total,是优先查询出符合条件的总记录数

3、解决方案

BaseDao:

package lv.com.three.dao;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.query.Query;

import lv.com.three.hql.PageBean;


/**
 * 1、设置参数的问题 2、分页代码重复的问题
 * 
 * sql的通用分页的时候
 * 
 * getCountSql(sql) select count(1) from (sql) t
 * 
 * getCountHql(hql) hql = "from Book where bookName like :bookName" hql =
 * "select * from new Book(bid,bookName) where bookName like :bookName" select
 * count(1) hql
 * 
 * @author Administrator
 *
 */
public class BaseDao {

    /**
     * 通用的参数设值方法
     * 
     * @param map
     *            参数键值对集合
     * @param query
     *            预定义处理的hql对象
     */
    public void setParam(Map<String, Object> map, Query query) {
        if (map != null && map.size() > 0) {
            Object value = null;
            Set<Entry<String, Object>> entrySet = map.entrySet();
            for (Entry<String, Object> entry : entrySet) {
                // 例子的圣墟,但是有的时候它并不是单纯的字符串,可能是数组比如爱好,也可能是集合
                value = entry.getValue();
                if (value instanceof Object[]) {
                    query.setParameterList(entry.getKey(), (Object[]) value);
                } else if (value instanceof Collection) {
                    query.setParameterList(entry.getKey(), (Collection) value);
                } else {
                    query.setParameter(entry.getKey(), value);
                }
            }
        }
    }
    
    /**
     * 拼接
     * 将关键字from都转为大写取得下标进行截取

     * @param hql
     * @return
     */
    public String getCountHql(String hql) {
        // hql = "from Book where bookName like :bookName"
        // * hql = "select * from new Book(bid,bookName) where bookName like :bookName"
        int index = hql.toUpperCase().indexOf("FROM");
        return "select count(*) " + hql.substring(index);
    }
    
    /**
     * 通用查询方法
     * @param session
     * @param map
     * @param hql
     * @param pageBean
     * @return
     */
    public List executeQuery(Session session,Map<String, Object> map,String hql,PageBean pageBean) {
        List list = null;
        if(pageBean != null && pageBean.isPagination()) {
            String countHql = getCountHql(hql);
            Query countQuery = session.createQuery(countHql);
            this.setParam(map, countQuery);
            pageBean.setTotal(countQuery.getSingleResult().toString());
            
            Query query = session.createQuery(hql);
//            给预定义hql语句执行对象中的参数赋值,有多少赋值多少
            this.setParam(map, query);
            query.setFirstResult(pageBean.getStartIndex());
            query.setMaxResults(pageBean.getRows());
            list = query.list();
        }else {
            Query query = session.createQuery(hql);
//            给预定义hql语句执行对象中的参数赋值,有多少赋值多少
            this.setParam(map, query);
            list = query.list();
        }
        return list;
    }

}

BookDao:

package lv.com.two.dao;

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 lv.com.three.dao.BaseDao;
import lv.com.three.hql.PageBean;
import lv.com.three.hql.StringUtils;
import lv.com.two.entity.Book;
import lv.com.two.entity.Category;
import lv.com.two.util.SessionFactoryUtil;

public class BookDao extends BaseDao{
    public Integer addBook(Book book) {
        Session session = SessionFactoryUtil.getSession();
        Transaction transaction = session.beginTransaction();
        Integer bid = (Integer) session.save(book);
        transaction.commit();
        session.close();
        return bid;
    }
    
    public Integer addCategory(Category category) {
        Session session = SessionFactoryUtil.getSession();
        Transaction transaction = session.beginTransaction();
        Integer cid = (Integer) session.save(category);
        transaction.commit();
        session.close();
        return cid;
    }
    
    public Category getCategory(Category category) {
        Session session = SessionFactoryUtil.getSession();
        Transaction transaction = session.beginTransaction();
        Category c = session.get(Category.class, category.getCategoryId());
        transaction.commit();
        session.close();
        return c;
    }
    
    public Book getBook(Book book) {
        Session session = SessionFactoryUtil.getSession();
        Transaction transaction = session.beginTransaction();
        Book b = session.get(Book.class, book.getBookId());
        if (b != null && new Integer(1).equals(book.getInitCategories())) {
            Hibernate.initialize(b.getCategories());
        }
        transaction.commit();
        session.close();
        return b;
    }
    
    public void delBook(Book book) {
        Session session = SessionFactoryUtil.getSession();
        Transaction transaction = session.beginTransaction();
        session.delete(book);
        transaction.commit();
        session.close();
    }
    
    public void delCategory(Category category) {
        Session session = SessionFactoryUtil.getSession();
        Transaction transaction = session.beginTransaction();
        Category c = session.get(Category.class, category.getCategoryId());
        if(c!=null) {
            for (Book b : c.getBooks()) {
//                通过在被控方通过主控方来解除关联关系,最后被控方再做删除
                b.getCategories().remove(c);
            }
        }
        session.delete(c);
        transaction.commit();
        session.close();
    }
    
    
    /*
     * hql讲解用到(需要继承BaseDao)
     */
    /**
     * 没有使用BaseDao之前的代码
     * @param book
     * @param pageBean
     * @return
     */
    public List<Book> list(Book book, PageBean pageBean) {
        Session session = SessionFactoryUtil.getSession();
        Transaction transaction = session.beginTransaction();
        String hql = "from Book where 1 = 1";

        if (StringUtils.isNotBlank(book.getBookName())) {
            hql += " and bookName like :bookName";
        }

        Query query = session.createQuery(hql);
        
        if (StringUtils.isNotBlank(book.getBookName())) {
            query.setParameter("bookName", book.getBookName());
        }

        if (pageBean != null && pageBean.isPagination()) {
            query.setFirstResult(pageBean.getStartIndex());
            query.setMaxResults(pageBean.getRows());
        }
        List<Book> list = query.list();
        transaction.commit();
        session.close();
        return list;

    }
    
    /**
     * 使用BaseDao之后的代码
     * @param book
     * @param pageBean
     * @return
     */
    public List<Book> list2(Book book, PageBean pageBean) {
        Session session = SessionFactoryUtil.getSession();
        Transaction transaction = session.beginTransaction();
        String hql = "from Book where 1 = 1";
        Map<String, Object> map = new HashMap<String, Object>();

        if (StringUtils.isNotBlank(book.getBookName())) {
            hql += " and bookName like :bookName";
            map.put("bookName", book.getBookName());
        }
        List list = super.executeQuery(session, map, hql, pageBean);
        transaction.commit();
        session.close();
        return list;
    }
    
    /**
     * 使用原生SQL
     * @param book
     * @param pageBean
     * @return
     */
    public List list3(Book book, PageBean pageBean) {
//        String sql = "select b.*,o.* from t_hibernate_book b,t_hibernate_Order o";
        String sql = "select * from t_hibernate_book";
        Session session = SessionFactoryUtil.getSession();
        Transaction transaction = session.beginTransaction();
        List list = session.createSQLQuery(sql).list();
        transaction.commit();
        session.close();
        return list;
    }
}
 

进行测试:

    @Test

//    原生sql
    public void testList1() {
        PageBean pageBean=new PageBean();
        pageBean.setRows(3);
        Book book = new Book();
//        book.setBookName("%圣墟%");
        List<Book> list=this.bookDao.list3(book, pageBean);
        for (Book b : list) {
            System.out.println(b);
        }
    }

     @Test
//    使用BaseDao
    public void testList2() {
        PageBean pageBean=new PageBean();
        pageBean.setRows(3);
        Book book = new Book();
//        book.setBookName("%圣墟%");
        List<Book> list=this.bookDao.list2(book, pageBean);
        for (Book b : list) {
            System.out.println(b);
        }
    }

     @Test
//    在hibernate中使用原生sql
    public void testList3() {
        PageBean pageBean=new PageBean();
        pageBean.setRows(3);
        Book book = new Book();
        List<Object[]> list=this.bookDao.list3(book, pageBean);
        for (Object[] object : list) {
            System.out.println(Arrays.toString(object));
        }
    }

本期内容结束~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值