1、上次课回顾
1.1 hibernate的一对多
- 表与表之间的关系
- 一对多关系
- 多对多关系
- 一对一关系
- hibernate的一对多配置 - 搭建hibernate基本环境 - 创建表 - 创建实体 - 一的一方 - 方的是多的一方的集合 - 多的一方 - 方的是一的一方的集合 - 创建映射 - 一的一方 - 配置的是set集合 - 多的一方 - 配置<many-to-one/> - 必须呢测试类
- hibernate的一对多的操作
- 级联操作 :cascade,用于操作其关联的对象
- 级联保存或更新
- 级联删除
- 测试对象导航
- 放弃外键维护权 :inverse:用户控制是否有外键维护能力
- 级联操作 :cascade,用于操作其关联的对象
1.2 hibernate的多对多
-
hibernate多对多的配置
- 搭建hibernate环境
- 创建表
- 创建实体
- 放置的是对方的集合
- 创建映射
- 放置的是对象的
- 编写测试类
-
hibernate多对多的操作
- 级联操作
- 级联保存或更新
- 级联删除(了解即可)
- 其他的操作
- 给用户选择角色
- 给用户修改角色
- 给用户删除角色
- 级联操作
2、Hibernate的查询的方式
2.1 OID查询
OID检索:hibernate根据对象的OID(主键)进行检索。
2.1.1 使用get方法
Customer customer = session.get(Customer.class,1l);
2.1.2 使用load方法
Customer customer = session.get(Customer.class,1l);
2.2 对象导航检索
对象导航检索:Hibernate根据一个已经查询到的对象,获得其关联的对象的一种查询方式。
LinkMan linkMan = Session.get(LinkMan.class,1l);
Customer customer = linkMan.getCustomer();
Customer customer = session.get(Customer.class,2l);
List<LinkMan> linkmans = customer.getLinkMans();
2.3 HQL检索
HQL查询:Hibernate Query Language(Hibernate的查询语言),是一种面向对象的方式的查询语言,语法类似SQL。通过session.createQuery(),用于接收一个进行查询的一种方式。
- 初始化一些数据
- 创建表
- 创建对象
2.3.1 HQL的简单查询
public void demo2() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
String hql = "from Customer";
Query query = session.createQuery(hql);
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
2.3.2 HQL的排序查询
/***
* HQL的排序查询
*/
@Test
public void demo3() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//默认情况:升序查询
//List<Customer> list = session.createQuery("from Customer order by cust_id").list();
//设置降序排序
List<Customer> list = session.createQuery("from Customer order by cust_id desc").list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
需要注意的是:我用的hibernate版本是5.4.1,在?后面加上数字0,1,1....。;老版本不需要加。
2.3.3 HQL的条件查询
/***
* HQL的条件查询
*/
@Test
public void demo4() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//条件查询
//1、按位置绑定:根据参数的位置进行绑定
//一个条件
/*
* Query query = session.createQuery("from Customer where cust_name=?0");
* query.setParameter(0, "雷军"); List<Customer> list = query.list();
*/
//多个条件
/*
* Query query = session.createQuery("from Customer where cust_id=?0 and cust_name like ?1");
* query.setParameter(0, 1l); query.setParameter(1, "雷%");
* List<Customer> list = query.list();
*/
//2、按名称绑定
Query query = session.createQuery("from Customer where cust_id= :aaa and cust_name like :name");
query.setParameter("aaa", 2l);
query.setParameter("name", "雷%");
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
2.3.4 HQL的投影查询
投影查询:查询对象的某个或某些属性
/**
* 投影查询:查询对象的某个或某些属性
*/
@Test
public void demo5() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//投影查询
//单个属性
/*
* List<Object> list =
* session.createQuery("select c.cust_name from Customer c").list(); for (Object
* object : list) { System.out.println(object); }
*/
//多个属性
/*
* List<Object[]> list =
* session.createQuery("select c.cust_id,c.cust_name from Customer c").list();
* for (Object[] objects : list) { System.out.println(Arrays.toString(objects));
* }
*/
//查询多个属性:但是我们想封装到对象中
List<Customer> list = session.createQuery("select new Customer(cust_id,cust_name) from Customer").list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
2.3.5 HQL的分组统计查询
/**
* 分组统计查询
*/
@Test
public void demo7() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//uniqueResult():唯一结果,只能查到一个值
//聚合函数的使用:count(),max(),min(),avg(),sum()
/*
* Object object= (Long)
* session.createQuery("select count(*) from Cutomer").uniqueResult();
* System.out.println(object);
*/
//分组统计
List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source").list();
//大于等于2的
//List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source having count(*) >=2").list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
transaction.commit();
}
2.3.6 HQL的分页查询
* 分页查询
*/
@Test
public void demo6() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
Query query = session.createQuery("from LinkMan");
query.setFirstResult(3); //起始位置
query.setMaxResults(5); //每页数据条数
List<LinkMan> list = query.list();
for (LinkMan linkMan : list) {
System.out.println(linkMan);
}
transaction.commit();
}
2.3.7 多表查询
-
SQL的多表查询
- 连接查询
- 交叉连接
- 内连接
- 隐式内连接
- 显式内连接
- 外连接
- 左外连接
- 右外连接
- 子查询
- 连接查询
-
HQL的多表查询
- 连接查询
- 交叉连接
- 内连接
- 显式内连接
- 隐式内连接
- 迫切内连接
- 外链接
- 左外连接
- 右外连接
- 迫切左外连接
- 连接查询
代码如下
/**
* HQL多表查询
*/
@Test
public void demo8() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
/*
* List<Object[]> list =
* session.createQuery("from Customer c,inner join c.linkMans ").list(); for
* (Object[] objects : list) { System.out.println(Arrays.toString(objects)); }
*/
//迫切内连接:其实就是在普通的内连接inner join 后添加一个关键字fetch
List<Customer> customers = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans ").list();//通知Hibernate,将另一个对象的数据封装到该对象中
for (Customer customer : customers) {
System.out.println(customer);
}
transaction.commit();
}
2.4 QBC检索
QBC:Query By Criteria,条件查询:是一种更加面向对象化的查询方式。
2.4.1 简单查询
/**
* 简单查询
*/
@Test
public void demo1() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//获得criteria的对象
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
2.4.2 排序查询
/**
* 排序查询
*/
@Test
public void demo2() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//获得criteria的对象
Criteria criteria = session.createCriteria(Customer.class);
//Order是hibernate中的一个对象
criteria.addOrder(Order.desc("cust_id"));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
2.4.3 分页查询
/*
* 分页查询
*/
@Test
public void demo3() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//获得criteria的对象
Criteria criteria = session.createCriteria(LinkMan.class);
criteria.setFirstResult(3);
criteria.setMaxResults(5);
List<LinkMan> list = criteria.list();
for (LinkMan linkMan : list) {
System.out.println(linkMan);
}
transaction.commit();
}
2.4.4 条件查询
/*
* 分页查询
*/
@Test
public void demo4() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//获得criteria的对象
Criteria criteria = session.createCriteria(Customer.class);
/**
* 设置条件:
* == eq (equals)
* > gt (greater than)
* >= ge (greater equals)
* < lt (less than)
* <= le (less equals)
* <> ne (not equals)
* like
* in
* between
* and
* or
*/
criteria.add(Restrictions.eq("cust_source", "影视"));
criteria.add(Restrictions.like("cust_name", "雷%"));
//criteria.add(Restrictions.or(Restrictions.like("cust_name", "雷%")));
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
2.4.5 统计查询
/*
* 统计查询
*/
@Test
public void demo5() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//获取Criteria的对象
Criteria criteria = session.createCriteria(Customer.class);
/**
* add :普通的条件,where后面的条件
* addOrder :排序
* setProjection :聚合函数和group by ,having 后面的条件
*/
criteria.setProjection(Projections.rowCount());
Long num = (Long) criteria.uniqueResult();
System.out.println(num);
transaction.commit();
}
2.4.6 离线条件查询(SSH)-->DetachedCriteria
使用DetachedCriteria-->离线(脱离session)
/*
* 离线条件查询
*/
@Test
public void demo6() {
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
detachedCriteria.add(Restrictions.like("cust_name", "雷%"));
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
List<Customer> list = criteria.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
2.5 SQL检索
@Test
public void demo1() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
/*
* List<Object[]> list =
* session.createSQLQuery("select * from cst_customer").list(); for (Object[]
* objects : list) { System.out.println(objects); }
*/
SQLQuery query = session.createSQLQuery("select * from cst_customer");
query.addEntity(Customer.class);
List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
}
transaction.commit();
}
3、Hibernate的抓取策略
3.1延迟加载
3.1.1延迟加载的概述
延迟加载:lazy(懒加载)。执行到该行代码的时候,不会马上送语句去进行查询,在真正使用这个对象的属性的时候才会发送SQL语句进行查询。
3.2延迟加载的分类
3.2.1类级别的延迟加载
值的是通过load方法查询某个对象的时候,是否采用延迟。session.load(Customer.class)
- 配置
- 在配置文件的class标签中设置lazy为true或者false,默认为true.
- 让lazy失效
- 将lazy设置为false
- 将持久化类使用 final修饰
- hibernate.initialize(Customer)
3.2.2关联级别的延迟加载
值的是在查询到某个对象的时候,查询其关联的对象的时候,是否采用延迟加载。Customer customer = session.get(Customer.class);
3.2 抓取策略
3.2.1 抓取策略的概述
- 通过一个对象抓取到关联对象需要发送SQL语句,SQL语句如何发送,发送成什么格式通过策略进行配置。
- 通过或者<many-to-one>上通过fetch属性进行设置。
- fetch和这些标签上的lazy如何设置优化发送的SQL语句。
3.2.1.1 上的fetch和lazy
-
fetch:抓取策略,控制SQL语句格式
- select :默认值,发送普通的select语句,查询关联对象
- join :发送一条迫切左外连接查询关联对象
- subselect :发送一条子查询查询其关联的额对象
-
lazy: 延迟加载,控制查询关联对象的时候是否采用延迟
- true :默认值,查询关联对象的时候,采用延迟加载
- false :查询关联对象的时候,不采用延迟加载
- extra :及其懒惰,
3.2.1.2 <many-to-one>上的fetch和lazy
- fetch:抓取策略:控制SQL语句格式
- select :默认,发送普通的select语句,查询关联对象
- join :发送一条迫切左外连接。
- lazy:延迟加载,控制查询关联对象的时候是否采用延迟加载
- proxy :默认,
- false :查询关联对象,不采用延迟加载
- no-proxy(不会使用)