hibernate的hql语句以及sql原生语句实现CRUD实例

Hql是什么,它跟Sql的区别是什么?

hql是Hibernate  Query Language的缩写,是hibernate独有的查询语言特性。

sql是Structured Query Language的缩写,为独立于各种数据库之间的结构化查询语言,除了 SQL 标准之外,大部分 SQL 数据库程序都拥有它们自己的私有扩展。

  HQL SQL
结构 面向类名/属性 面向数据表/列
大/小写 对象部分区分大小写,关键字部分不区分 不区分大小写
别名 支持 支持
?占位符 参数赋值时下标从0开始(已过时) 参数赋值时下标从1开始
命名参数:变量 支持命名参数方式实现参数绑定 不支持
抽象层次 面向对象     面向结构

查询部分

1.利用hql实现查询

1)查询结果集List<T>       

        String hql = "from Book";//如果时直接查询整个实体,hql可以直接省略select,用实体类名代替表名。
            Query<Book> query = session.createQuery(hql, Book.class);//获取查询对象。
            List<Book> list = query.list();//执行查询对象并且返回结果集。

2)查询单个结果T

            String hql = "from Book as b where b.bookId=1";//hql支持sql关键字带条件查询。
            Query<Book> query = session.createQuery(hql, Book.class);
            List<Book> list = query.list();

3)查询实体的多个属性返回的时List<Object[]>

            String hql = "select bookId,bookName from Book";//hql查询列名统一用类的属性名来代替。
            Query query = session.createQuery(hql);
            List list = query.list();
            list.forEach(bk->{
                System.out.println(Arrays.toString((Object[]) bk));//集合中每个元素都是Object[]数组,所以需要转换为数组,只返回所有的值(不返回列)。
            });  

4)利用new map()指定hql,必须要给列取上别名

            String hql = "select new map(b.bookId as bid,b.bookName as bname) from Book as b";//取别名须要带上as。
            Query query = session.createQuery(hql);
            List list = query.list();
            list.forEach(bk->{
                System.out.println(bk);//返回的集合中每个元素都是一个map对象。
            });

5)new 构造函数(属性名)方式

            String hql = "select new Book(bookId,bookName,price) from Book";//构造函数里面的属性必须与实体类中定义的属性顺序一致。
            Query query = session.createQuery(hql);
            List list = query.list();
            list.forEach(bk->{
                System.out.println(bk);
            });

6)命名参数方式,注意:1.冒号不要使用中文。2.问号占位符的方式可以使用(不推荐),下标从0开始。3.使用命名参数传值,必须在执行之前赋值。  

              String hql = "select bookId,bookName,price from Book where bookId=:bid";
              Query query = session.createQuery(hql);

            //在执行hql之前完成参数赋值
            //过时的方法:利用占位符?的方式,下标从0开始
            //query.setInteger(0, 1);
   //如果是多参数情况,比如from tbale where id in(?,?,?);
      
  //String hql = "select bookId,bookName,price from Book where bookId in(:ids);
//执行之前设置参数集合,完成赋值,然后执行
//query.setParameterList("ids",Arrays.asList(new Integer[]{1,2,3}));
//推荐使用setParameter方法指定参数值
query.setParameter("bid", 1);
List list = query.list();
list.forEach(bk
->{

System.out.println(Arrays.toString((Object[]) bk));
});

7)链接查询(可以使用List<Object[]>或new map()返回数据)

            String hql = "select b.bookId,b.bookName,b.price,c.categoryName from Book b inner join b.categories c ";
            Query query = session.createQuery(hql);
            List list = query.list();
            list.forEach(obj->{
                System.out.println(Arrays.toString((Object[]) obj));
            });

8)hql支持聚合函数

            String hql = "select new map(sum(b.price) as sum,max(b.price) as max,min(b.price) as min,avg(b.price) as avg,count(b.price) as count) from Book b";
            Query query = session.createQuery(hql);
            List list = query.list();
            list.forEach(obj->{
                System.out.println(obj);
            });

9)分页查询

            //定义页码和行数
            int page = 2;
            int rows = 4;
            String hql = "from Book";        
            Query<Book> query = session.createQuery(hql,Book.class);
            //在执行之前给参数赋值
            query.setFirstResult((page-1)*rows);//设置记录开始位置
            query.setMaxResults(rows);//设置展示行数
            List<Book> list = query.list();//执行查询
            list.forEach(System.out::println);

2.利用原生sql实现查询

1)查询返回List<T>

            String sql = "select * from t_book_hb";
            NativeQuery<Book> query = session.createNativeQuery(sql, Book.class);//创建sql的执行对象
            List<Book> list = query.list();
            list.forEach(System.out::println);

2)查询返回单个实体T

            String sql = "select * from t_book_hb where book_id =:bid";//使用命名参数方式
            NativeQuery<Book> query = session.createNativeQuery(sql, Book.class);
            //设置参数
            query.setParameter("bid",1);
            List<Book> list = query.list();
            list.forEach(System.out::println);

3)查询返回List<map>用于多表联查

            String sql = "select bk.*,ch.category_name from t_book_hb bk,t_book_category_hb bc,t_category_hb ch "
                    + "where bk.book_id=bc.bid and bc.cid=ch.category_id";//三表链接查询
            NativeQuery query = session.createNativeQuery(sql);
            query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);//设置返回方式为map对象
            List list = query.list();
            list.forEach(obj->{
                System.out.println(obj);
            });

4)视图(查询较多的联查语句创建视图方便查询)

            String sql = "select * from v_book_category";//数据库创建视图v_book_category
            NativeQuery query = session.createNativeQuery(sql);
            query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);//设置返回map对象
            List list = query.list();//执行
            list.forEach(obj->{
                System.out.println(obj);
            });

增删改部分

 1)hibernate方式

    public void updateBook(Book bk) {//打开session对象,SessionFactoryUtils封装了打开hibernate会话的方法
        Session session = SessionFactoryUtils.openSession();
        //打开事务
        Transaction transaction = session.beginTransaction();
        //执行增加操作(save),删除(delete),更新(update/merge)
        session.save(bk);//session.delete();/session.update();||session.merge();
        //提交事务
        transaction.commit();
        //关闭会话
        SessionFactoryUtils.closeSession();
    }

2)原生sql方式

    @SuppressWarnings({ "deprecation", "rawtypes" })
    public void updateSql(Category ct) {
        String sql = "insert into t_category_hb(category_name)values(:cname)";//定义原生sql语句,update或是delete,使用命名参数方式赋值
        //获取session对象
        Session session = SessionFactoryUtils.openSession();
        //开启并获取事务
        Transaction tran = session.beginTransaction();
        //创建原生sql对象
        NativeQuery query = session.createSQLQuery(sql);
        //赋值
        query.setParameter("cname", ct.getCategoryName());
        query.executeUpdate();//执行sql,注意删除语句,一般需要自己手动解除关联关系。
        //提交并关闭
        tran.commit();
        SessionFactoryUtils.closeSession();
    }

总结

hql和sql各有优劣,hql查询条件进行了面向对象封装,符合编程人员的思维方式,更加灵活便捷,但是对于多表联查来说配置繁琐。

而sql语句可以有更大的优化,多表联查的情况下更具优势,所以要结合实际中的使用场景使用不同的方式。

posted @ 2020-09-02 10:35  _未来可期  阅读(446)  评论(0编辑  收藏  举报