0 总述
0.1 写在前面 碎碎念
上午拆了笔记本清了一下灰,重新涂了硅脂。好像是有稍微快一点了的错觉,今天肯定是学不完了…一个hibernate原本四天的课愣是被我看了八天,我也真的太懒了。晚上要上团日、做网络营销的PPT、给爸爸打电话。
不说了,冲冲冲。
3/31/2019
0.1 地图
1 hibernate的查询方式
hibernate中提供了五种查询方式。
1.1 OID查询
根据对象的OID(主键)进项检索。使用get(Class c,Long long)&load(Class c,Long long)的方法。
Customer c1 = session.get(Customer.class,3l);
Customer c2 = session.load(Customer.class,4l);
1.2 对象导航查询
hibernate根据已经查询到的对象,获得其关联的对象的一种查询方式。
LinkMan lm1 = session.get(LinkMan.class,3l);
Customer c1 = lm.getCustomer();
Customer c2 = session.get(Customer.class,2l);
Set<LinkMan> linkMans = c2.getLinkMans();
1.3 HQL检索(重要)
HibernateQueryLanguage:面向对象的查询语言,语法类似SQL。通过session.createQuery(),用于接收一个HQL进行查询。
1.3.1 初始化数据
1.3.2 HQL简单查询
Query q = s.createQuery("from Customer");
List<Customer> list = q.list();
//sql中支持*写法:select * from cst_customer,HQL中不支持*
for (Customer customer : list) {
System.out.println(customer);
}
- 别名的查询
Query q = s.createQuery("select c from Customer c");
List<Customer> list = q.list();
for (Customer customer : list) {
System.out.println(customer);
}
1.3.3 HQL排序查询
//升序asc,降序desc
List<Customer> list = session.createQuery("select c from Customer c order by cust_id desc").list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
1.3.4 HQL条件查询
1.3.4.1 按位置绑定
Query q= session.createQuery("from Customer where cust_name like ?");
q.setParameter(0, "5%");
List<Customer> list = q.list();
1.3.4.2 按名称绑定
Query q = session.createQuery("from Customer where cust_name like :aaa"); //冒号后面没有空格
q.setParameter("aaa","5%");
List<Customer> list = q.list();
1.3.5 HQL投影查询
投影查询:查询对象的某个或某些属性
//投影查询
/*List<Object[]> list = s.createQuery("select c.cust_id,c.cust_name from Customer c").list();
List<Object> list1 = s.createQuery("select c.cust_name from Customer c").list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
for (Object object : list1) {
System.out.println(object);
}*/
//查询多个属性并进行封装
List<Customer> list = s.createQuery("select new Customer(cust_name,cust_source) from Customer").list();
for (Customer customer : list) {
System.out.println(customer);
}
1.3.6HQL分页查询
q.setFirstResult(0);
q.setMaxResults(10);
1.3.7 HQL分组统计查询
Query q = session.createQuery("select c.cust_source,count(*) from Customer c group by c.cust_source having count(*) >= 2");
List<Object[]> list = q.list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
1.3.8 HQL 多表查询(未学到)
- SQL多表查询
- 连接查询
- 交叉连接(不常用)笛卡尔积
select * from A,B;
- 内连接 inner join(inner 可以省略),查到两个表的交集
- 隐式内连接
select * from A,B where A.id = B.id;
- 显式内连接,语句中有inner join
select * from A inner join B on A.id=B.id;
- 隐式内连接
- 外连接 outer join
- 左外连接,left outer join(outer可以省略),查到左边表的全部部分,和右边表的公共部分
select * from A left outer join B on A.id=B.idl;
- 右外连接,right outer join
select * from A right outer join B on A.id=B.id;
- 左外连接,left outer join(outer可以省略),查到左边表的全部部分,和右边表的公共部分
- 交叉连接(不常用)笛卡尔积
- 子查询(SQL嵌套)
- 连接查询
- HQL 多表查询
- 连接查询
- 交叉连接
- 内连接
- 隐式内连接
- 显式内连接
List<Object[]> list = session.createQuery("from Customer c inner join c.linkMans").list();
- 迫切内连接
- 迫切内连接 在普通内连接的inner join后添加关键字fetch
- fetch通知hibernate将另一个对象的数据封装到该对象中
List<Customer> list = session.createQuery("select distict c from Customer c inner join fetch c.linkMans").list();
- 外连接
- 左外连接
- 右外连接
- 迫切左外连接
- 连接查询
1.4 QBC检索(重要)
1.4.1 简述
Query By Criteria :条件查询,面向对象化的查询方式。
1.4.2 简单查询
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();
1.4.3 排序查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(Order.desc("cust_id"));
List<Customer> list = criteria.list();
1.4.4 分页查询
Criteria criteria = session.createCriteria(LinkMan.class);
criteria.setFirstResult(0);
criteria.setMaxResults(10);
List<LinkMan> list = criteria.list();
1.4.5 条件查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("cust_source","chichi"));
List<Customer> list = criteria.list();
1.4.6 统计分组查询
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Customer.class);
criteria.setProjection(Projections.rowCount());
Object o = criteria.uniqueResult();
1.4.7 离线条件查询(SSH)DetachedCriteria
离线:脱离Session使用。
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
dc.add(Restrictions.eq("cust_source", "chichi"));
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria c = dc.getExecutableCriteria(session);
List<Customer> list = c.list();
1.5 SQL检索
使用sql基本语句进行查询
SQLQuery q = session.createSQLQuery("select * from cst_customer");
q.addEntity(Customer.class); //创建Customer实体
List<Customer> list = q.list();
2 HQL 查询语句总结
3 Hibernate的抓取策略(优化手段)
3.1 延迟加载的概述
延迟加载:lazy懒加载。执行到该行代码的时候,不会发送语句进行查询,在真正使用该对象的属性的时候才会发送SQL语句进行查询。
3.2 延迟加载的分类
- 类级别的延迟加载
- 指的是通过load方法查询某个对象的时候,是否采用延迟。
- 在xxx.hbm.xml的
<class>
标签上配置的lazy=“true/false”,true默认,false失效。 Session.load(Customer.class,1l);
- 关联级别的延迟加载
- 指的是在查询到某个对象的时候,查询其关联对象的时候,是否会采用延迟加载。
- 在关联对象的hbm.xml的
<set>
或<many-to-one>
标签上配置lazy=“true/false”,true默认,false失效。 Customer c = Session.get(Customer.class,1l);
c.getLinkMans(); //通过 客户获得联系人的时候,联系人对象是否采用了延迟加载。
- 抓起策略往往会和关联级别的延迟加载一起使用,优化语句。
3.3 抓取策略
- 通过一个对象抓取到关联对象需要发送SQL语句,SQL语句如何发送,发送成什么样的格式通过策略进行配置。
- 通过
<set>
或者<many-to-one>
上通过fetch属性进行设置 - fetch和标签上的lazy如何设置来优化发送的sql语句
- 通过
3.3.1 <set>
上的fetch和lazy
- fetch:抓取策略,控制SQL语句格式
- select(默认),发送普通的select语句,查询关联对象
- join,发送一条迫切左外连接查询关联对象
- subselect,发送一条子查询语句查询其关联对象
- lazy:延迟加载,控制查询关联对象的时候是否采用延迟
- true(默认),查询关联对象时采用延迟加载
- false,不采用延迟加载
- extra,极其懒惰
3.3.1.1 fetch=“select” lazy=“true”
发送普通SQL语句查询,关联对象采用延迟加载(关联对象被调用的时候才开始加载)。
3.3.1.2 fetch=“select” lazy=“false”
发送普通SQL语句查询,关联对象不采用延迟加载(关联对象在加载对象时已经加载)。
3.3.1.3 fetch=“select” lazy=“extra”
发送普通SQL语句查询,关联对象采用延迟加载(调用关联对象的某个属性的时候才发送sql语句查询该属性)。
3.3.1.4 fetch=“join” lazy失效
发送迫切左外连接SQL语句查询
3.3.1.5 fetch=“subselect” lazy=“true”
在调用对象时:发送查询所有客户的sql语句,在使用关联对象时:发送一条子查询。
3.3.1.5 fetch=“subselect” lazy=false"
在调用对象时:发送查询所有客户的sql语句,并且发送一条子查询,查询所有关联对象。
3.3.1.3 fetch=“select” lazy=“extra”
在调用对象时:发送查询所有客户的sql语句,关联对象采用延迟加载(调用关联对象的某个属性的时候才发送sql子查询语句查询该属性)。
3.3.2 <many-to-one>
上的fetch和lazy
- fetch:抓取策略,控制SQL语句格式
- select(默认),发送普通的select语句,查询关联对象
- join,发送一条迫切左外连接查询关联对象
- lazy:延迟加载,控制查询关联对象的时候是否采用延迟
- proxy(默认),取决于关联对象的
<class>
标签上的lazy属性的值 - false,查询关联对象不采用延迟
- no-proxy(不会使用
- proxy(默认),取决于关联对象的
3.3.3 批量抓取
一批关联对象一起抓取,添加属性batch-size=”一次抓几个对象“。
- 批量抓取联系人,在Customer.hbm.xml中的set标签中添加属性batch-size=”一次抓几个LinkMan对象“
- 批量抓取客户,在Customer.hbm.xml中的class标签中添加属性batch-size=”一次抓几个Customer对象“