一、Get/Load

Get方法是立即检索,而load是延迟检索,他们都是根据主键进行查询。在<class>标签中,若把lazy属性改为false,load方法就会立即检索,class中的lazy属性仅对load方法有效。在使用load时,当数据库没有找到数据时,会有ObjectNotFoundException,异常。

   public void LazyTest() {
//lazy 改为false或者true,查看打印sql的时机
Tb_User u = session.load(Tb_User.class, "1");
//System.out.println(u.getName());
}

二、1-n或多对多的查询

2.1 set 标签的lazy属性 可以设置为三种值:true,false,extra。

  1. 默认为懒加载策略,即lazy默认为true
  2. Lazy为false时,会采用立即加载
  3. Extra会尽可能的延迟集合初始化的时机,可以重打印的sql语句发现,使用了count
  select
count(ID)
from
TB_ORDER
where
userid =?

2.2   set标签的batch-size属性,确定批量初始化集合元素的个数

2.3   set标签的fetch属性,默认值为select,确定初始化集合的方式

  1.select ,通过正常的方式来初始化set

  2.subselect,通过子查询的方式来初始化所有的set集合,lazty属性有效,batch-size属性失效,此时sql语句

Hibernate:
select
orders0_.userid as userid6_0_1_,
orders0_.ID as ID1_0_1_,
orders0_.ID as ID1_0_0_,
orders0_.NAME as NAME2_0_0_,
orders0_.MONEY as MONEY3_0_0_,
orders0_.COUNT as COUNT4_0_0_,
orders0_.CREATETIME as CREATETIME5_0_0_,
orders0_.userid as userid6_0_0_
from
TB_ORDER orders0_
where
orders0_.userid in (
select
tb_user0_.ID
from
TB_USER tb_user0_
)

  2.4  join,lazy会失效,采用左外连接查询。若使用hql查询,会忽略fetch=join属性

三、n-1的查询

1. many-to-one 的 lazy属性有三个取值:proxy 延迟检索,no-proxy,false 立即检索

2.many-to-one 的 fetch属性有两个取值:select,join,作用和上面的一样。

3.batch-size属性是加到1方的class标签上的,这里不是加到many-to-one上的!

四、采用hql查询

1.使用步骤:

-用过Session的createQuery方法创建一个Query对象,参数为HQL语句

-动态的绑定参数(按参数名字绑定 :参数名,按参数位置绑定 ?)

     //基于参数位置绑定参数值
@Test
public void test1(){
Query query = session.createQuery("FROM Tb_User WHERE name = ? AND id = ?");
query.setParameter(0, "1");
query.setParameter(1, "1");
List<Tb_User> list = query.getResultList();
System.out.println(list.size());
} //基于参数名称绑定参数值
@Test
public void test2(){
Query query = session.createQuery("FROM Tb_User WHERE name = :name AND id = :id");
query.setParameter("name", "1");
query.setParameter("id", "1");
List<Tb_User> list = query.getResultList();
System.out.println(list.size());
}

-调用query相关方法执行查询语句

2.分页查询  两个相关方法 setFirsetResult | setMaxResult

     //分页测试
@Test
public void pageTest(){
Query query = session.createQuery("SELECT id FROM Tb_User");
int pageNo = 2;//当前页数
int pageSize = 4;//每页大小 List<String> list = query
.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(4).getResultList();
for(String u : list){
System.out.println(u);
}
}

3.命名查询 getNamedQuery

命名查询可以让我们在xml中定义hql语句,在映射文件中,class标签外添加;这里用CDATA是因为若hql中有大于>或小于<等符号时,可以避免冲突

<query name = "findUserByName">
<![CDATA[FROM Tb_User a WHERE a.name = :name]]>
</query>

然后通过name属性来执行该语句

  @Test
public void nameQuery(){
Query query = session.getNamedQuery("findUserByName");
List<Tb_User> list = query.setParameter("name", "1").getResultList();
System.out.println(list.size());
}

4.投影查询 查询表中某些字段

这里选择了两个字段,因此每条数据查询出来是一个object数组,由于有多条数据,所以就用了List<Object[]>来保存结果,若只查询一个字段,则可用List<T>来保存结果

    @Test
public void filedQuery(){
String hql = "SELECT a.id ,a.name FROM Tb_User a";
Query query = session.createQuery(hql);
List<Object[]> result = query.getResultList(); for(Object[] objs: result){
System.out.println(Arrays.asList(objs));
//System.out.println(objs[0]);
}
}

当然,也可以在查询出来的同时初始化这个类,如下,注意需要在Tb_User中添加一个只有id和name的构造函数。

    @Test
public void filedQuery2(){
String hql = "SELECT new Tb_User( a.id ,a.name ) FROM Tb_User a";
Query query = session.createQuery(hql);
List<Tb_User> result = query.getResultList(); for(Tb_User u: result){
System.out.println(u);
}
}

