hibernate中的qbc查询案例

hibernate的qbc查询

Criteria查询也叫做QBC查询(Query By Criteria),这种查询方式是Hibernate提供的“更加面向对象”的一种检索方式,说白了都是操作对象的一些查询方法来查询,因此这个查询掌握起来难度相对要大些。

本篇文章的示例代码下载地址
https://download.csdn.net/download/qq_29001539/12280873

QBC查询方式

// 1.查询所有
// 2.条件查询
// 3.模糊查询
// 4.范围查询
// 5.排序查询(order by)
// 6.分页查询
// 7.投影查询(只获取部分字段的结果)
// 8.聚集函数使用(聚合函数)(count、sum、avg、max、min等)
// 9.TOP N查询

学习参考

  • RESTRICTIONS用法:https://www.cnblogs.com/hahajava/p/9445480.html
  • Hibernate—QBC查询(1):https://blog.csdn.net/an_2016/article/details/52003559
  • Hibernate5.2值QBC查询:https://www.cnblogs.com/miller-zou/p/5737843.html


看到下面这张图有何感想,都是一些接口和实现类,主要的还是Criterion父级层次接口,后面都是围绕他来进行展开操作查询的,每个对象的提供方法不同,不过呢,有一个工具类帮我们实现了条件的指定,它就是org.hibernate.criterion.Restrictions,里面定义了不同的返回类型,但都始终是来自Criterion下或者它自己(Criterion)的类型,修饰符号为static,所以呢,我们可以直接通过类名称.方法的形式来调用具体方法。

在这里插入图片描述

1、查询所有

// 1.查询全部:获取所用用户信息
@Test
public void testList() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

2、条件查询

HQL运算符 QBC运算方法 含义
= SimpleExpression eq(String propertyName, Object value) 等于equal
<> SimpleExpression ne(String propertyName, Object value) 不等于not equal
> SimpleExpression gt(String propertyName, Object value) 大于greater than
>= SimpleExpression ge(String propertyName, Object value) 大于等于greater than or equal
< SimpleExpression lt(String propertyName, Object value) 小于less than
<= SimpleExpression le(String propertyName, Object value) 小于等于less than or equal
= PropertyExpression eqProperty(String propertyName, String otherPropertyName)
<> PropertyExpression neProperty(String propertyName, String otherPropertyName)
> PropertyExpression gtProperty(String propertyName, String otherPropertyName)
>= PropertyExpression geProperty(String propertyName, String otherPropertyName)
< PropertyExpression ltProperty(String propertyName, String otherPropertyName)
<= PropertyExpression leProperty(String propertyName, String otherPropertyName)
is null NullExpression isnull(String propertyName) 等于空值
is not null NullExpression isNotNull(String propertyName) 非空值
  • Criterion allEq(Map<String,?> propertyNameValues) --> 参数为Map对象,使用key/value进行多个等于的比对,相当于多个Restrictions.eq的效果
  • LogicalExpression and(Criterion lhs, Criterion rhs) 返回两个表达式的组合
  • Conjunction and(Criterion… predicates),返回多个表达式的组合
// 2.1条件查询:查询id=1的指定对象
@Test
public void testGetById() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    /*
     * 第一种方式:SimpleExpression eq(String propertyName, Object value)
     */
    // criteria.add(Restrictions.eq("sid", 1));// 设置sid=1

    /*
     * 第二种方式:Criterion idEq(Object value)
     * 该方式是根据你映射文件中hbm.xml配置里来的,id节点
     * <id name="sid" column="sid"> 
     *    <generator class="native" /> 
     * </id>
     */
    criteria.add(Restrictions.idEq(1));

    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

// 2.2条件查询:查询指定班级成绩合格的信息
@Test
public void testGetClazzByPassScore() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);

    /*
     * 第一种写法:分开添加
     */
    // criteria.add(Restrictions.eq("clazz", "s1t87"));// clazz = s1t87
    // criteria.add(Restrictions.ge("score", 61));// score >= 61

    /*
     * 第二种写法:LogicalExpression and(Criterion lhs, Criterion rhs)
     */
    criteria.add(Restrictions.and(// clazz = s1t87 and score >= 61
            Restrictions.eq("clazz", "s1t87"), 
            Restrictions.ge("score", 61)));
    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

