Hibernate - hibernate 有几种查询方式
总结
1.HQL (Hibernate Query Language)
- 语法类似sql
- 把sql语句的表名换成了类名,把字段名换成实体类中的属性
- 具有跨数据库的优点
2.QBC (Query By Criteria)
- 使用Session实例的createCriteria(XXX.class)方法创建Criteria对象;
- 使用工具类Restrictions的方法为Criteria对象设置查询条件,Order工具类的方法设置排序方式,Projections工具类的方法进行统计和分组;
- 使用Criteria对象的list()方法进行查询并返回结果。
3.SQL (Structured Query Language)
- 违背了hibernate的跨平台优点,不易维护,不面向对象。不推荐使用。
HQL示例
参考:https://www.cnblogs.com/jasonjson/p/12430917.html
查询所有,条件查询,排序查询,分页查询,统计查询,投影查询
import com.utils.HibernateUtils;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.junit.Test;
import java.util.List;
public class CustomerTestDemo06 {
/**
* HQL查询
* 把sql语句的表明换成了类名。把字段名换成实体类中的属性
*/
//查询所有
@Test
public void test01(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
Query query=s.createQuery("from Customer");
List list = query.list();
for (Object o : list) {
System.out.println((Customer)o);
}
tx.commit();
}
//按条件查询--1.占位符
@Test
public void test02(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
Query query=s.createQuery("from Customer where lovel = ? or name like ?");
query.setString(0,"做县官"); //占位符从0开始的
query.setString(1,"%刘%");
List list = query.list();
for (Object o : list) {
System.out.println((Customer)o);
}
tx.commit();
}
//按条件查询--2.给占位符取名字
@Test
public void test03(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//给参数区名 :名 规范是(:属性)
Query query=s.createQuery("from Customer where lovel = :a or name like :name");
// query.setString("a","做县官"); //占位符从0开始的
// query.setString("name","%刘%");
//setParameter()方法,此参数类型更灵活
query.setParameter("a","做县官");
query.setParameter("name","%刘%");
List list = query.list();
for (Object o : list) {
System.out.println((Customer)o);
}
tx.commit();
}
//排序查询
@Test
public void test04(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//order by 列明 desc
Query query=s.createQuery("from Customer order by id desc ");
List list = query.list();
for (Object o : list) {
System.out.println((Customer)o);
}
tx.commit();
}
/**
* 分页查询,hibernate提供高了两个方法:
* setFirstResult(),设置开始查询记录索引
* setMaxResults(),设置每页查询条数
*
*/
@Test
public void test05(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//order by 列明 desc
Query query=s.createQuery("from Customer order by id desc ");
query.setFirstResult(3);
query.setMaxResults(3);
List list = query.list();
for (Object o : list) {
System.out.println((Customer)o);
}
tx.commit();
}
/**
* 统计查询,使用聚合函数:
*count sum avg max min
*/
@Test
public void test06(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//order by 列明 desc
Query query=s.createQuery("select count(*) from Customer");
/*List list = query.list();
for (Object o : list) {
System.out.println(o);
}*/
Object o = query.uniqueResult(); //当返回结果唯一的时候使用此方法
System.out.println(o);
tx.commit();
}
/**
* 投影查询:
* 查询结果只需要部分字段,不需要全部不,且希望返回的结果是封装类,而不是Object
* 用法:用在HQL语句中new 一个对象,并给对象一个具体的带参的构造函数
*/
@Test
public void test07(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//order by 列明 desc
Query query=s.createQuery("select new com.bean.Customer(id,name) from Customer");
List list = query.list();
for (Object o : list) {
System.out.println(o);
}
tx.commit();
}
}
HBC示例
参考:https://www.cnblogs.com/jasonjson/p/12430917.html
- Criteria 基本查询,条件查询,排序查询,分页查询,统计(投影)查询,
- DetachedCriteria 离线查询
package com.bean;
import com.utils.HibernateUtils;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.criterion.*;
import org.junit.Test;
import java.util.List;
public class CustomerTestDemo07 {
/**
* QBC查询
* 更加面向对象的查询方式,它把生成语句的过程全都融入到方法之中
* 效率比HQL查询慢
*/
//基本查询
@Test
public void test01(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//获取Criteria对象
Criteria criteria = s.createCriteria(Customer.class);
List list = criteria.list();
for (Object o : list) {
System.out.println((Customer)o);
}
tx.commit();
}
//条件查询
@Test
public void test02(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//获取Criteria对象
Criteria criteria = s.createCriteria(Customer.class);
//添加查询条件
criteria.add(Restrictions.eq("lovel", "做县官"));
criteria.add(Restrictions.like("name", "%张%"));
List list = criteria.list();
for (Object o : list) {
System.out.println((Customer)o);
}
tx.commit();
}
//分页查询
@Test
public void test03(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//获取Criteria对象
Criteria criteria = s.createCriteria(Customer.class);
//设置分页
criteria.setFirstResult(0);//起始下标
criteria.setMaxResults(2); //每页显示条数
List list = criteria.list();
for (Object o : list) {
System.out.println((Customer)o);
}
tx.commit();
}
//排序查询
@Test
public void test04(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//获取Criteria对象
Criteria criteria = s.createCriteria(Customer.class);
//添加查询条件
criteria.addOrder(Order.desc("name"));
List list = criteria.list();
for (Object o : list) {
System.out.println((Customer)o);
}
tx.commit();
}
//统计查询
//使用sql自带的聚合函数
@Test
public void test05(){
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//获取Criteria对象
Criteria criteria = s.createCriteria(Customer.class);
//添加查询条件
criteria.setProjection(Projections.count("id"));
Object o = criteria.uniqueResult();
System.out.println(o);
tx.commit();
}
//离线查询
//先用离线对象将查询条件封装,再交给session
@Test
public void test06(){
//1.获取DetachedCriteria离线对象
DetachedCriteria dc=DetachedCriteria.forClass(Customer.class);
//2.封装查询条件
dc.add(Restrictions.eq("lovel", "做县官"));
dc.add(Restrictions.like("name", "%张%"));
//3.获取session对象,开始事务
Session s=HibernateUtils.getCurrnetSession();
Transaction tx = s.beginTransaction();
//4.将离线对象转成Criteria对象
//Session s1=HibernateUtils.getCurrnetSession();
Criteria criteria = dc.getExecutableCriteria(s);
//5.执行查询
List list = criteria.list();
for (Object o : list) {
System.out.println((Customer)o);
}
tx.commit();
}
}
SQL示例
static List sql() {
Session s = HibernateUtil.getSession();
Query q = s.createSQLQuery("select * from user").addEntity(User.class);
List<User> rs = q.list();
s.close();
return rs;
}
为何有了Criteria,还需要DetachedCriteria?
参考:https://www.cnblogs.com/jinsheng1027/p/11327159.html
我的理解:
为了“解耦”,解除Criteria和session的依赖关系。
HQL与QBC的区别
参考:https://blog.csdn.net/liuchangjie0112/article/details/51567321
两者优缺点
|
比较方面 |
HQL检索方式 |
QBC检索方式 |
|
可读性 |
和SQL查询语言比较接近,比较容易读懂 |
QBC把查询语句肢解为一组Criterion实例。可读性差。 |
|
功能 |
功能最强大,支持各种各样的查询。 |
没有HQL的功能强大,例如不支持报表查询和子查询,而且对连接查询也做了很多限制。 |
|
查询语句形式 |
应用程序必须提供基于字符串形式的HQL查询语句。 |
QBC检索方式封装了基于字符串形式的查询语句,提供了更加面向对象的接口。 |
|
何时被解析 |
HQL查询语句只有在运行时才会被解析 |
OBC在编译时就能被编译,因此更加容易排错 |
|
可扩展性 |
不具有扩展性 |
允许用户扩展Criterion接口 |
|
对动态查询语句的支持 |
尽管支持生成动态查询语句,但是编程很麻烦 |
适合于生成动态查询语句 |
连接查询的支持
|
指定的连接查询类型 |
HQL语法 |
QBC语法 |
适用范围 |
|
内连接 |
inner join或者join |
Criteria.createAlias() |
适用于有关联关系的持久化类,并且在映射文件中对这种关联关系作了映射。 |
|
迫切内连接 |
inner join fetch或者join fetch |
不支持 |
|
|
隐式内连接 |
|
不支持 |
|
|
左外连接 |
left outer join或者left join |
不支持 |
|
|
迫切左外连接 |
left outer join fetch或者left join fetch |
FetchMode.EAGER |
|
|
右外连接 |
right outer join或者right join |
不支持 |
|
|
交叉连接 |
ClassA,ClassB |
不支持 |
适用于 |
浙公网安备 33010602011771号