5.报表查询,hql可用GROUP BY 和 HAVING 关键字,可以调用一下的聚集函数

-count()

-min()

-max()

-sum()

-avg()

//查询每个用户的最大金额和最小金额
@Test
public void GroupQuery(){
String hql = "SELECT min(a.money) ,max(a.money) FROM Tb_Order a "+
"GROUP BY a.user";
Query query = session.createQuery(hql);
List<Object[]> result = query.getResultList(); for(Object[] objs: result){
System.out.println(Arrays.asList(objs));
//System.out.println(objs[0]);
}
}

6.左外连接

左外连接有两种关键字:LEFT JOIN 和 LEFT JOIN FETCH

LEFT JOIN FETCH的方式是查出来,并且立即初始化集合,集合可能包含有重复的元素,需要去重。去重可用hql的distinct或者hashset集合

    @Test
public void leftJoinFetch() {
String hql = "From Tb_User a LEFT JOIN FETCH a.orders"; //String hql = "SELECT DISTINCT a From Tb_User a LEFT JOIN FETCH a.orders"; //hql去掉重复的字段
Query query = session.createQuery(hql);
List<Tb_User> list = query.getResultList();
//list = new ArrayList<Tb_User>(new LinkedHashSet<Tb_User>(list));//hashset去掉重复字段
for(Tb_User u : list){
System.out.println(u.getName() +"-"+ u.getOrders().size());
}
}

LEFT JOIN方式,默认查出来每条数据是一个对象数组,每个对象数组包含了Tb_User和Tb_Order,但是他并没有初始话集合,初始化集合的操作需要更加映射文件的配置来。可能会有重复,但是只能用hql的distinct关键字去重

    @Test
public void leftJoin() {
String hql = "From Tb_User a LEFT JOIN a.orders"; Query query = session.createQuery(hql);
List<Object[]> list = query.getResultList(); for(Object[] objs : list){
System.out.println(Arrays.asList(objs));
}
}

这下面这种情况下,他会根据user映射文件的配置查询数据库得到他order的数量

    @Test
public void leftJoin2() {
String hql = "SELECT DISTINCT a From Tb_User a LEFT JOIN a.orders"; Query query = session.createQuery(hql);
List<Tb_User> list = query.getResultList(); for(Tb_User u : list){
System.out.println(u.getName() +"-"+ u.getOrders().size());
}
}

内链接也有两个INNER JOIN FETCH 和INNER JOIN 和左外连接的区别在于他不会查询左表不符合条件的记录,在这里即是不返回订单为0的用户。

五、QBC(Query By Criteria) 面向对象的查询

使用Criteria的接口来实现

    @Test
public void qbcTest(){
//1.创建一个Criteria对象
Criteria criteria = session.createCriteria(Tb_User.class);
//2.添加查询条件
criteria.add(Restrictions.eq("id","1"));
//3.执行查询
Tb_User u = (Tb_User)criteria.uniqueResult();
System.out.println(u);
}

他们的and或者or的查询方式

    @Test
public void qbcTest2(){
Criteria criteria = session.createCriteria(Tb_User.class);
// AND : 使用Conjunction表示
Conjunction conjunction = Restrictions.conjunction();
conjunction.add(Restrictions.like("name","1",MatchMode.ANYWHERE));
conjunction.add(Restrictions.eq("id", "1"));
criteria.add(conjunction);
System.out.println(criteria.list());
//or
Criteria criteria1 = session.createCriteria(Tb_Order.class);
Disjunction disjunction = Restrictions.disjunction();
disjunction.add(Restrictions.ge("money",2.0));
disjunction.add(Restrictions.eq("name", "aa"));
criteria1.add(disjunction);
System.out.println(criteria1.list().size());
}

criteria的统计查询

    @Test
public void qbcTest3(){ Criteria criteria = session.createCriteria(Tb_Order.class);
//统计查询:使用prijection来表示
criteria.setProjection(Projections.max("money"));
//添加排序
//criteria.addOrder(Order.asc("id"));
System.out.println(criteria.uniqueResult());
}

他的分页和query.getResultList方法是一样的

六、本地sql查询

若自己写sql查询出来是一个对象数组,使用起来感觉怪怪的。

    @Test
public void nativeSql(){
String sql = "select * from Tb_User where name = :name";
Query query = session.createSQLQuery(sql);
query.setParameter("name", "1");
List<Object[]> list = query.getResultList();
for(Object[] u : list){
System.out.println(Arrays.asList(u));
}
}

若要执行其他sql

    @Test
public void nativeSql(){
UUID u = UUID.randomUUID();
String sql = "insert into Tb_User(id,name) values (:id,:name)";
Query query = session.createSQLQuery(sql);
query.setParameter("id", u.toString());
query.setParameter("name", u.toString());
query.executeUpdate();
}

Demo地址:http://pan.baidu.com/s/1kUT9H91