// 2.3条件查询:查询性别男,成绩为100,clazz为s1t87的对象信息
@Test
public void testGetAllEq() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    /*
     * 第一种写法:Criterion allEq(Map<String,?> propertyNameValues)
     */
    // Map<String, Object> maps = new HashMap<String, Object>();
    // maps.put("gender", "男");
    // maps.put("score", 100);
    // maps.put("clazz", "s1t87");
    // criteria.add(Restrictions.allEq(maps));

    /*
     * 第二种写法:Conjunction and(Criterion... predicates)
     */
    criteria.add(Restrictions.and(// 添加条件:gender="男",score=100,clazz="s1t87"
            Restrictions.eq("gender", "男"), 
            Restrictions.eq("score", 100), 
            Restrictions.eq("clazz", "s1t87")));

    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

// 2.4条件查询:查询生日为空(null)的对象信息
@Test
public void testBirthIsNull() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    /*
     * 第一种方法:Criterion isNull(String propertyName)
     */
    // criteria.add(Restrictions.isNull("birth"));

    /*
     * 第二种方法: Criterion eqOrIsNull(String propertyName, Object value) 此方法有eq也有isNull
     */
    criteria.add(Restrictions.eqOrIsNull("birth", null));
    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

3、模糊查询

谈谈like和ilike:刚开始link还比较好容易理解,就是一个模糊查询的关键字,但是iLike是什么东西???
翻了一下:LIKE和ILIKE操作符可以模糊匹配字符串,LIKE是一般用法,ILIKE匹配时则不区分字符串的大小写
https://blog.csdn.net/sinat_41928169/article/details/82718319

LIKE模式(一般的用法)

  • SimpleExpression like(String propertyName, Object value)
  • SimpleExpression like(String propertyName, String value, MatchMode matchMode)
    在这里插入图片描述

iLIKE模式(该模式不分大小写)

  • LikeExpression ilike(String propertyName, Object value)
  • LikeExpression ilike(String propertyName, String value, MatchMode matchMode)
    在这里插入图片描述

MatchMode(是一个枚举类),我理解成是一种匹配模式,或者是一个匹配策略,它有如下的几种策略:

  • MatchMode.EXACT --> 字符串精确匹配.相当于"like ‘value’"
  • MatchMode.ANYWHERE --> 字符串在中间匹配.相当于"like ‘%value%’"
  • MatchMode.START --> 字符串在最前面的位置.相当于"like ‘value%’"
  • MatchMode.END --> 字符串在最后面的位置.相当于"like ‘%value’"
    在这里插入图片描述
// 3.1模糊查询:查询name含有“杰”的对象信息
@Test
public void testLikeName() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    criteria.add(Restrictions.like("name", "%杰%"));
    // criteria.add(Restrictions.ilike("name", "杰", MatchMode.ANYWHERE));
    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

// 3.2模糊查询:查询name含有“c”的对象信息(不分大小写)
@Test
public void testLikeName1() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    // criteria.add(Restrictions.ilike("name", "%c%"));
    criteria.add(Restrictions.ilike("name", "c", MatchMode.ANYWHERE));
    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

4、范围查询

  • 介于两者之间(lo >>low,hi >> high),可以实现的方法
    BetweenExpression between(String propertyName, Object lo, Object hi)
  • 或者or,可以实现的方法
    两者中:LogicalExpression or(Criterion lhs, Criterion rhs)
    多个:Disjunction or(Criterion… predicates)
  • 包含in(列表),可以实现的方法
    Disjunction or(Criterion… predicates)
    InExpression in(String propertyName, Collection values)
    InExpression in(String propertyName, Object[] values)
