• hibernate的三种查询方式


    hibernate的查询方式常见的主要分为三种: HQL, QBC, 以及使用原生SQL查询(Session的查询)

    1)Query的查询:使用HQL语句或SQL语句完成查询

    2)Criteria的查询:通过方法和类中属性的关系,来设置查询条件,完成查询。

    3)Session的查询:按主键查询查询,方法为get或load

    一.HQL查询

    • HQL(Hibernate Query Language)提供了丰富灵活的查询方式,使用HQL进行查询也是Hibernate官方推荐使用的查询方式。

    • HQL在语法结构上和SQL语句十分的相同,所以可以很快的上手进行使用。使用HQL需要用到Hibernate中的Query对象,该对象专门执行HQL方式的操作。

                                                                                             查询所有示例

    1
    2
    3
    4
    5
    6
    7
    8
    
    session.beginTransaction();
    String hql = "from User"; // from 后跟的是要查询的对象,而不是表
    Query query = session.createQuery(hql);
    List<User> userList = query.list();
    for(User user:userList){
      System.out.println(user.getUserName());
    }
    session.getTransaction().commit();
    
                                       带where的查询示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    session.beginTransaction();
    String hql = "from User where userName = 'James'";
    Query query = session.createQuery(hql);
    List<User> userList = query.list();
    for(User user:userList){
      System.out.println(user.getUserName());
    }
    session.getTransaction().commit();
    /*
     在HQL中where语句中使用的是持久化对象的属性名,如上面示例中的userName。当然在HQL中也可以使用别名
    */
    String hql = "from User as u where u.userName = 'James'";
    /*
    过滤条件 
    在where语句中还可以使用各种过滤条件,如:=、<>、<、>、>=、<=、between、not between、
    in、not in、is、like、and、or等
    */
    
                                                                     获取一个不完整的对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    session.beginTransaction();
    String hql = "select userName from User";
    Query query = session.createQuery(hql);
    List<Object> nameList = query.list();
    for(Object obj:nameList){
       String name=(String)obj;
       System.out.println(name); } session.getTransaction().commit(); // 多个属性的话,需要用object[]接收 session.beginTransaction(); String hql = "select userName,userPwd from User"; Query query = session.createQuery(hql); List nameList = query.list(); for(Object obj:nameList){ Object[] array = (Object[]) obj; // 转成object[] System.out.println("name:" + array[0]); System.out.println("pwd:" + array[1]); } session.getTransaction().commit();
                                                              统计和分组查询
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    session.beginTransaction();
    String hql = "select count(*),max(id) from User";
    Query query = session.createQuery(hql);
    List nameList = query.list();
    for(Object obj:nameList){
      Object[] array = (Object[]) obj;
      System.out.println("count:" + array[0]);
      System.out.println("max:" + array[1]);
    }
    session.getTransaction().commit();
    /*  
     该条sql语句返回的是单条数据,所以还可以这样写
     单列数据用Object,多列数据用Object[]
    */
    Object[] object = (Object[]) query.uniqueResult();
    System.out.println("count:" + object[0]);
    System.out.println("max:" + object[1]);
    
                                                      更多写法
    1
    2
    3
    4
    5
    6
    7
    
    select distinct name from Student;
    select max(age) from Student;
    select count(age),age from Student group by age;
    from Student order by age;
    
                                                  HQL占位符
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    session.beginTransaction();
    String hql = "from User where userName = ?";
    Query query = session.createQuery(hql);
    // 索引从0开始 
    query.setString(0, "James");
    List<User> userList = query.list();
    for(User user:userList){
      System.out.println(user.getUserName());
    }
    session.getTransaction().commit();
    
                                                       HQL引用占位符
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    session.beginTransaction();
    String hql = "from User where userName = :name";
    Query query = session.createQuery(hql);
    query.setParameter("name", "James");
    List<User> userList = query.list();
    for(User user:userList){
      System.out.println(user.getUserName());
    }
    session.getTransaction().commit();
    
                                                 HQL分页
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    session.beginTransaction();
    String hql = "from User";
    Query query = session.createQuery(hql);
    query.setFirstResult(0);
    query.setMaxResults(2);
    List<User> userList = query.list();
    for(User user:userList){
      System.out.println(user.getUserName());
    }
    session.getTransaction().commit();
    

    1.1HQL语句不只支持查询功能,还支持修改以及删除功能

    1. public void doRemove(Integer id) throws Exception {  
    2.         // 注意,使用Hibernate删除时,必须先查询对象,再删除.  
    3.         // HibernateSessionFactory.getSession().delete(findById(id));  
    4.         String hql = "DELETE FROM News AS n WHERE n.id = ?" ;  
    5.         Query query = HibernateSessionFactory.getSession().createQuery(hql);  
    6.         query.setInteger(0, id);  
    7.         query.executeUpdate();  
    8.     }  

    注:使用HQL的删除可以不需要先查询,直接删除,支持一次删除多条数据
    开发中的选择:1)当删除一条数据时,直接使用session.delete()就可以,因为简单,hibernate不在乎那点查询的性能;

                             2)批量删除时,使用Hql形式,这是可以提高性能的方法,因为它中间省去了查询的步骤。

    1.2HQL语句修改功能

    1. public void doUpdate(News vo) throws Exception {  
    2.         // HibernateSessionFactory.getSession().update(vo);  
    3.         String hql = "UPDATE News AS n SET n.title = ?,n.content = ? WHERE n.id = ?" ;  
    4.         Query query = HibernateSessionFactory.getSession().createQuery(hql);  
    5.         query.setString(0, vo.getTitle());  
    6.         // ....其他参数一样设置  
    7.         query.executeUpdate();  
    8.     }  

    开发中的选择:1)如果是直接的修改功能,选择session.update()方法;

    2)如果是只修改某一字段,使用HQL方式。
    注:HQL语句不支持添加,但是Query支持添加。

    1.3针对HQL的查询功能,也支持写SELECT,可以通过编写SELECT,来只查询对象中某一个或某几个属性。

    但是对于多种字段不同类型的查询返回的,Hibernate中只能是数组。

    例如:

    1. public List testHQL() throws Exception {  
    2.         String hql = "SELECT n.id,n.title FROM News AS n";  
    3.         Query query = HibernateSessionFactory.getSession().createQuery(hql);  
    4.         return query.list();  
    5.     }  

    经过测试,发现当只查询一个字段时,直接返回该类型的List集合。

    但查询两个以上的字段时,返回的是List<Object[]>,每一条查询出的数据,使用Object[]来表示,这就很不方便。

    1. public void testHQL() throws Exception {  
    2.         List all = ServiceFactory.getINewsServiceInstance().testHQL();  
    3.         Object[] value1 = (Object[]) all.get(0);  
    4.         System.out.println(value1[1]);  
    5.     }  

    这样使用起来很麻烦,因此在Hibernate3.2以上的版本中,提供了一个自动转换类,可以将查询出的Object[],自动转换为pojo 对象。

    1. public List testHQL() throws Exception {  
    2.         String hql = "SELECT n.id AS id,n.title AS title FROM News AS n";  
    3.         Query query = HibernateSessionFactory.getSession().createQuery(hql);  
    4.         <span style="color:#cc0000;">query  
    5.                 .setResultTransformer(new AliasToBeanResultTransformer(  
    6.                         News.class));</span>  
    7.         return query.list();  
    8.     }  

    注:一般开发中不会使用这种方法,只有当表中的字段过多,但查询只需要其中的几个字段时,才会用到这种方法。

    1.4Hibernate还可以将语句写到配置文件中 

    1. <query name="findAll">  
    2.         FROM News AS n WHERE n.title LIKE ?  
    3.     </query>  

    通过程序读取配置文件,取得这段HQL,并生成Query对象,完成查询。 

    1. Query query = HibernateSessionFactory.getSession().getNamedQuery(  
    2.                 "findAll");  
    3.         query.setString(0, "%测试%");  
    4.         return query.list();  

    这种方式在Mybatis中普遍使用,但是在Hibernate中一般很少这样做。

    二.QBC(Query By Criteria)查询

    • Criteria对象提供了一种面向对象的方式查询数据库。Criteria对象需要使用Session对象来获得。

    • 一个Criteria对象表示对一个持久化类的查询。

                                            查询所有
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    session.beginTransaction();
    Criteria c = session.createCriteria(User.class);
    List<User> userList = c.list();
    for(User user:userList){
      System.out.println(user.getUserName());
    }
    session.getTransaction().commit();
    

      或                        

    1. public List<News> testCriteria() throws Exception {  
    2.         // 根据传入的pojo类型,查询该类型对应的全部数据  
    3.         Criteria c = HibernateSessionFactory.getSession().createCriteria(  
    4.                 News.class);          
    5.         return c.list();  
    6.     }  
                               如果想加入查询条件,需要使用Restrictions的各种方法来完成条件的拼写。 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    session.beginTransaction();
    Criteria c = session.createCriteria(User.class);
    c.add(Restrictions.eq("userName", "James"));
    List<User> userList = c.list();
    for(User user:userList){
      System.out.println(user.getUserName());
    }
    session.getTransaction().commit();
    
     或
    1. public List<News> testCriteria() throws Exception {  
    2.         // 根据传入的pojo类型,查询该类型对应的全部数据  
    3.         Criteria c = HibernateSessionFactory.getSession().createCriteria(  
    4.                 News.class);  
    5.         // 1、WHERE id = 26  
    6.         // c.add(Restrictions.eq("id", 26));  
    7.         // 2、WHERE id > 26  
    8.         // c.add(Restrictions.gt("id", 26));  
    9.         // 3、WHERE id < 26  
    10.         // c.add(Restrictions.lt("id", 26));  
    11.         // 4、WHERE id >= 26  
    12.         // c.add(Restrictions.ge("id", 26));  
    13.         // 5、WHERE id <= 26  
    14.         // c.add(Restrictions.le("id", 26));  
    15.         // 6、WHERE id <> 26  
    16.         // c.add(Restrictions.ne("id", 26));  
    17.         // 7、WHERE title LIKE '%测试%'  
    18.         // c.add(Restrictions.like("title", "%测试%"));  
    19.         // 8、WHERE id between 23 and 27  
    20.         // c.add(Restrictions.between("id", 23, 27));  
    21.         // 9、WHERE id IN (23,25,27)  
    22.         // List<Integer> allIds = new ArrayList<Integer>();  
    23.         // allIds.add(23);  
    24.         // allIds.add(25);  
    25.         // allIds.add(27);  
    26.         // c.add(Restrictions.in("id", allIds));  
    27.         // 10、复杂条件,需要使用and或or来连接各个条件  
    28.         // WHERE id = 23 OR (id <> 26 AND title LIKE '%测试%')  
    29.         c  
    30.                 .add(Restrictions.or(Restrictions.eq("id", 23), Restrictions  
    31.                         .and(Restrictions.ne("id", 26), Restrictions.like(  
    32.                                 "title", "%测试%"))));  
    33.         return c.list();  
    34.     }  

    如果想加入ORDER BY排序条件,需要使用Order对象。

    1. c.addOrder(Order.desc("id"));  

    如果想加入统计函数和分组函数,则需要用到Projection这个类

    1. <span style="white-space:pre">  </span>ProjectionList pro = Projections.projectionList();  
    2.         // 加入统计函数  
    3.         pro.add(Projections.rowCount());  
    4.         // 还可以加入分组条件  
    5.         pro.add(Projections.groupProperty("title"));  
    6.         c.setProjection(pro);  
                                                         Restrictions对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    方法名称                  对应SQL中的表达式
    ----------------------------------------------------------
    Restrictions.eq       field = value
    Restrictions.gt       field > value
    Restrictions.lt       field < value
    Restrictions.ge      field >= value
    Restrictions.le       field <= value
    Restrictions.between      field between value1 and value2
    Restrictions.in       field in(…)
    Restrictions.and      and
    Restrictions.or       or
    Restrictions.like     field like value
    
                                         示例
    1
    2
    3
    4
    5
    6
    
    Criteria c = session.createCriteria(User.class);
    c.add(Restrictions.like("userName", "J"));
    c.add(Restrictions.eq("id", 120));
    c.add(Restrictions.or(Restrictions.eq("userName", "James"),
      Restrictions.eq("userName", "Alex")));
    
                                     获取唯一记录
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    session.beginTransaction();
    Criteria c = session.createCriteria(User.class);
    c.add(Restrictions.eq("id", 120));
    User user = (User) c.uniqueResult();
    System.out.println(user.getUserName());
    session.getTransaction().commit();
    
                                               分页
    1
    2
    3
    4
    
    Criteria c = session.createCriteria(User.class);
    c.setFirstResult(0);
    c.setMaxResults(5);
    

                                           

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    session.beginTransaction();
    Criteria c = session.createCriteria(User.class);
    c.setProjection(Projections.sum("id"));
    Object obj = c.uniqueResult();
    System.out.println(obj);
    session.getTransaction().commit();
    
                                               Projections对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    方法名称                          描述
    -------------------------------------------------------
    Projections.sum           等于SQL中聚合函数sum
    Projections.avg           等于SQL中聚合函数avg
    Projections.count         等于SQL中聚合函数count
    Projections .distinct     去除重复记录
    Projections.max           等于SQL中聚合函数max
    Projections.min           等于SQL中聚合函数min
    Projections .groupProperty  对指定的属性进行分组查询
    
                                            多个统计与分组
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    session.beginTransaction();
    Criteria c = session.createCriteria(User.class);
    ProjectionList projectionList = Projections.projectionList();
    projectionList.add(Projections.sum("id"));
    projectionList.add(Projections.min("id"));
    c.setProjection(projectionList);
    // 和HQL一样,单列用Object,多列用Object[] 
    Object[] obj = (Object[]) c.uniqueResult();
    System.out.println("sum:" + obj[0]);
    System.out.println("min:" + obj[1]);
    
                                         排序
    1
    2
    3
    
    Criteria c = session.createCriteria(User.class);
    c.addOrder(Order.desc("id"));
    

              

                                          示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    session.beginTransaction();
    String sql = "select id,username,userpwd from t_user";
    List list = session.createSQLQuery(sql).list();
    for(Object item : list){
      Object[] rows = (Object[]) item;
      System.out.println("id:" + rows[0] + "username:"
        + rows[1] + "userpwd:" + rows[2]);
    }
    session.getTransaction().commit();
    
                                           addEntity()示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    session.beginTransaction();
    String sql = "select id,username,userpwd from t_user";
    // addEntity()可以告诉Hibernate你想要封装成对象的类型,然后自动为你封装
    SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
    List<User> list = query.list();
    for(User user : list){
      System.out.println(user.getUserName());
    }
    session.getTransaction().commit();
    
                                                    uniqueResult示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    session.beginTransaction();
    String sql = "select id,username,userpwd from t_user where id = 2";
    SQLQuery query = session.createSQLQuery(sql).addEntity(User.class);
    User user = (User) query.uniqueResult();
    System.out.println(user.getUserName());
    session.getTransaction().commit();
    

  • 相关阅读:
    c语言中限制用户输入整数
    c语言 输入验证(限制输入正数)
    c语言中只读取输入的一行字符的首个字符
    python如何通过代码自动免密登陆ssh
    计算机科学速成课 02:电子计算机、继电器、术语“bug”的来源、真空管、晶体管、发展路径 转
    golang ...用法
    01 _ 程序的运行过程:从代码到机器运行
    深入Golang调度器之GMP模型 转
    golang可视化
    修改默认输入法,用英文标点符号
  • 原文地址:https://www.cnblogs.com/wyongqi/p/7991845.html
Copyright © 2020-2023  润新知