HQL是Hibernate Query Language的缩写,提供更加丰富灵活、更为强大的查询能力;HQL更接近SQL语句查询语法。
在有了前面学hibernate的知识后,运行hql的原理就可以很好的解释了。
1、hql操作的是实体类
看下图的代码,hql语句中Book不是表,而是实体类,所以hql操作的是实体类,不是表名
public void testList1() {
String hql = "from Book";
//Query --》preparestatement
Query query = session.createQuery(hql);
List<Book> list = query.list();
for(Book book:list) {
System.out.println(book);
}
}
2、hql 严格区别大小写,
bookName是Book实体类中的属性 不能写bookname等,要和属性名一致
public void testList2() {
String hql = "select bookName from Book";
List<String> list = session.createQuery(hql).list();
for(String bname : list) {
System.out.println(bname);
}
}
3、hql有命名参数 : ,而不是在用占位符?。
public void testList6() {
String hql = "from Book where bookId = :bookId";
Query query = session.createQuery(hql);
query.setParameter("bookId", 2);
Book book = (Book) query.getSingleResult();
System.out.println(book);
}
4、hql的下标从0开始计算位置(hibernate5之后不支持)
5、hql是面向对象的查询语言
6、别名
大多数情况下, 你需要指定一个别名, 原因是你可能需要 在查询语句的其它部分引用到Book
from Book as b |
as 是可选的。 可省略
7、hql查询语法
查全部:session.createQuery(hql).list();
单行单列:query.getSingleResult();
模糊查和分页:
设置分页的值
query.setFirstResult((page-1)*rows);
query.setMaxResults(rows);
注意:在hql中是不需要单引号的
public void testList9() {
String hql = "from Book where bookName like :bookName";
int rows = 3;
int page = 1;
Query query = session.createQuery(hql);
query.setParameter("bookName", "%三国%");
query.setFirstResult((page-1)*rows);
query.setMaxResults(rows);
List<Book> list = query.list();
for(Book b : list) {
System.out.println(b);
}
}
8、hql连表查询
hql连表查询的关键点是属性关联,hql的语句有两种写法①②
public void testList7() {
//① String hql = "select o.orderNo,oi.productId from Order o, OrderItem oi where o.orderId = oi.order.orderId ";
String hql = "select o.orderNo,oi.productId from Order o, OrderItem oi where o = oi.order";//②
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
for(Object[] b : list) {
System.out.println(Arrays.toString(b));
}
}
9、hql的聚合函数
和SQL的语句是一样的。
sum
avg
max
min
count
hql处理结果的情况有五种:
1、直接利用对象进行处理
@Test
public void testList1() {
String hql = "from Book";
//Query --》preparestatement query相当于预定义对象
Query query = session.createQuery(hql);
List<Book> list = query.list();
for(Book book:list) {
System.out.println(book);
}
}
原理解释:
hql操作Book的实体类,在实体类的配置文件Book.hbm.xml中自动生成了hql语句
select * from t_hibernate_book ,通过mvc返回了结果集 resultSet rs 拿到了Book的数据,
在mvc中通过建模拿到了Class clz = Book.class这个类,然后通过子控制器遍历实体类属性
while(rs.next()){
Book b = clz .newInstance();//new一个对象
Field[] declaredFields = clz.getDeclaredFields();
for(Filed f :Fileds){
f.set(b,rs.getObject(1));//给对象赋值
}
list.add(b);//把有值的对象装到list容器中
}
return list;//list集合返回
end----------------------------
2、查一列,返回的是引用数据类型
@Test
public void testList2() {
String hql = "select bookName from Book";
List<String> list = session.createQuery(hql).list();
for(String bname : list) {
System.out.println(bname);
}
}
3、通过Object[]进行接收,因为是数组,要看的时候可以用Arrays.toString()
@Test
public void testList3() {
String hql = "select bookId,bookName from Book";
List<Object[]> list = session.createQuery(hql).list();
for(Object[] book : list) {
System.out.println(Arrays.toString(book));
}
}
4、利用hibernate内置的函数(map)进行结果处理 ,map是一个函数 ,不是接口,不是类
@Test
public void testList4() {
String hql = "select new map(bookId,bookName) from Book";
List<Map> list = session.createQuery(hql).list();
for(Map book : list) {
System.out.println(book);
}
}
5、利用构造方法进行结果处理 ,当你给某一个类提供有参构造器时,也要提供无参构造器
@Test
public void testList5() {
String hql = "select new Book(bookId,bookName) from Book";
List<Book> list = session.createQuery(hql).list();
for(Book book : list) {
System.out.println(book);
}
}
hql与sql的区别
HQL | SQL |
操作的是类、属性 | 表名、列名 |
区分大小写,关键字不区分大小写 | 不区分大小写 |
别名 | 别名 |
有命名参数: | 不支持命名参数 |
?,从下标0开始计算位置(hibernate5之后不支持) | ?,从顺序1开始计算位置 |
面向对象的语言 | 面向结构的语言 |