// 4.1范围查询:查询成绩在80~100分范围的对象信息
@Test
public void testScopeBetweenScore() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    criteria.add(Restrictions.between("score", 80, 100));// 设置score的范围80~100(含80,100)
    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

// 4.2范围查询:查找用户的密码是123456或者asdfghjkl这两种
@Test
public void testScopeOrPwd() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    criteria.add(Restrictions.or( // 添加一个or的条件,or的条件是123456和asdfghjkl
            Restrictions.eq("pwd", "123456"), Restrictions.eq("pwd", "asdfghjkl")));
    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

// 4.3范围查询:查找用户的密码有123456、010101、555555、999999等范围
@Test
public void testScopeInPwd() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    /*
     * 第一种方法:Disjunction or(Criterion... predicates)
     */
    criteria.add(
        Restrictions.or( // 添加多个范围的条件
            Restrictions.eq("pwd", "123456"), 
            Restrictions.eq("pwd", "010101"), 
            Restrictions.eq("pwd", "555555"),
            Restrictions.eq("pwd", "999999")));
    /*
     * 第二种方法:InExpression in(String propertyName, Object[] values)
     */
    // String[] parPwd = { "123456", "010101", "555555", "999999" };
    // criteria.add(Restrictions.in("pwd", parPwd));

    /*
     * 第三种方法:InExpression in(String propertyName, Object[] values)
     */
    // List<String> pwdList = new ArrayList<String>();
    // pwdList.add("123456");
    // pwdList.add("010101");
    // pwdList.add("555555");
    // pwdList.add("999999");
    // criteria.add(Restrictions.in("pwd", pwdList));

    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

// 4.4范围查询:查找班级不是s1t86、s1t87的
// (not in)技巧:其实就是加了一个  >>> not方法(in的查询方法)
@Test
public void testScopeNotClass () {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    
    Criteria criteria = session.createCriteria(User.class);
    /*
     * 第二种方法:InExpression in(String propertyName, Object[] values)
     */
     String[] parClazz = { "s1t86", "s1t87" };
     criteria.add(Restrictions.not(Restrictions.in("clazz", parClazz)));
    
    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

5、排序查询

  • Order.asc --> 根据传入的字段进行升序排序
  • Order.desc --> 根据传入的字段进行降序排序
// 5.排序查询:获取排序后的对象信息
@Test
public void testGetOrderList() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    criteria.addOrder(Order.asc("sid"));// 按照sid进行升序
    // criteria.addOrder(Order.desc("sid"));// 按照sid进行降序
    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

6、分页查询

// 6.分页查询
@Test
public void testPaging() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    criteria.setFirstResult(0);// 从0开始
    criteria.setMaxResults(5);// 显示5条数据
    List<User> lis = criteria.list();
    for (User user : lis) {
        System.out.println(user);
    }
    tx.commit();
    session.close();
    sessionFactory.close();
}

在这里插入图片描述

后面就要讲讲这个org.hibernate.criterion.Projections的使用,这个是用来支持投影、聚合、分组的

方法 说明
PropertyProjection groupProperty(String propertyName) 获取某一个属性
ProjectionList projectionList() 获取某几个属性
Projection distinct(Projection projection) distinct
Projection rowCount() count(*)
CountProjection count(String propertyName) count(xxx)
CountProjection countDistinct(String propertyName) distinct count(xxx)

7、投影查询

// 7.1投影查询:用于指定获取对象的某一个或某几个属性(返回数组)
@Test
public void testGetAppoint() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    
    Criteria criteria = session.createCriteria(User.class);
    /*
     * 第一种方法:PropertyProjection property(String propertyName)
     */
    // criteria.setProjection(Projections.projectionList()
    // .add(Projections.property("sid"))
    // .add(Projections.property("name"))
    // .add(Projections.property("gender"))
    // .add(Projections.property("clazz")));
    
    /*
     * 第二种方法:Property forName(String propertyName) 
     */
    criteria.setProjection(Projections.projectionList()
            .add(Property.forName("sid"))
            .add(Property.forName("name"))
            .add(Property.forName("gender"))
            .add(Property.forName("clazz")));
    
    List<Object[]> lis = criteria.list();
    for (Object[] objects : lis) {
        System.out.println("sid:"+objects[0]+"---name:"+objects[1]+"---gender:"+objects[2]+"---clazz:"+objects[3]);
    }
    
    tx.commit();
    session.close();
    sessionFactory.close();
}

