Hibernate_day03
一 查询总结
查询方式:
1.oid查询—get方法
2.对象属性导航查询(通过获得持久化对象的关联属性进行查询)
3.HQL
4.Criteria
5.原生SQL
一 HQL语法
(1)HQL基础语法
**1.基本查询**
public class Demo {
**//基本查询**
@Test
public void fun1() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//-------------------------------------------
//简单写法
String hql1 ="from Customer ";
Query query = session.createQuery(hql1);
List<Customer> list = query.list();
System.out.println(list);
//-------------------------------------------
tx.commit();
}
2.排序查询
@Test
//排序查询
public void fun2() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//-------------------------------------------
//简单写法
String hql1 ="from Customer order by cust_id desc";
Query query = session.createQuery(hql1);
List<Customer> list = query.list();
System.out.println(list);
//-------------------------------------------
tx.commit();
}
3.条件查询
@Test
//条件查询
public void fun3() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//-------------------------------------------
//简单写法
String hql1 ="from Customer where cust_id = :id";
String hql2 ="from Customer where cust_id = ?";
Query query = session.createQuery(hql1);
Query query1 = session.createQuery(hql2);
//query.setParameter(0,2l);
query.setParameter("id",2l);
List<Customer> list = query.list();
System.out.println(list);
//-------------------------------------------
tx.commit();
}
4.分页查询
@Test
//分页查询
public void fun4() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//-------------------------------------------
//简单写法
String hql1 ="from Customer ";
Query query = session.createQuery(hql1);
//limit ?,?
//起始=(当前页-1)*每页条数
query.setFirstResult(2);
query.setMaxResults(2);
List<Customer> list = query.list();
System.out.println(list);
//-------------------------------------------
tx.commit();
}
5.统计查询
@Test
//count
//sum
//avg
//max
//min
public void fun5() {
//统计查询
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//-------------------------------------------
//简单写法
String hql1 ="select count(*) from Customer";
String hql2 ="select sum(cust_id) from Customer";
String hql3 ="select avg(cust_id) from Customer";
String hql4 ="select max(cust_id) from Customer";
String hql5 ="select min(cust_id) from Customer";
Query query = session.createQuery(hql5);
Number number = (Number) query.uniqueResult();
System.out.println(number);
//-------------------------------------------
tx.commit();
}
6.投影查询
@Test
//投影查询
public void fun6() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//-------------------------------------------
//简单写法
String hql1 ="select cust_id,cust_name from Customer";
String hql2 ="select new Customer(cust_id,cust_name) from Customer";
Query query = session.createQuery(hql2);
List list = query.list();
System.out.println(list);
//-------------------------------------------
tx.commit();
}
}
(2)HQL多表语法
回顾原生SQL
交叉连接–笛卡儿积(没有意义,避免)
select * from A,B
内连接
隐式内连接
select * from A,B where b.aid = a.id
显式内连接
select * from A inner jion B on b.aid = a.id
外连接
左外连接
select * from A left[outer] jion B on b.aid = a.id
右外连接
select * from A right[outer] jion B on b.aid = a.id
------------------------------------------------------------------------
HQL的多表查询(不常用语法,太诡异)
内连接(迫切)
外连接
左外(迫切)
右外(迫切)
@Test
//HQL内连接=>将连接的两端对象分别返回,然后放到数组里,
public void fun1() {
Session session = HibernateUtils.getCurrentSession();
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();
}
//HQL迫切内连接=>帮我们进行封装
@Test
//HQL迫切内连接=>帮我们进行封装
public void fun2() {
Session session = HibernateUtils.getCurrentSession();
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();
}
//HQL右外连接
@Test
//HQL右外连接
public void fun4() {
Session session = HibernateUtils.getCurrentSession();
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();
}
//HQL左外连接
@Test
//HQL左外连接
public void fun3() {
Session session = HibernateUtils.getCurrentSession();
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();
}
二 criteria语法
@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);
//c.add(Restrictions.idEq(2l));
c.setFirstResult(0);
c.setMaxResults(2);
List<Customer> list = c.list();
System.out.println(list);
//-----------------------------------------
tx.commit();
session.close();
}
@Test
//排序语法 与HQL语法一样
public void fun4() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//-----------------------------------------
Criteria c = session.createCriteria(Customer.class);
c.addOrder(Order.desc("cust_id"));
List<Customer> list = c.list();
System.out.println(list);
//-----------------------------------------
tx.commit();
session.close();
}
@Test
//统计语法 与HQL语法一样
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();
}
离线查询
非离线
离线
离线的语法:
@Test
//离线Criteria查询
public void fun1() {
//Service或者web层
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
//拼装条件(全部与普通Criteria一样)
dc.add(Restrictions.idEq(2l));
//------------------------------------------
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
//-----------------------------------------
Criteria c = dc.getExecutableCriteria(session);
List<Customer> list = c.list();
System.out.println(list);
//-----------------------------------------
tx.commit();
session.close();
}
查询优化
类级别查询
get方法:没有任何策略,调用即立即查询数据库加载数据
load方法:应用类级别的加载策略
- load方法(默认):实在执行时,不发送任何sql语句,返回一个对象,
- 使用该对象时,才执行查询
- 延迟加载:仅仅获得没有使用,不会查询,在使用时才会查询
- 是否对类进行延迟加载:可以通过在class元素上配置lazy属性来控制
- lazy:true 加载时,不查询,使用时才查询
- lazy:flase 加载时立即查询
- 注意:lazy只有在load方法中存在,get方法没有策略
结论:为了提高效率,建议使用load方法延迟加载(懒加载)
注意:使用懒加载时,调用属性加载数据时,session还是打开的,不然会抛出异常
关联级别查询
集合策略
关联属性策略
结论:
为了提高效率,fetch的选择上select,lazy的取值应选择true,全部使用默认值.
no-session问题解决:
一般地,session在service层打开事务的时候创建,在事务提交或者回滚的时候,清除
用filter扩大session的作用范围,
filter在到达servlet之前会执行一次,在页面显示完成之后还会执行一次.