查询总结
- oid查询-get
- 对象属性导航查询
- HQL
- Criteria
- 原生SQL
其中1、2、5三种查询我们比较熟悉,所以主要介绍Hibernate自带的HQL和Criteria查询。
查询-HQL语法
HQL查询语句在之前的博客中也提到过,它是Hibernate自创的面向对象的查询语句
//学习HQL语法
public class Demo {
//基本语法
@Test
public void fun1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql = " from cn.itcast.domain.Customer ";//完整写法
String hql2 = " from Customer "; //简单写法
String hql3 = " from java.lang.Object ";
Query query = session.createQuery(hql);
List list = query.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//排序
public void fun2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql1 = " from cn.itcast.domain.Customer order by cust_id asc ";//完整写法,升序排列
String hql2 = " from cn.itcast.domain.Customer order by cust_id desc ";//完整写法,降序排列
Query query = session.createQuery(hql2);
List list = query.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//条件查询
public void fun3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql1 = " from cn.itcast.domain.Customer where cust_id =? ";//完整写法
String hql2 = " from cn.itcast.domain.Customer where cust_id = :id ";//完整写法
Query query = session.createQuery(hql1);
query.setParameter(0, 2l);
// query.setParameter("id", 2l);
List list = query.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//分页查询
public void fun4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql1 = " from cn.itcast.domain.Customer ";//完整写法
Query query = session.createQuery(hql1);
//limit ?,?
// (当前页数-1)*每页条数
query.setFirstResult(2);
query.setMaxResults(2);
List list = query.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//统计查询
//count 计数
//sum 求和
//avg 平均数
//max
//min
public void fun5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql1 = " select count(*) from cn.itcast.domain.Customer ";//完整写法
String hql2 = " select sum(cust_id) from cn.itcast.domain.Customer ";//完整写法
String hql3 = " select avg(cust_id) from cn.itcast.domain.Customer ";//完整写法
String hql4 = " select max(cust_id) from cn.itcast.domain.Customer ";//完整写法
String hql5 = " select min(cust_id) from cn.itcast.domain.Customer ";//完整写法
Query query = session.createQuery(hql5);
Number number = (Number) query.uniqueResult();
System.out.println(number);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//投影查询
public void fun6(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql1 = " select cust_name from cn.itcast.domain.Customer ";
String hql2 = " select cust_name,cust_id from cn.itcast.domain.Customer ";
String hql3 = " select new Customer(cust_id,cust_name) from cn.itcast.domain.Customer ";
Query query = session.createQuery(hql3);
List list = query.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
}
HQL-多表查询
//学习HQL语法(不常用) - 多表查询语法
public class Demo2 {
//回顾-原生SQL
// 交叉连接-笛卡尔积(避免)
// select * from A,B
// 内连接(表示两张表关联的部分,类似两个集合取交集)
// |-隐式内连接
// select * from A,B where b.aid = a.id
// |-显式内连接
// select * from A inner join B on b.aid = a.id
// 外连接
// |- 左外
// select * from A left [outer] join B on b.aid = a.id
// |- 右外
// select * from A right [outer] join B on b.aid = a.id
//---------------------------------------------------------------------
//HQL的多表查询
//内连接(迫切,这里的迫切是指将相关联的部分,封装到一块)
//外连接(表示一张表所有的内容,包括关联的和没有关联的部分)
// |-左外(迫切)
// |-右外(迫切)
@Test
//HQL 内连接 => 将连接的两端对象分别返回.放到数组中.
public void fun1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql = " from Customer c inner join c.linkMens ";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
for(Object[] arr : list){
System.out.println(Arrays.toString(arr));
}
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//HQL 迫切内连接 => 帮我们进行封装.返回值就是一个对象
public void fun2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql = " from Customer c inner join fetch c.linkMens ";
Query query = session.createQuery(hql);
List<Customer> list = query.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//HQL 左外连接 => 将连接的两端对象分别返回.放到数组中.
public void fun3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql = " from Customer c left join c.linkMens ";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
for(Object[] arr : list){
System.out.println(Arrays.toString(arr));
}
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//HQL 右外连接 => 将连接的两端对象分别返回.放到数组中.
public void fun4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
String hql = " from Customer c right join c.linkMens ";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
for(Object[] arr : list){
System.out.println(Arrays.toString(arr));
}
//----------------------------------------------------
tx.commit();
session.close();
}
}
查询-Criteria语法
Criteria之前也有说到,它也是Hibernate自创的面向无语句的查询。它所有的查询都是通过调用方法来进行的。
//学习Criteria语法
public class Demo {
@Test
//基本语法
public void fun1(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Criteria c = session.createCriteria(Customer.class);
List<Customer> list = c.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//条件语法
public void fun2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Criteria c = session.createCriteria(Customer.class);
// c.add(Restrictions.idEq(2l));
c.add(Restrictions.eq("cust_id",2l));
List<Customer> list = c.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//分页语法 - 与HQL一样
public void fun3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Criteria c = session.createCriteria(Customer.class);
//limit ?,?
c.setFirstResult(0);
c.setMaxResults(2);
List<Customer> list = c.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//排序语法
public void fun4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Criteria c = session.createCriteria(Customer.class);
c.addOrder(Order.asc("cust_id"));
//c.addOrder(Order.desc("cust_id"));
List<Customer> list = c.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
@Test
//统计语法
public void fun5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Criteria c = session.createCriteria(Customer.class);
//设置查询目标
c.setProjection(Projections.rowCount());
List list = c.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
}
现在我们来想象一个场景,在我们做一些特别复杂的条件查询的时候,往往会在WEB层向业务层传递很多参数,再由业务层传递给DAO层,最后在DAO层将查询语句组装完成。那么我们能不能在WEB层就将查询语句提前拼接好呢?这样的话就只需要传递拼接好的查询语句了。
这个时候就需要用到我们的DetachedCriteria对象,中文译为离线条件查询。为什么说它是离线呢?因为我们都知道Criteria对象必须由Session对象来创建。也就是说要先有Session对象才能有Criteria对象。而我们的DetachedCriteria对象就可以做到脱离Session对象来创建。这样也就实现了在WEB层进行SQL语句拼接的需求了。
下面我们来看一个离线条件查询的例子
//学习离线Criteria
public class Demo2 {
@Test
public void fun1(){
//Service/web层
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
dc.add(Restrictions.idEq(6l));//拼装条件(全部与普通Criteria一致)
//----------------------------------------------------
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//----------------------------------------------------
Criteria c = dc.getExecutableCriteria(session);
List list = c.list();
System.out.println(list);
//----------------------------------------------------
tx.commit();
session.close();
}
}
从上面这个例子,我们可以发现Dao层就可以为一个固定的模版不需要去更改了。