zoukankan      html  css  js  c++  java
  • 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语句可以有更大的优化,多表联查的情况下更具优势,所以要结合实际中的使用场景使用不同的方式。

  • 相关阅读:
    (04)-Python3之--字典(dict)操作
    word2vec简单介绍
    基于websocket爬虫
    Python数据结构之链表(1)-->单链表
    词云wordcloud
    Neo4j--第一章
    AHP(层次分析法) 附Python示例代码(觉得还可以的,帮忙点个赞,谢谢)
    几种归一化方法(Normalization Method)python实现
    EM算法之Python
    通俗易懂的EM
  • 原文地址:https://www.cnblogs.com/StarChen20/p/13600430.html
Copyright © 2011-2022 走看看