从零打造在线网盘系统之Hibernate查询与更新技术

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

本章学习目标

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

本篇前言

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

标准查询API

要想使用标准查询API就要用到Hibernate的org.hibernate.Criteria接口,经过Session.createCriteria既能够建立Criteria对象github

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对象.sql

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

咱们一样能够进行模糊匹配数据库

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

使用MatchMode类静态常量,模糊匹配咱们也能够这样也是同样的api

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

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

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接口两条语句便可实现分页功能ssh

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框架的任意场景中熟练运用各类查询与更新技术

相关文章
相关标签/搜索