Hibernate进阶-笔记02-HQL和QBC检索
目录
- HQL检索
- QBC检索
- HQL与QBC对比
- 使用别名
- 查询结果排序
- 分页查询
- 查询单条记录
- HQL中绑定参数
- 设定查询条件
- 连接查询(未学习)
- 投影查询
- 分组与统计查询
- 动态查询
- 子查询(未学习)
1. HQL检索
HQL(Hibernate Query Language)是面向对象的查询语言,与SQL想比,SQL操作的是数据表,列的数据库对象,HQL所操作的对象是类,对象,属性等。
在Hibernate提供的各种检索方式中,HQL使用最广泛。
【语法】
[select 属性列表 ...]
from 类名
[where ...]
[group by ...]
[having ...]
[order by ...]
其中:
- select,where,group by,having,order by字句都是可选的
- 属性列表,多个属性列表用逗号隔开
- 类名, 要查询的类的名称
HQL查询中常用的关键字
HQL检索步骤
- 获取Hibernate的Session对象
- 编写HQL查询语句
- 以HQL语句作为参数,调用Session的createQuery()方法,创建Query对象
- 如果HQL中包含参数,调用Query对象的setXXX()为参数赋值
- 调用Query对象的list()等方法得到查询结果。
示例
/**
* 测试HQL检索
*/
@Test
public void testCriteriaBusiness_HQL(){
String address = "韶关";
Session session = HibernateUtil.getSession();
String hql = "from Customer c where c.address =:address";
Query query = session.createQuery(hql);
query.setString("address", address);
List<Customer> list = query.list();
for (Customer c : list) {
System.out.println(c);
}
HibernateUtil.closeSession();
}
2. QBC检索
QBC(Query By Criteria)是一种面向对象的查询方式,这种查询方式以函数API的方式动态地设置查询条件,组成查询语句。
QBC检索主要通过以下两个接口和一个工具类来实现:
- Criteria接口,代表一次查询
- Criterion接口,代表一个查询条件
- Restriction类,产生查询条件的工具类
HQL检索步骤
- 获取Hibernate的Session对象
- 调用Session的createCriteria()方法,创建Criteria对象
- 调用Criteria的add()方法,增加Criteria查询条件
- 执行Criteria的list()方法或uniqueResult()返回查询结果
示例
/**
* 测试QBC检索
*/
@Test
public void testCriteriaBusiness_QBC(){
String address = "韶关";
Session session = HibernateUtil.getSession();
//创建Criteria对象,以Customer的Class对象作为参数
Criteria criteria = session.createCriteria(Customer.class);
//增加Criteria查询条件
criteria.add(Restrictions.eq("address", address));
//获取结果
List<Customer> list = criteria.list();
for (Customer c : list) {
System.out.println(c);
}
}
3. HQL与QBC对比
4. 使用别名
通过HQL检索一个类的实例是,如果在查询语句的其他地方需要应用该类,则应该为这个类制定一个别名,以便于引用
【语法】
类名 as 别名
或
类名 别名
示例
from Customer as c where c.address =:address
或
from Customer c where c.address =:address
5. 查询结果排序
- HQL使用order by排序
- QBC使用org.hibernate.criterion.Order类排序
HQL的排序
【语法】
order by 属性列表[asc|desc]
- asc 升序(默认)
- desc 降序
【示例】
/**
* 查询结果排序 HQL
*/
@Test
public void testOrderByUsernameDesc_HQL(){
Session session = HibernateUtil.getSession();
String hql = "from Customer c order by c.username desc";
Query query = session.createQuery(hql);
List<Customer> list = query.list();
for (Customer c : list) {
System.out.println(c);
System.out.println();
}
}
QBC的排序
QBC排序使用Order类的asc()升序方法和desc()降序方法,返回值为Order类型
【语法】
criteria.addOrder(Order.asc("属性")); //升序
criteria.addOrder(Order.desc("属性")); //降序
【示例】
/**
* 查询结果排序 QBC
* addOrder()方法
*/
@Test
public void testOrderByUsernameDesc_QBC(){
Session session = HibernateUtil.getSession();
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(org.hibernate.criterion.Order.desc("username"));
List<Customer> list = criteria.list();
for (Customer c : list) {
System.out.println(c);
System.out.println();
}
}
6. 分页查询
HQL分页查询
HQL分页查询只要是通过Query接口的setFirstResult()和setMaxResults()结合使用来实现
【示例】
/**
* HQL分页查询
*/
@Test
public void testListPage_HQL(){
int pageNo = 2;
int perPageNum = 3;
Session session = HibernateUtil.getSession();
String hql = "from Customer c order by c.username desc";
Query query = session.createQuery(hql);
//从第2页开始
query.setFirstResult((pageNo - 1) * perPageNum);
//每页3条记录
query.setMaxResults(perPageNum);
List<Customer> list = query.list();
for (Customer c : list) {
System.out.println(c);
System.out.println();
}
}
QBC分页查询
Criteria分页查询方式与HQL类似,通过Criteria接口的setFirstResult() setMAxResults()方法结合使用来完成。
【示例】
/**
* QBC分页查询
*/
@Test
public void testListPage_QBC(){
int pageNo = 2;
int perPageNum = 3;
Session session = HibernateUtil.getSession();
Criteria criteria = session.createCriteria(Customer.class);
//从第2页开始
criteria.setFirstResult((pageNo - 1) * perPageNum);
//每页3条记录
criteria.setMaxResults(perPageNum);
List<Customer> list = criteria.list();
for (Customer c : list) {
System.out.println(c);
System.out.println();
}
}
7. 查询单条记录
【步骤】
- 先调用Query接口或Criteria接口的setMaxResults(1)方法,将最大的检索数设置为1
- 然后调用uniqueResult()方法返回一个Object类型的对象
HQL查询单条记录
【示例】
/**
* 查询单条数据 HQL
*/
@Test
public void testFindOneCustomer_HQL(){
Session session = HibernateUtil.getSession();
String hql = "from Customer c order by c.username desc";
Query query = session.createQuery(hql);
//查询单条记录 使用uniqueResult()方法 配合setMaxResults(1)方法
Customer customer = (Customer) query.setMaxResults(1).uniqueResult();
System.out.println(customer);
}
QBC查询单条记录
【示例】
/**
* 查询单条数据 QBC
*/
@Test
public void testFindOneCustomer_QBC(){
Session session = HibernateUtil.getSession();
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(org.hibernate.criterion.Order.desc("username"));
//查询单条记录 使用uniqueResult()方法 配合setMaxResults(1)方法
Customer customer = (Customer) criteria.setMaxResults(1).uniqueResult();
System.out.println(customer);
}
8. HQL中绑定参数
Hibernate 参数绑定机制在底层依赖了JDBC的PrepareStatement的预定义SQL语句功能。
有以下两种方式绑定参数
- 按照参数名字绑定
hql语句
from Customer c where c.username =:username
java代码调用
public Query setString(String name, String val);
- 按照参数位置绑定
hql语句
from Customer c where c.username = ? //该方法过时
//需换成JTA风格,即:在问号后面加上位置,从1开始
from Customer c where c.username = ?1
java代码调用
public Query setString(int position, String val);
【示例】
按照参数名字绑定
/**
* 按照参数名字绑定
*/
@Test
public void testFindCustomerByName(){
String name = "王五";
Session session = HibernateUtil.getSession();
String hql = "from Customer c where c.username = :name";
Query query = session.createQuery(hql);
query.setString("name", name);
List<Customer> list = query.list();
for (Customer c : list) {
System.out.println(c);
}
}
按照参数位置绑定
/**
* 按照参数位置绑定
*/
@Test
public void testFindCustomerByNamePosition(){
String name = "王五";
Session session = HibernateUtil.getSession();
String hql = "from Customer c where c.username = ?1";
Query query = session.createQuery(hql);
query.setString(1, name);
List<Customer> list = query.list();
for (Customer c : list) {
System.out.println(c);
}
}
9. 设定查询条件
HQL方式在where字句设定条件
where 条件
QBC方式使用Restriction类创建Criterion对象来设定条件
Criteria criteria = session.createCriteria(Customer.class)
.add(Restrictions.eq("username", "王五"));
图 HQL和QBC查询的各种运算
10. 连接查询(未学习)
11. 投影查询
投影查询是指结果仅包含部分试题或者部分的实体属性(不包含全部属性)。
投影查询通过select关键字来实现
【示例】
/**
* 投影查询
*/
@Test
public void testTouyingQuery(){
Session session = HibernateUtil.getSession();
String hql = "select new Customer(c.username, c.password, c.address) " +
"from Customer c inner join c.orders o where c.username like '李%'";
Query query = session.createQuery(hql);
List<Customer> list = query.list();
for (Customer c : list) {
System.out.println(c);
}
}
12. 分组与统计查询
HQL统计查询
【示例】
/**
* 分组与统计查询 HQL
*/
@Test
public void testQueryFunction_HQL(){
Session session = HibernateUtil.getSession();
//count函数
String hql_count = "select count(c.id) from Customer c";
Long count = (Long) session.createQuery(hql_count).uniqueResult();
System.out.println("Customer数量:" + count);
//max 和 min函数
String hql_max_min = "select max(c.id), min(c.id) from Customer c";
Object[] objects = (Object[]) session.createQuery(hql_max_min).uniqueResult();
Integer maxId = (Integer) objects[0];
Integer minId = (Integer) objects[1];
System.out.println("maxId = " + maxId + "\nminId = " + minId);
//avg函数
String hql_avg = "select avg(c.id) from Customer c";
Double avg = (Double) session.createQuery(hql_avg).uniqueResult();
System.out.println("avg = " + avg);
}
QBC统计查询
/**
* 分组与统计查询 QBC
*/
@Test
public void testQueryFunction_QBC(){
Session session = HibernateUtil.getSession();
//count函数
Criteria criteria_count = session.createCriteria(Customer.class);
criteria_count.setProjection(Projections.count("id"));
Long count = (Long) criteria_count.uniqueResult();
System.out.println("Customer数量:" + count);
//max 和 min函数
Criteria criteria_max_min = session.createCriteria(Customer.class);
ProjectionList pList = Projections.projectionList();
pList.add(Projections.max("id"));
pList.add(Projections.min("id"));
criteria_max_min.setProjection(pList);
Object[] objects = (Object[]) criteria_max_min.uniqueResult();
Integer maxId = (Integer) objects[0];
Integer minId = (Integer) objects[1];
System.out.println("maxId = " + maxId + "\nminId = " + minId);
//avg函数
Criteria criteria_avg = session.createCriteria(Customer.class);
criteria_avg.setProjection(Projections.avg("id"));
Double avg = (Double) criteria_avg.uniqueResult();
System.out.println("avg = " + avg);
}
13. 动态查询
动态查询是指在开发过程中无法确定要查询的字段时采用的查询方式
HQL动态查询方式
【示例】
/**
* HQL动态查询
*/
@Test
public void testDynamicQuery_HQL(){
String username = "张三";
String password = "123456";
findCustomerByHQL(username, password);
}
public void findCustomerByHQL(String username, String password){
Session session = HibernateUtil.getSession();
StringBuffer buffer = new StringBuffer();
//生成基础的SQL语句
buffer.append("from Customer c where 1=1 ");
//如果参数username满足条件,则加入语句中
if (username != null){
buffer.append("and lower(c.username) like :username");
}
if (password != null && !password.equals("")){
buffer.append(" and c.password = :password");
}
Query query = session.createQuery(buffer.toString());
if (username != null){
query.setString("username", "T%");
}
if (password != null && !password.equals("")){
query.setString("password", password);
}
List<Customer> list = query.list();
for (Customer c : list) {
System.out.println(c);
System.out.println();
}
}
QBC动态查询方式
【示例】
/**
* QBC动态查询
*/
@Test
public void testDynamicQuery_QBC(){
String username = "张三";
String password = "123456";
findCustomerByQBC(username, password);
}
public void findCustomerByQBC(String username, String password){
Session session = HibernateUtil.getSession();
Criteria criteria = session.createCriteria(Customer.class);
//如果参数username满足条件,则加入语句中
if (username != null){
criteria.add(Restrictions.ilike("username", username, MatchMode.ANYWHERE));
}
if (password != null && !password.equals("")){
criteria.add(Restrictions.eq("password", password));
}
List<Customer> list = criteria.list();
for (Customer c : list) {
System.out.println(c);
System.out.println();
}
}
QBE动态查询方式
QBE查询就是检索与指定的样本对象具有相同属性的对象
【示例】
/**
* QBE动态查询
*/
@Test
public void testDynamicQuery_QBE(){
Customer customer = new Customer("AlanLee", "123", "广州");
findCustomerByQBE(customer);
}
public void findCustomerByQBE(Customer customer){
Session session = HibernateUtil.getSession();
Example example = Example.create(customer)
.enableLike()
.excludeNone()
.excludeZeroes()
.ignoreCase();
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(example);
List<Customer> list = criteria.list();
for (Customer c : list) {
System.out.println(c);
System.out.println();
}
}