Hibernate的查询Query

这篇文章讲述的是Hibernate中查询数据的方式,如有错误或者不当之处,还望各位大神批评指正。

Hibernate中查询的几种方式

  1. 导航对象图检索方式:根据已经加载的对象导航到其他对象
  2. OID查询方式:根据查询对象的ID来查询兑现
  3. HQL查询方式:使用面向对象的查询语言
  4. QBC查询方式:使用QBC(Query By Criteria)API来查询对象
  5. 本地SQL语言查询:使用本地数据库的查询语言来检索

初始数据

注:省略hibernate的配置

Student表初始数据
这里写图片描述

通过OID查询数据get和load方法

  • 通过get方法查询学生
public Student getStudentById(int id) {
    // TODO Auto-generated method stub

    Session session = SessionUtil.openSession() ;
    Student student = (Student) session.get(Student.class, id) ;

    SessionUtil.closeSession(session);

    return student ;
}
  • 通过load方法查询学生
public Student loadStudentById(int id) {
        // TODO Auto-generated method stub

        Session session = SessionUtil.openSession() ;

        Student student = (Student) session.load(Student.class,id) ;

        SessionUtil.closeSession(session);

        return student ;

    }

get和load的区别

  1. get方法在查询对象时会立即加载对象,而load方法会返回一个代理对象,在用到该对象时才会加载对象。
  2. 若查询对象不存在,get方法会返回一个null,而load方法会抛出异常。
  3. load方法在需要初始化对象之前已经关闭session时可能会抛出LazyIInitializationException异常。

HQL查询语言查询

HQL是什么
Hibernate 查询语言(HQL)是一种面向对象的查询语言,类似于 SQL,但不是去对表和列进行操作,而是面向对象和它们的属性。 HQL 查询被 Hibernate 翻译为传统的 SQL 查询从而对数据库进行操作。

主要语法

1.FROM 语句(根据对象查询)

String hql = "FROM Student";
Query query = session.createQuery(hql);
List results = query.list();

2.AS 语句(给类起别名)

String hql = "FROM Student AS STD";
Query query = session.createQuery(hql);
List results = query.list();

3.SELECT 语句(选择想要的结果)

String hql = "SELECT STD.NAME FROM Student STD";
Query query = session.createQuery(hql);
List results = query.list();

4.WHERE 语句

String hql = "FROM Employee E WHERE E.id = 10";
Query query = session.createQuery(hql);
List results = query.list();

5.ORDER BY 语句(对结果排序)

String hql = "FROM Student STD WHERE STD.score > 60 ORDER BY STD.score DESC";
Query query = session.createQuery(hql);
List results = query.list();

6.GROUP BY 语句(组函数聚合)

String hql = "SELECT MAX(STD.score),STD.name FROM Student STD " +
             "GROUP BY STD.id";
Query query = session.createQuery(hql);
List results = query.list();

7.UPDATE 语句
与SQL类似
8.DELETE 语句
与SQL类似
9.INSERT 语句
与SQL类似

查询举例
- 查询所有学生姓名

public List<Student> listAllStudent() {
        // TODO Auto-generated method stub
        Session session = SessionUtil.openSession() ;
        String hql = "from Student" ;
        Query query = session.createQuery(hql) ;
        List<Student> results = query.list() ;
        return results;
    }

1.预编译查询

  • 查询分数大于60的学生
//写法一:占位符
        String hql = "FROM Student WHERE score > ?" ;
        Query query = session.createQuery(hql) ;
        query.setFloat(0, 60) ;
        List<Student> passStd = query.list() ;
//写法二:命名参数
        String hql2 = "FROM Student WHERE score > :pass ORDER BY score" ;
        Query query = session.createQuery(hql2) ;
        query.setFloat("pass", 60) ;
        List<Student> passStd = query.list() ;

2.HQL分页查询

  • 分页查询学生从0开始,每页2人
String hql = "FROM Student" ;
        Query query = session.createQuery(hql) ;
        int pageNum = 2 ; //分页中的第二页
        int pageSize = 2 ; //每页两个记录
        query.setFirstResult((pageNum - 1)*pageSize) //从第几个开始检索
             .setMaxResults(pageSize); //每页显示2条记录
        List<Student> passStd = query.list() ;

3.HQL查询嵌套到*.hbm.XML文件

  • 配置xml实现按名字查询学生

Student.hbm.xml中

<query name="findStudentById">
       <![CDATA[
            FROM Student WHERE id = :id 
       ]]> 
</query>

注:CDATA全称character data,翻译为字符数据。我们在写XML文档时,有时需要显示字母,数字和其它的符号本身,比如”<”,而在XML中,这些字符已经有特殊的含义,我们怎么办呢?这就需要用到CDATA语法。语法格式如下:<![CDATA[这里放置需要显示的字符]]>

使用时:

String hql = "findStudentById" ;
Queryquery = session.getNamedQuery(hql) ;
query.setInteger("id", 3) ;
List<Student> passStd = query.list() ;

4.投影查询
- 查询所有学生

/*写法一:*/
String hql = "SELECT s.id , s.name , s.score FROM Student s" ;
        Query query = session.createQuery(hql) ;

        List<Object[]> stdList= query.list() ;
        for(int i=0 ; i<stdList.size() ; i++){
            System.out.println(Arrays.asList(stdList.get(i)));
        }
/*写法二:直接封装成对象*/
        String hql = "SELECT new Student(id,name,score)"
                + "FROM Student s" ;
        Query query = session.createQuery(hql) ;

        List<Student> stdList = query.list() ;
        for(int i=0 ; i<stdList.size() ; i++){
            Student std = stdList.get(i) ;
            System.out.println(std.name);
        }
/*注:第二种方法需要在对应的类里写上构造方法。*/

分组函数的使用

  • 查询学生的平均分
String hql = "SELECT AVG(score) "
                + "FROM Student " ;
Query query = session.createQuery(hql) ;

List<Object[]> stdList = query.list() ;
for(int i=0 ; i<stdList.size() ; i++){
    System.out.println(stdList.get(i));
}

QBA限定查询

特点
QBC特点:提供面向对象的接口,编译时就可被解析,便于排错调试,扩展性好,允许用户扩展Criteria接口.。

劣势
可读性差,功能没有HQL强大,不支持报表查询和子查询。

  • 查询id为4的学生
        /**
         * 在QBC中通过 Criteria来表示
         * Criteria可以通过Restrictions静态方法得到
         * */
        Criteria criteria = session.createCriteria(Student.class) ;
        criteria.add(Restrictions.eq("id", 4)) ;

        Student student = (Student) criteria.uniqueResult() ;
        System.out.println(student.name);

其他限定方法

1. Restrictions.eq() 对应sql的("="2. Restrictions.gt() 对应sql的(">"3. Restrictions.ge() 对应sql的(">="4. Restrictions.lt() 对应sql的("<"5. Restrictions.le() 对应sql的("<="6. Restrictions.between() 对应sql的(between)
7. Restrictions.like() 对应sql的(like语句)
8. Restrictions.in() 对应sql的("in"9. Restrictions.and() 对应sql的("and"10. Restrictions.or() 对应sql的("or"

本地SQL查询

  • 查询所有学生(使用本地SQL查询方式)
String sql = "select * from student" ;
Query query = session.createSQLQuery(sql) ;

List<Object[]> stdList = query.list() ;

for(int i=0 ; i<stdList.size() ; i++){
    System.out.println(Arrays.asList(stdList.get(i)));
}

猜你喜欢

转载自blog.csdn.net/u013634252/article/details/80746809