// 7.2投影查询:查询所有的班级(去重复的值)
@Test
public void testGetClazzs() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    
    Criteria criteria = session.createCriteria(User.class);
    criteria.setProjection(Projections.distinct(Property.forName("clazz")));// distinct clazz
    List<String> lis = criteria.list();
    for (String objects : lis) {
        System.out.println("clazz:" + objects);
    }
    
    tx.commit();
    session.close();
    sessionFactory.close();
}

8、聚合函数

// 8.1聚合函数的使用:count统计总数据量
@Test
public void testCount() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    criteria.setProjection(Projections.rowCount());// 获取总行数
    Object obj = criteria.uniqueResult();// 获取唯一值
    System.out.println(obj);

    tx.commit();
    session.close();
    sessionFactory.close();
}

// 8.2聚合函数的使用:sum统计性别男、女的总人数
@Test
public void testSum() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    
    Criteria criteria = session.createCriteria(User.class);
    // select gender,sum(gender) from tableName group by gender
    criteria.setProjection(Projections.projectionList()
            .add(Property.forName("gender"))
            .add(Projections.sum("gender"))
            .add(Projections.groupProperty("gender"))
            );
    List<Object[]> obj = criteria.list();
    for (Object[] objects : obj) {
        System.out.println(objects[0]+"--"+objects[1]);
    }
    
    tx.commit();
    session.close();
    sessionFactory.close();
}

// 8.3聚合函数的使用:avg获取平均的分数
@Test
public void testAvgScore() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    
    Criteria criteria = session.createCriteria(User.class);
    criteria.setProjection(Projections.avg("score"));
    Object obj = criteria.uniqueResult();
    System.out.println("平均成绩:"+ obj);
    
    tx.commit();
    session.close();
    sessionFactory.close();
}

// 8.4聚合函数的使用:max获取最高的分数
@Test
public void testMaxScore() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    criteria.setProjection(Projections.max("score"));
    Object obj = criteria.uniqueResult();
    System.out.println("最高的分数:"+ obj);

    tx.commit();
    session.close();
    sessionFactory.close();
}

// 8.5聚合函数的使用:min获取最低的分数
@Test
public void testMinScore() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    criteria.setProjection(Projections.min("score"));
    Object obj = criteria.uniqueResult();
    System.out.println("最低的分数:"+ obj);
    
    tx.commit();
    session.close();
    sessionFactory.close();
}

9、TOP N查询

// 9.TOP N查询:返回s1t87班级中前五位分数最高的用户信息
@Test
public void testGetTopN() {
    Configuration cfg = new Configuration().configure();
    SessionFactory sessionFactory = cfg.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();

    Criteria criteria = session.createCriteria(User.class);
    ProjectionList prList = Projections.projectionList();
    prList.add(Projections.property("sid"));
    prList.add(Projections.property("name"));
    prList.add(Projections.property("score"));
    prList.add(Projections.property("clazz"));
        criteria.add(Restrictions.eq("clazz", "s1t87"))
                .setProjection(prList
                        .add(Projections.property("sid"))
                        .add(Projections.groupProperty("score")))
                .addOrder(Order.desc("score"))
                .setFirstResult(0)// 结果从第一条开始
                .setMaxResults(5);// // 只保留五条数据
    List<Object[]> lis = criteria.list();
    for (Object[] objects : lis) {
        System.out.println("sid:" + objects[0] + "\tname:" + objects[1] 
                + "\tscore:" + objects[2] + "\tclazz:" + objects[3]);
    }

    tx.commit();
    session.close();
    sessionFactory.close();
}
发布了69 篇原创文章 · 获赞 12 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_29001539/article/details/105182223
今日推荐