Hibernate学习笔记(四)

Hibernate的查询方式

 

1 对象导航查询

根据id查询某个客户,再查询这个客户里面所有的联系人

 

2 OID查询

根据id查询某一条记录,返回对象

 

3 HQL查询

    Query对象,写hql语句实现查询

   * 查询所有

   * 条件查询

   * 排序查询

   * 分页查询

   * 投影查询

   * 聚集函数使用

 

4 QBC查询

    Criteria对象

   * 查询所有

   * 条件查询

   * 排序查询

   * 分页查询

   * 统计查询

 

5 本地SQL查询

SQLQuery对象,使用普通sql实现查询

 

对象导航查询

 

查询某个客户里面所有联系人的过程,就可以使用对象导航实现

代码

 

//根据cid=1,在查询这个客户里面所有联系人
Customer customer = session.get(Customer.class,1);
//在查询这个客户里面所有联系人
//直接得到客户里面联系人的set集合
Set<LinkMan> linkman = customer.getSetLinkMan();
System.out.println(linkman.size());


OID查询

 根据id查询记录

        调用session里面的get方法实现

 

//根据cid=1客户,在再查询这个客户里面所有联系人
Customer customer = session.get(Customer.class,1);


HQL查询

 

1  hqlhibernate Query languagehibernate提供的一种查询语言,hql语言和普通sql很相似

   区别:普通sql操作数据库表和字段,hql操作实体类和属性

 

2  常用的hql语句

       查询所有: from 实体类名称

       条件查询: from 实体类名称 where 实体类属性名称=and实体类属性名称=

                  from 实体类名称 where实体类属性名称like?(模糊查询)

       排序查询: from 实体类名称 order by 实体类属性名称asc/desc

 

       

3  使用hql查询操作时候,使用Query对象

   --- 创建Query对象,写hql语句

   --- 调用Query对象里面的方法得到结果

 

* 查询所有

 

写法:from 实体类名称

 

//1 创建Query对象
//SQL查询:select * t_customer where cid=? and custName=?
Query query = session.createQuery("from Customer c where c.cid=? and c.custName=?");
//2 设置条件值
// setParameter方法两个参数
//第一个参数:int类型 ?位置,?位置从0开始
//第二个参数:具体参数值
//设置第一‘?’
query.setParameter(0,1);
//设置第二个‘?’
query.setParameter(1,"三国");
//3 调用方法得到结果
List<Customer> list = query.list();



 

//1 创建Query对象
Query query = session.createQuery("from Customer");
//2 调用方法得到结果
List<Customer> list = query.list();

 * 条件查询

 

  写法:from 实体类名称 where 实体类属性名称=and实体类属性名称=

        from 实体类名称 where实体类属性名称like?(模糊查询)

 

普通查询

代码

 

//1 创建Query对象
//SQL查询:select * t_customer where cid=? and custName=?
Query query = session.createQuery("from Customer c where c.cid=? and c.custName=?");
//2 设置条件值
// setParameter方法两个参数
//第一个参数:int类型 ?位置,?位置从0开始
//第二个参数:具体参数值
//设置第一‘?’
query.setParameter(0,1);
//设置第二个‘?’
query.setParameter(1,"三国");
//3 调用方法得到结果
List<Customer> list = query.list();

模糊查询

 

//1 创建Query对象
Query query = session.createQuery("from Customer c where c.custName like ? ");
//2 设置?值
// %国%

//设置第一‘?’
query.setParameter(0,"%国%");


//3 调用方法得到结果
List<Customer> list = query.list();

 

  * 排序查询

降序:desc   升序:asc

 

 

//1 创建Query对象
Query query = session.createQuery("from Customer order by cid desc");
//2 调用方法得到结果
List<Customer> list = query.list();

  * 分页查询

 

MySQL实现分页

使用关键字limit

Select * from t_customer limit 0,3;

hql中实现分页

   hql操作中,在语句中不能写limithibernateQuery对象封装了两个方法实现分页操作

 

//1 创建Query对象
Query query = session.createQuery("from Customer ");
//2 设置分页数据
// 设置开始位置
query.setFirstResult(0);
// 设置分页记录数
query.setMaxResults(3);
//3 调用方法得到结果
List<Customer> list = query.list();

 

  * 投影查询

 

投影查询:查询的不是所有字段的值,而是部分字段的值

 

投影查询hql语句写法

* Select 实体类属性名称1,实体类属性名称2 from实体类名称

 

Select 后面不能写 *hql投影查询不支持

 

//1 创建Query对象
Query query = session.createQuery("select custName from Customer ");
// 调用方法得到结果
List<Object> list = query.list();

因为查询的是 cusName,是一个字段,所有集合泛型不能用customer,可以用String,严谨点用Object

 

  * 聚集函数使用

 

常用的聚集函数

Count  sum  avg   max   min

 

Hql聚集函数语句写法

   如:查询表里面的记录数

       Select count(*) from 实体类名称

 

//1 创建Query对象
Query query = session.createQuery("select count(*) from Customer ");
// 调用方法得到结果
// Query对象里面有方法,直接返回对象形式
Object obj = query.uniqueResult();

//首先把object变成long类型,再变成int类型,否则会报错
Long lobj = (Long) obj;
int count = lobj.intValue();
System.out.println(count);

 

QBC查询

 

使用hql查询需要写好语句实现,但是使用QBC的时候,不需要写语句,而是使用方法实现

使用QBC的时候,也是操作实体类和属性

