这篇文章讲述的是Hibernate中查询数据的方式,如有错误或者不当之处,还望各位大神批评指正。
Hibernate中查询的几种方式
- 导航对象图检索方式:根据已经加载的对象导航到其他对象
- OID查询方式:根据查询对象的ID来查询兑现
- HQL查询方式:使用面向对象的查询语言
- QBC查询方式:使用QBC(Query By Criteria)API来查询对象
- 本地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的区别
- get方法在查询对象时会立即加载对象,而load方法会返回一个代理对象,在用到该对象时才会加载对象。
- 若查询对象不存在,get方法会返回一个null,而load方法会抛出异常。
- 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)));
}