zoukankan      html  css  js  c++  java
  • 从零打造在线网盘系统之Hibernate查询与更新技术

    欢迎浏览Java工程师SSH教程从零打造在线网盘系统系列教程,本系列教程将会使用SSH(Struts2+Spring+Hibernate)打造一个在线网盘系统,本系列教程是从零开始,所以会详细以及着重地阐述SSH三个框架的基础知识,第四部分将会进入项目实战,如果您已经对SSH框架有所掌握,那么可以直接浏览第四章,源码均提供在GitHub/ssh-network-hard-disk上供大家参阅

    本章学习目标

    1. 掌握标准查询API的使用
    2. 掌握QBE
    3. 掌握HQL
    4. 掌握SQL

    本篇前言

    在前面两篇文章中我们基本会使用Hibernate操作数据库,但是基本都是使用的是Session接口进行操作,像这种根据索引进行检索数据库局限性非常大.为此Hibernate提供了很强大的查询技术,例如标准查询API,QBE,HQL,SQL等

    标准查询API

    要想使用标准查询API就要用到Hibernate的org.hibernate.Criteria接口,通过Session.createCriteria既可以创建Criteria对象

        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Criteria criteria = session.createCriteria(Product.class);
            criteria.setMaxResults(2);
            List list = criteria.list();
            for (Object var : list) {
                System.out.print(var.toString());
            }
            session.close();
        }
    

    在使用标准API进行查询的时候增加约束条件是一个SimpleExpression对象,由org.hibernate.criterion.Restrictions类的静态方法可以获得相应的SimpleExpression对象.

    criteria.add(Restrictions.eq("name", "中药"));
    

    我们同样可以进行模糊匹配

    criteria.add(Restrictions.like("name", "%中%"));
    

    使用MatchMode类静态常量,模糊匹配我们也可以这样也是一样的

    criteria.add(Restrictions.like("name", "中", MatchMode.ANYWHERE));
    

    在增加查询的约束条件的时候我们会这样使用,查询成绩大于90的学生并且是女生,或者怎么怎么样....,我们可以使用LogicalExpression改变他们的逻辑

        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Criteria criteria = session.createCriteria(Product.class);
            SimpleExpression id1 = Restrictions.eq("id", 1);
            SimpleExpression id11 = Restrictions.eq("id", 11);
            LogicalExpression logicalExpression = Restrictions.or(id1, id11);
            criteria.add(logicalExpression);
            List list = criteria.list();
            for (Object var : list) {
                System.out.print(var.toString());
            }
            session.close();
        }
    

    可以看到使用LogicalExpression逻辑变得非常臃肿,Hibernate提供了更便捷的解决方案,那就是使用Conjunction生成And关系,使用Disjunction生成or关系

            Disjunction disjunction = Restrictions.disjunction();
            disjunction.add(id1);
            disjunction.add(id11);
            criteria.add(disjunction);
    
            Conjunction conjunction = Restrictions.conjunction();
            conjunction.add(id1);
            conjunction.add(id11);
            criteria.add(conjunction);
    

    那么如何使用标准查询API进行分页查询呢?得益于Hibernate对不同数据库的封装,我们可以很便捷地进行分页,例如xxxxx limit0, 10这样的SQL我们平时经常见到,我们可以使用Criteria接口两条语句即可实现分页功能

            criteria.setFirstResult(0);
            criteria.setMaxResults(10);
    

    您阅读到这里的时候可以发现Criteria接口返回的都是List对象,如果我们知道一条索引id,我们根绝这个id去进行去进行查找,就没必要返回给我一个List集合了吧? 同样我们可以使用uniqueResult方法返回一个Object对象

            Session session = HibernateSessionFactory.getSession();
            Criteria criteria = session.createCriteria(Product.class);
            criteria.add(Restrictions.eq("id",1));
            Product product = (Product) criteria.uniqueResult();
    

    在处理多个实体Bean关联的情况下我们需要处理多个Criteria之间的关联,我们可以通过Criteria创建另一个Criteria对象,参数是一个属性名

            Session session = HibernateSessionFactory.getSession();
            Criteria productCriteria = session.createCriteria(Product.class);
            Criteria productDetailCriteria = productCriteria.createCriteria("productDetail");
            productDetailCriteria.add(Restrictions.eq("detatil", "肯定匹配不到我"));
            List list = productCriteria.list();
    

    我们可以使用AggregateProjection类进行聚合操作查询,例如查询一个表中的记录数

        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Criteria criteria = session.createCriteria(Product.class);
            criteria.setProjection(Projections.rowCount());
            Long count = (Long) criteria.uniqueResult();
        }
    

    QBE(Query By Example)

    除了使用标准查询API,我们还可以使用QBE进行查询

        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Criteria criteria = session.createCriteria(Product.class);
            Product product = new Product();
            product.setName("中药");
            criteria.add(Example.create(product));
            List list = criteria.list();
        }
    

    HQL(Hibernate Query Language)

    HQL是Hibernate框架提供的另一种操作数据的方式,其语法非常接近SQL,但却是面向对象的也就是说HQL所操作的都是持久化对象,而不是数据表

        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Query from_product = session.createQuery("from Product");
            List list = from_product.list();
        }
    

    我们在进行复杂的查询HQL都是游刃有余的

        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Query from_product = session.createQuery("select name from Product where id >0 or id<10");
            List list = from_product.list();
        }
    

    HQL和JDBC一样是支持占位符查询的

        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Query from_product = session.createQuery("select name from Product where id > :id");
            from_product.setInteger("id", 0);
            List list = from_product.list();
        }
    

    HQL进行分页查询跟标准查询API很是相似

        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Query from_product = session.createQuery("from Product");
            from_product.setFirstResult(0);
            from_product.setMaxResults(10);
            List list = from_product.list();
        }
    

    HQL同样支持聚合查询

        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Query from_product = session.createQuery("select count(*) from Product");
            Long count = (Long) from_product.uniqueResult();
        }
    

    HQL作为一种查询语言同样支持Update/Delete/Insert

        Query from_product = session.createQuery("xxxxxxx");
        from_product.executeUpdate();
    

    SQL

    虽然HQL可以完成大多数的操作,但是HQL并不支持数据库的所有特性,因此在需要的时候我们还是需要直接使用SQL操作数据库

        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            NativeQuery sqlQuery = session.createSQLQuery("select * from products p");
            sqlQuery.addEntity("p", Product.class);
            List<Product> list = sqlQuery.list();
        }
    

    本篇总结

    掌握Hibernate的查询与更新技术,能在Hibernate框架的任意场景中熟练运用各种查询与更新技术

  • 相关阅读:
    面试金典——模式匹配
    浅谈C语言中的联合体
    android recovery模式及ROM制作
    模拟键盘输入 : SendMessage, keybd_event, PostKeybdMessage
    在游戏中使用keybd_event的问题
    keybd_event函数用法
    C语言清空输入缓冲区的N种方法对比
    深究“字节对齐”的原因
    字节对齐
    网络安装CentOS 5.3
  • 原文地址:https://www.cnblogs.com/jimisun/p/9939831.html
Copyright © 2011-2022 走看看