Hibernate查询方式
1.对象导航查询
- (1)根据id查询某个客户,再查询这个客户里面所有的联系人
- (2)代码
// 根据cid=1客户,再查询这个客户里面所有联系人
Customer customer = session.get(Customer.class, 1);
// 再查询这个客户里面所有联系人
// 直接得到客户里面所有联系人的set集合
Set<LinkMan> linkman = customer.getSetLinkMan();
2.OID查询
- (1)根据id查询某个一条记录,返回对象
- 调用session里面的get方法得到
Customer customer = session.get(Customer.class, 1);
3.hql查询
- hql:即:hibernate query language,Hibernate提供的一种查询语言
- 和sql区别:普通sql操作数据库表和字段,hql操作实体类和属性
- 常用的hql语句
使用hql查询操作时候,使用Query对象
- 第一步:创建Query对象,写hql语句
- 第二步:调用query对象里面的方法得到结果
查询所有
- 查询所有客户记录
- from 实体类名称
// 创建Query对象
Query query = session.createQuery("from Customer");
// 调用方法得到结果
List<Customer> list = query.list();
for(Customer customer : list) {
System.out.println(customer.getCid()+ "::" + customer.getCustName());
}
条件查询
- 写法
- 1)from 实体类名称 where 实体类属性名称=? and 实体类属性名称=?
- 2)from 实体类名称 where 实体类属性名称 like ?
// 创建Query对象
Query query = session.createQuery("from Customer as c where c.cid=? and c.custName=?");
// 设置值,向?里面设置值
// setParameter:第一个参数int类型是?位置,?位置从0开始;第二个参数:具体参数值
query.setParameter(0, 1);
query.setParameter(1, "百度");
// 调用方法得到结果
List<Customer> list = query.list();
for(Customer customer : list) {
System.out.println(customer.getCid()+ "::" + customer.getCustName());
}
// 创建Query对象
Query query = session.createQuery("from Customer as c where c.custName like ?");
// 设置值,向?里面设置值
query.setParameter(0, "%浪%");
// 调用方法得到结果
List<Customer> list = query.list();
for(Customer customer : list) {
System.out.println(customer.getCid()+ "::" + customer.getCustName());
}
排序查询
- from 实体类名称 order by 实体类属性名称 asc/desc
// 创建Query对象
Query query = session.createQuery("from Customer order by cid desc");
// 调用方法得到结果
List<Customer> list = query.list();
for(Customer customer : list) {
System.out.println(customer.getCid()+ "::" + customer.getCustName());
}
分页查询
- MySQL实现分页:使用limit关键字
- 在hql实现分页
- 在hql操作中,在语句里面不能写limit,hibernate的Query对象封装两个方法实现分页操作
// 1.创建Query对象
// 查询所有的语句
Query query = session.createQuery("from Customer");
// 2.设置分页参数
// 2.1设置开始位置
query.setFirstResult(0);
// 2.2设置每页显示记录数
query.setMaxResults(3);
// 3.调用方法得到结果
List<Customer> list = query.list();
for(Customer customer : list) {
System.out.println(customer.getCid()+ "::" + customer.getCustName());
}
投影查询
- 投影查询
- 查询不是所有字段的值,而是部分字段的值
- 写法
- select 实体类属性名称1,实体类属性名称2 from 实体类名称(select后不能写*)
// 1.创建Query对象
// 查询所有的语句
Query query = session.createQuery("select custName from Customer");
// 2.调用方法得到结果,泛型里不能写Customer
List<Object> list = query.list();
for(Object object : list) {
System.out.println(object);
}
聚合函数使用
- 常用的聚集函数
- count,sum,avg,max,min
- 写法
- 查询表记录数:select count(*)from Customer
// 1.创建Query对象
Query query = session.createQuery("select count(*) from Customer");
// 2.调用方法得到结果
Object obj = query.uniqueResult();
// 返回的值,不能直接变成int类型
// 先把object变成long类型,再变成int类型
long lobj = (Long)obj;
int count = (int)lobj;
System.out.println(count);
4.QBC查询
- 使用QBC不需要写语句,使用方法实现
- 使用QBC时候,操作实体类属性
- 使用QBC,使用Criteria对象实现
查询所有
// 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
// 调用方法得到结果
List<Customer> list = criteria.list();
for(Customer customer : list) {
System.out.println(customer.getCid() + "::" + customer.getCustName());
}
条件查询
// 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
// 使用Criteria对象里面的方法实现
// 首先使用add方法,表示设置条件之
// 在add方法里面使用类的方法实现条件设置
criteria.add(Restrictions.eq("cid", 1));
criteria.add(Restrictions.eq("custName", "百度"));
// 调用方法得到结果
List<Customer> list = criteria.list();
排序查询
// 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
// 设置对哪个属性进行排序,设置排序规则
criteria.addOrder(Order.asc("cid"));
// 调用方法得到结果
List<Customer> list = criteria.list();
分页查询
// 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
// 设置分页数据
// 设置开始位置:计算公式(当前页-1)*每页记录数
criteria.setFirstResult(0);
//煤业显示记录数
criteria.setMaxResults(3);
// 调用方法得到结果
List<Customer> list = criteria.list();
统计查询
// 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
// 设置操作
criteria.setProjection(Projections.rowCount());
// 调用方法得到结果
Object obj = criteria.uniqueResult();
Long lobj = (Long)obj;
int count = lobj.intValue();
System.out.println(count);
离线查询
- 1.servlet调用service,service调用dao
- (1)在dao里面对数据库crud操作
- (2)在dao里面使用hibernate框架,使用hibernate时候,调用session里面的方法实现功能
// 创建Criteria对象
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
// 最终执行时候才需要到session
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
List<Customer> list = criteria.list();
for(Customer customer : list) {
System.out.println(customer.getCid() + "::" + customer.getCustName());
}
5.HQL多表查询
内连接
- 查询hql语句写法
以客户和联系人为例:from Customer c inner join c.setLinkMan
返回list,list里面每部分是数组形式
// 1 创建Query对象
Query query = session.createQuery("from Customer c inner join c.setLinkMan");
// 2 调用方法得到结果
List list = query.list();
迫切内连接
- 和内连接底层实现一样的
- 区别:迫切内连接返回list每部分是对象,内连接返回list每部分是数组
- 写法:
from Customer c inner join fetch c.setLinkMan
左外连接
- 写法
from Customer c left outer join c.setLinkMan
迫切左外连接
- 写法
from Customer c left outer join fetch c.setLinkMan - 区别:与迫切内连接和内连接类似
右外连接
- 写法
from Customer c right outer join c.setLinkMan
Hibernate检索策略
检索策略的概念
- hibernate检索策略分两类
- 立即查询
根据id查询,调用get方法,一调用get方法马上发送语句查询数据库 - 延迟查询
根据id查询,调用load方法,调用load方法不会马上发送语句查询数据,只有得到对象里面的值才会发送语句查询数据库
- 立即查询
- 延迟查询分为两类
- 类级别延迟
根据id查询,返回实体类对象,调用load方法不会马上发送语句
- 类级别延迟
Customer customer = session.get(Customer.class, 1);
// 得到set集合,没有发送语句
Set<LinkMan> linkman = customer.getSetLinkMan();
// 发送语句查询数据库
System.out.println(linkman.size());
- 关联级别延迟
查询某个客户,再查询这个客户的所有联系人
操作方法 - 在客户映射文件中配置
在set标签上使用属性
- fetch:值select
调用get之后,发送两条查询语句 - lazy:值true(延迟)、false(不延迟)、extra(极其延迟,要什么值查询什么值)
批量抓取
- fetch:值select
- 查询所有客户,返回list集合,遍历list集合,得到每个客户,得到每个客户所有联系人,此操作会发送很多sql语句
- 在客户的映射文件中,set标签中配置
batch-size
batch-size的值越大,效率越高 - 减少语句发送