Hibernate学习笔记--------4.查询的更多相关文章

  1. hibernate学习笔记6--Criteria查询方式、完整小练习(开发步骤)

    一.Criteria查询方式没有sql语了,因此更加面向对象一些.Criteria是一种比HQL更面向对象的查询方式:Criteria的创建方式: Criteria c = s.createCrite ...

  2. Hibernate学习笔记四 查询

    HQL语法 1.基本语法 String hql = " from com.yyb.domain.Customer ";//完整写法 String hql2 = " fro ...

  3. Hibernate学习笔记-Hibernate HQL查询

    Session是持久层操作的基础,相当于JDBC中的Connection,通过Session会话来保存.更新.查找数据.session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库 ...

  4. Hibernate学习笔记(二)

    2016/4/22 23:19:44 Hibernate学习笔记(二) 1.1 Hibernate的持久化类状态 1.1.1 Hibernate的持久化类状态 持久化:就是一个实体类与数据库表建立了映 ...

  5. Hibernate学习笔记(一)

    2016/4/18 19:58:58 Hibernate学习笔记(一) 1.Hibernate框架的概述: 就是一个持久层的ORM框架. ORM:对象关系映射.将Java中实体对象与关系型数据库中表建 ...

  6. Hibernate 学习笔记一

    Hibernate 学习笔记一 今天学习了hibernate的一点入门知识,主要是配置domain对象和表的关系映射,hibernate的一些常用的配置,以及对应的一个向数据库插入数据的小例子.期间碰 ...

  7. mybatis学习笔记(14)-查询缓存之中的一个级缓存

    mybatis学习笔记(14)-查询缓存之中的一个级缓存 标签: mybatis mybatis学习笔记14-查询缓存之中的一个级缓存 查询缓存 一级缓存 一级缓存工作原理 一级缓存測试 一级缓存应用 ...

  8. Linux学习笔记(七) 查询系统

    1.查看命令 (1)man 可以使用 man 命令名称 命令查看某个命令的详细用法,其显示的内容如下: NAME:命令名称 SYNOPSIS:语法 DESCRIPTION:说明 OPTIONS:选项 ...

  9. Hibernate学习笔记(五)—— Hibernate查询方式

    一.对象图导航查询 对象图导航查询方式是根据已经加载的对象,导航到他的关联对象.它利用类与类之间的关系来查询对象.比如要查找一个联系人对应的客户,就可以由联系人对象自动导航找到联系人所属的客户对象.当 ...

随机推荐

  1. 《Python基础教程(第二版)》学习笔记 -> 第一章 基础知识

    写笔记的原因:书也看了一遍,视频也看了,但总是感觉效果不好,一段时间忘记了,再看又觉得有心无力,都是PDF的书籍,打开了就没有心情了,上班一天了,回家看这些东西,真的没多大精力了,所以,我觉得还是把p ...

  2. STM32之CAN ---CAN ID过滤器分析

      1 前言 在CAN协议里,报文的标识符不代表节点的地址,而是跟报文的内容相关的.因此,发送者以广播的形式把报文发送给所有的接收者.节点在接收报文时,根据标识符(CAN ID)的值决定软件是否需要该 ...

  3. prefuse学习(二)显示一张图

    1.  把数据以点连线的方式在画面中显示 2.  数据按照数据的性别属性使用不同的颜色 3.  鼠标左键可以把图在画面中拖动 4.  鼠标右键可以把图放大或者缩小 5.  鼠标单击某个数据上,该数据点 ...

  4. 【noip2011】观光公交

    题解: 做这题的时候为了敢速度- - 直接orz了神小黑的题解 其实我还是有想一个拙计的方法的- - dp:f[i][j] 表示到i点使用j个加速器 在i前上车的人的时间和 轻松愉悦转移之 - - 但 ...

  5. openstack 在线repo

    https://repos.fedorapeople.org/repos/openstack/openstack-kilo/

  6. MapReduce 开发环境搭建(Eclipse\MyEclipse + Maven)

    写在前面的话 可详细参考,一定得去看 HBase 开发环境搭建(Eclipse\MyEclipse + Maven) Zookeeper项目开发环境搭建(Eclipse\MyEclipse + Mav ...

  7. URL编码原理解释

    当你在浏览器中输入一个URL时,浏览器会将你输入到地址栏的非数字字母转化为URI编码. 那么,它是按照什么样的规则来转换的呢 是这样的,URI编码就是一个字符的ASCII码,它的ACSII码的十六进制 ...

  8. http 需要掌握的知识点(一)

    超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.HTTP 也属于 TCP/IP 协议族的子集,想要学习 HTTP ,先需要了解 ...

  9. iOS开发 autoResizingMask使用

    autoResizingMask 是UIView的一个属性,在一些简单的布局中,使用autoResizingMask,可以实现子控件相对于父控件的自动布局. autoResizingMask 是UIV ...

  10. readonly disabled 区别

    readonly 提交表单时包含该属性的内容 控件 disabled 不包含该属性