zoukankan      html  css  js  c++  java
  • Hibernate的DetachedCriteria使用(含Criteria)

    1、背景了解:Hibernate的三种查询方式

    Hibernate总的来说共有三种查询方式:HQL、QBC和SQL三种,这里做简单的概念介绍,不详细进行展开。

    1.1 HQL(Hibernate Query Language)

    与所熟悉的SQL的语法差不太多,不同的就是把表名换成了类或者对象,如下示例:
    @Override 
    public SysUser findUserByLoginName(String pLoginName) {
        String hql = "from SysUser as u where u.loginName = ?";
        List<SysUser> users = getHibernateTemplate().find(hql, pLoginName); //pLoginName对应?
        return users.isEmpty() ? null : users.get(0);
    }

    1.2 SQL(Structured Query Language)

    static List sql() {
       Session s = HibernateUtil.getSession();
        Query q = s.createSQLQuery("select * from user").addEntity(User.class);
        List<User> rs = q.list();
        s.close();
        return rs;
    }

    缺点:违背了hibernate的跨平台优点,不易维护,不面向对象。不推荐使用。

    1.3 QBC(Query By Criteria)

    1.3.1 QBC查询的基本步骤

    这种方式比较面向对象方式,重点是有三个描述条件的对象:Restrictions,Order,Projections。使用QBC查询,一般需要以下三个步骤:
    • 使用Session实例的createCriteria()方法创建Criteria对象;
    • 使用工具类Restrictions的方法为Criteria对象设置查询条件,Order工具类的方法设置排序方式,Projections工具类的方法进行统计和分组;
    • 使用Criteria对象的list()方法进行查询并返回结果。

    1.3.2 Restrictions、Order、Projections的常用方法

    Restrictions类的常用方法(设置查询条件):
    返回值类型方法名称描述
    SimpleExpressionRestrictions.eq等于(equal)
    CriterionRestrictions.allEq使用Map,Key/Valu进行多个等于的比对
    SimpleExpressionRestrictions.gt大于(great than)
    SimpleExpressionRestrictions.ge 大于等于(great than or equal)
    SimpleExpressionRestrictions.lt小于(less than)
    SimpleExpressionRestrictions.le小于等于(less than or equal)
    CriterionRestrictions.between对应SQL的between
    SimpleExpressionRestrictions.like对应SQL的like
    CriterionRestrictions.in对应SQL的in
    LogicalExpressionRestrictions.andand关系
    LogicalExpressionRestrictions.or or关系
    CriterionRestrictions.isNull为空
    CriterionRestrictions.sqlRestriction SQL限定查询

    Order类的常用方法(设置排序方式):
    返回值类型方法名称描述
    OrderOrder.asc升序
    OrderOrder.desc降序

    Projections类的常用方法(统计和分组):
    返回值类型方法名称描述
    AggregateProjectionProjections.avg求平均值
    CountProjectionProjections.count统计某属性的数量
    CountProjectionProjections.countDistinct统计某属性不同值的数量
    PropertyProjectionProjections.groupProperty指定某个属性为分组属性
    AggregateProjectionProjections.max求最大值
    AggregateProjectionProjections.min求最小值
    ProjectionListProjections.projectionList创建一个ProjectionList对象
    ProjectionProjections.rowCount查询结果集中的记录条数
    AggregateProjectionProjections.sum求某属性的合计
    更多方法,以及方法的详细使用及解释,请参看在线APIHibernate API Documentation(3.2.7.ga)

    1.3.3 QBC的查询示例和基本理解

    接下来,基于以上的一些常用方法,我们先看两个示例:
    //查询匹配的账户adminList
    Criteria c=s.createCriteria(Admin.class);
    c.add(Restrictions.eq("aname",name));//eq是等于,gt是大于,lt是小于,or是或
    c.add(Restrictions.eq("apassword", password));
    List<Admin> list=c.list();

    //分页查询前10条
    Criteria criteria = session.createCriteria(Customer.class);
    criteria.addOrder( Order.asc("name") ); //排序方式
    criteria.setFirstResult(0);
    criteria.setMaxResults(10);
    List result = criteria.list()

    看到这里,流程大概很好理解,从方法名就知道无非是把各种条件往里面加最后就可以获得一个符合条件的list。那么,下面再延伸理解一下
    org.hibernate.Criteria实际上是个条件附加的容器如果想要设定查询条件,则要使用org.hibernate.criterion.Restrictions的各种静态方法传回org.hibernate.criterion.Criterion实例,传回的每个org.hibernate.criterion.Criteria实例代表着一个条件,你要使用org.hibernate.Criteria的add()方法加入这些条件实例。下面看个示例:
    //查找age等于(eq)20或(or)age为空(isNull)的User
    Criteria criteria = session.createCriteria(User.class);
    criteria.add(Restrictions.or( Restrictions.eq("age", new Integer(20)), Restrictions.isNull("age") ));
    List users = criteria.list();
    
    //实际上它产生的对应的sql如下
    Hibernate: 
    select 
        this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ 
    from 
        T_USER this_ 
    where 
        (this_.age=? or this_.age is null)

    1.3.4 复合查询

    复合查询就是在原有的查询基础上在进行查询,比如有Clazz班级,包含对象属性Student,那么我们希望查询 “包含学生姓名为Bob” 的班级,那么就可以使用复合查询:
    Criteria criteria = session.createCriteria(Clazz.class);
    Criteria criteriaInner = criteria.createCriteria(Student.class);
    criteriaInner.add(Restrictions.eq("name", "Bob"));
    List clazzList =  criteria.list();

    如果是DetachedCriteria,则是根据关联属性的名称,而非Class,如:
    Member member = MemberHelper.getCurrentLoginMember();
    DetachedCriteria criteria = DetachedCriteria.forClass(Picture.class);
    DetachedCriteria collectCriteria = criteria.createCriteria("collectRecordList");
    collectCriteria.add(Restrictions.eq("member", member));
    List<Picture> pictureList = Picture.listByCriteria(criteria, page, Order.desc("updateDate"));

    1.3.5 Hibernate中Criteria方式的基本使用流程

    所以,基于以上的的示例和理解,我们不难看出Criteria的基本使用流程:


    2、DetachedCriteria是什么,和Criteria有什么区别

    父接口CriteriaSpecification,其下有子接口Criteria和实现类DetachedCriteria,Criteria和DetachedCriteria均可使用Criterion和Projection设置查询条件。可以设置FetchMode( 联合查询抓取的模式 ) ,设置排序方式。对于Criteria还可以设置FlushModel(冲刷 Session 的方式)和LockMode(数据库锁模式)。

    Criteria和DetachedCriteria的主要区别在于创建的形式不一样,Criteria是在线的,所以它是由Hibernate Session进行创建的;而DetachedCriteria是离线的,创建时无需Session,它通过2个静态方法forClass(Class)forEntityName(Name) 进行DetachedCriteria 的实例创建。

    (另,Spring的框架提供了getHibernateTemplate ().findByCriteria(detachedCriteria) 方法可以很方便地根据DetachedCriteria来返回查询结果)

    所以它也称为离线条件查询,即建立一个DetachedCriteria对象,将查询的条件等指定好,然后在session.beginTransaction()后将这个对象传入。通常这个对象可以在表示层建立,然后传入业务层进行查询。

    3、DetachedCriteria的基本使用

    上面已经提到,Criteria和DetachedCriteria均可使用Criterion和Projection设置查询条件,设置排序方式。那么这里也无需过度展开,以一个简单的例子来示意吧:
    //查询id为1且在今天或今天之前出生的user的名单
    //1、创建DetachedCriteria并设置条件
    DetachedCriteria dc = DetachedCriteria.forClass(User.class);
    int id = 1;
    dc.add(Restrictions.eq("id", id));
    Date age = new Date();
    dc.add(Restrictions.le("birthday", age));
    
    //2、执行查询(Criteria   getExecutableCriteria(Session session))
    Session session = HibernateUtil.getSession();
    Criteria c = dc.getExecutableCriteria(session);
    List users = c.list();

    这里值得一提的是,DetachedCriteria并没有像Criteria一样有list()的方法来返回List,所以需要以此获取一个可执行的Criteria,达到真正执行查询的目的,我们看下官方的解释:
    org.hibernate.criterion
    
    Class DetachedCriteria
    
    getExecutableCriteria
    
    public Criteria getExecutableCriteria(Session session)
    Get an executable instance of Criteria, to actually run the query.

    4、参考链接



  • 相关阅读:
    JS,JQ及时监听input值的变化,MUI的input搜索框里的清除按钮的点击监听事件
    MUI 底部弹出的选择框
    MUI 拍照或选取照片上传作为头像
    多行文本文本输入框 textarea 可点击任意地方编辑的问题
    mui dtpicker 时间的设置 以及MUI的弹窗
    MUI 样式按钮的禁用
    利用渐变实现书本的效果
    调用sqlserver中的存储过程
    XmlHelper
    面试题 数据库sql
  • 原文地址:https://www.cnblogs.com/deng-cc/p/6428599.html
Copyright © 2011-2022 走看看