使用QBC时,使用Criteria对象实现

 

* 查询所有

 

创建Criteria对象

调用方法

 

//1 创建Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
// 调用方法得到结果
List<Customer> list = criteria.list();

 

* 条件查询

 

没有语句,使用封装的方法实现

Restrictions类中的一些方法:

           QBC运算符                                          含义
           Restrictions.eq()                                  等于
           Restrictions.not(Exprission.eq())         不等于
           Restrictions.gt()                                   大于
           Restrictions.ge()                                  大于等于
           Restrictions.lt()                                    小于
           Restrictions.le()                                   小于等于
           Restrictions.isnull()                              等于空值
           Restrictions.isNotNull()                        非空值
           Restrictions.like()                                 字符串模式匹配
           Restrictions.and()                                逻辑与
           Restrictions.conjunction()                    逻辑与
           Restrictions.or()                                   逻辑或
           Restrictions.disjunction()                     逻辑或
           Restrictions.not()                                 逻辑非
           Restrictions.in()                                   等于列表中的某一个值
           Restrictions.not(Restrictions.in())        不等于列表中任意一个值
           Restrictions.between()                        闭区间xy中的任意值
           not between x and y  Restrictions.not(Restrictions..between()) 小于值X或者大于值y

查询代码:

 

//创建对象
Criteria criteria = session.createCriteria(Customer.class);
//使用Criteria对象里面的方法设置条件值
//首先使用add方法, 表示设置条件值
//在add方法里使用类的方法实现条件设置
//类似于cid=?
criteria.add(Restrictions.eq("cid",1));
criteria.add(Restrictions.eq("custName","三国"));
//调用方法得到结果
List<Customer> list = criteria.list();

 

* 排序查询

 

//创建对象
Criteria criteria = session.createCriteria(Customer.class);
//设置对那个属性进行排序,设置排序规则
criteria.addOrder(Order.asc("cid"));
//调用方法得到结果
List<Customer> list = criteria.list();

 

* 分页查询

 

//创建对象
Criteria criteria = session.createCriteria(Customer.class);
//设置分页数据
//设置开始位置
criteria.setFirstResult(0);
//每页显示记录数
criteria.setMaxResults(3);

//调用方法得到结果
List<Customer> list = criteria.list();

开始位置计算公式:(当前页-1)*每页记录数

 

* 统计查询

 

//创建对象
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);

 

* 离线查询

不需要使用session就能够得到Criteria对象

 

//创建对象
Criteria criteria = session.createCriteria(Customer.class);

DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);

//最终执行的时候才需要session
Criteria criteria = detachedCriteria.getExecutableCriteria(session);

List<Customer> list = criteria.list();

Servlet调用serviceservice调用dao

dao里面对数据库crud操作

dao里面使用hibernate框架,使用hibernate框架的时候,调用session里面的方法实现功能

 

 

HQL 多表查询

 

MySQL里面多表查询

 

内连接

 select * from t_customer c,t_linkman l where c.cid = l.cid

select * from t_customer c inner join t_linkman l on c.cid = l.cid

 

外连接

  左外连接

 select * from t_customer c left outer join t_linkman l on c.cid = l.cid

 

  右外连接

 select * from t_customer c right outer join t_linkman l on c.cid = l.cid

 

HQL 实现多表查询

    

内连接

内连接查询hql语句写法  以客户和联系人为例

    Form Customer c inner join c.setLinkMan

 

返回的list里面每部分是数组形式


迫切内连接

迫切内连接和内连接底层实现是一样的

区别:内连接返回的list中每部分是数组,迫切内连接返回的list是对象

写法: Form Customer c inner join fetch c.setLinkMan

 

左外连接 

左外连接hql语句

From Customer c left outer join c.setLinkMan

 

迫切左外连接

迫切左外连接语句

From Customer c left outer join fetch c.setLinkMan

区别:左外连接返回的list中每部分是数组,迫切左外连接返回的list是对象

 

右外连接

右外连接hql语句

From Customer c right outer join c.setLinkMan

 

Hibernate检索策略

 

检索策略的概念

  * 立即查询

      根据id查询,调用get方法,一调用get方法马上发送语句查询数据库

  * 延迟查询

      根据id查询,还有load方法,调用load方法不会马上发送语句查询数据,只有得到对象里面的值的时候才会发送语句查询数据库

 

延迟查询有分成两类

    -- 类级别延迟:根据id查询返回实体类对象,调用load方法不会马上发送语句       

    -- 关联级别延迟:查询某个客户,再查询出这个客户里面的所有联系人,查询客户的所有联系人的过程是否需要延迟,这个过程称为关联级别延迟


关联级别延迟操作

 

1 在映射文件中进行配置实现

    根据客户得到所有的联系人,在客户映射文件中配置

2 set标签中使用属性

    Fetch  : 值 select(默认)

    Lazy   : 值  true(延迟)(默认)  

false(不延迟)   

 extra(及其延迟)

 

 

默认效果,写了和不写一样

fetch = "select" lazy = "true"

其他效果可根据属性自由调整

 

批量抓起

 

应用场景:查询所有客户,返回list集合,遍历list集合,得到每个客户,再得到每个客户的所有联系人,不用批量抓取,会发送很多SQL语句,效率极低

  

这个代码会发送很多SQL语句进行查询

使用批量抓取,首先进行配置,在set标签里面配置,batch-size值越大,发送的语句越少,效率越高

 

<set name = "setlinkMan" batch-size = "10">

Hibernate框架到这儿就结束了




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值