本文内容

  • OID查询
  • 对象导航查询
  • HQL查询
  • QBC查询
  • SQL查询

首发日期:2018-07-31


hibernate的查询方式:

hibernate有很多查询方式

  • OID查询
  • 对象导航查询:
  • HQL查询:
  • QBC查询:
  • SQL查询:

OID查询:

OID查询:基于唯一标识属性(主键)来查询

  • 使用方法:session.get(持久类.class,主键值)或session.load(持久类.class,主键值)
public void test1() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Person p1 = session.get(Person.class, 1L);//因为我用的是Long,所以这里给个1L
Person p2 = session.load(Person.class, 2L);//不会立即发生sql语句
System.out.println(p1);
System.out.println(p2);//这里才发送p2的查询
}

get和load的区别:

load是延迟加载的,意思是当调用load的时候,并不立即发送SQL语句,只有当使用了这个对象的时候才去发送SQL语句。

而且,get对于不存在的对象的查询返回的是null,load会报错。


对象导航查询

对象导航查询:利用对象之间的关系来获取【前提--对象之间建立了关系,比如给某个学生选择了班级,那么就可以通过这个学生来查询到班级,而无法通过这个学生查询到没有跟他绑定的班级】

  • 使用方法:利用对象的关系【参照例子帮助了解,以一对多关系为例。】
public void test2() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Student student = session.get(Student.class, 1L);
Grade grade = student.getGrade();
System.out.println(grade);
Grade grade2 = session.get(Grade.class, 1L);
for (Student s : grade2.getStudents()) {
System.out.println(s);
} }

HQL查询:

HQL是hibernate版本的SQL语句,HQL与SQL相像,不过它的表名变成了类名,字段名变成了属性名。

  • 执行HQL查询:Query query = session.createQuery(HQL语句);

  • 获取结果:query.list()【获取结果集】、query.unique()【如果只查单行单列数据,用这个】

查询所有:

HQL中的"from 类名"相当于SQL中的“select * from 表名”

public void test3() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Query query = session.createQuery("from Student ");
List<Student> list = query.list();
for(Student s :list) {
System.out.println(s);
} }

别名查询

HQL中也给可以给类名指定一个别名。

public void test4() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Query query = session.createQuery("select s from Student s ");
List<Student> list = query.list();
for(Student s :list) {
System.out.println(s);
}

排序查询:

HQL的排序查询也类似于SQL,不过它的排序条件是类的属性名

public void test5() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Query query = session.createQuery("from Student order by id desc");
List<Student> list = query.list();
for(Student s :list) {
System.out.println(s);
}

条件查询:

HQL的条件查询也类似于SQL,不过它的条件中字段名是类的属性名

条件都是跟在from 类名后面,不过设置值的方法有三种:

  1. 直接设置

  2. 使用?占位,然后使用setParameter(下标,值)设置【不过好像一些版本不再支持这个】
  3. 使用:XXX占位,然后是setParameter(XXX,值)设置
public void test6() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
//方式1
// Query query = session.createQuery("from Student where id = 1");
//方式2
// Query query = session.createQuery("from Student where name = ?");
// query.setParameter(0, "李白");
//方式3
Query query = session.createQuery("from Student where id = :aaa");
query.setParameter("aaa", 1L);
List<Student> list = query.list();
for(Student s :list) {
System.out.println(s);
}
}

投影查询:

投影查询就是查询对象的某个或某些属性,这个用法与SQL基本相同。不过这个时候使用query.list得出的结果是Object类型的。

public void test7() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Query query = session.createQuery("select name from Student");
List<Object> list = query.list();
//如果你的Student有合适参数的构造函数,那么你可以这样用,这会帮你封装到对象中,返回的也是Student对象
// Query query = session.createQuery("select new Student(id,name) from Student");
// List<Student> list = query.list(); for(Object s :list) {
System.out.println(s);
}
}

分页查询:

HQL分页查询的核心函数是setMaxResult(一页显示的条数),setFirstResult(第一条记录的索引值)

public void test8() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Query query = session.createQuery("from Student");
query.setMaxResults(3);
query.setFirstResult(0);
List<Student> list = query.list(); for(Student s :list) {
System.out.println(s);
}
}

分组统计查询:

HQL分组统计查询与SQL的分组统计查询的语法相类似。

public void test9() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Query query = session.createQuery("select count(*) from Student group by grade");//这样得出的是Object[]类型的数据
List<Object > list = query.list(); for(Object o :list) {
System.out.println(o);
}
}

多表查询:

HQL的多表查询有几个不同

1.它不是使用表名,它使用持久类的类名

2.它可以使用映射外键,比如:from Student s inner join Grade g on s.grade=g.id

3.使用持久类的类名之后,它可以直接利用关联关系来进行连接,例如:from Student s inner join s.grade

public void test10() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
//内连接
// Query query = session.createQuery("from Student s inner join s.grade");//这样得出的是Object[]类型的数据
// Query query = session.createQuery("from Student s inner join Grade g on s.grade=g.id");//这样得出的是Object[]类型的数据
// List<Object[] > list = query.list();
// for(Object[] o :list) {
// System.out.println(Arrays.toString(o));
// }
//左外连接
// Query query = session.createQuery("from Student s left join s.grade");//这样得出的是Object[]类型的数据
// Query query = session.createQuery("from Student s left join Grade g on s.grade=g.id");//这样得出的是Object[]类型的数据
// List<Object[] > list = query.list();
// for(Object[] o :list) {
// System.out.println(Arrays.toString(o));
// }
//右外连接差不多,这里不讲了
}

多表查询中有两个特殊的连接:迫切内连接和迫切左外连接。当利用关联关系来连接的时候,在后面那个关联之前加个fetch,效果是把后面那个关联持久类的内容封装到前面那个类的实体中。

比如:

补充:

  • 很多时候都要依靠query.list()来获取结果,那么怎么判断返回的结果是什么类型的呢?
    • 查询结果是单列的时候,是Object

    • 查询结果是一个个持久类对象的时候,返回的是持久类
    • 查询结果是多列数据,而且不全是某个持久类的所有数据的时候,返回的是Object[]

QBC查询

  • QBC(Query By Criteria)查询是面向对象的查询
  • 使用方法:Criteria criteria = session.createCriteria(持久类.class);
  • 获取结果: criteria.list();

查询所有:

public void test1() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Criteria criteria = session.createCriteria(Student.class);
List<Student> list = criteria.list();
for(Student s:list) {
System.out.println(s);
}

排序查询:

在查询所有的基础上,调用criteria.addOrder()来进行排序,参数Order.desc(根据哪个字段排序)、Order.asc(根据哪个字段排序)

public void test2() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Criteria criteria = session.createCriteria(Student.class);
criteria.addOrder(Order.desc("id"));
List<Student> list = criteria.list();
for(Student s:list) {
System.out.println(s);
} }

条件查询:

在查询所有的基础上,调用criteria.add()来增加条件,参数是Restrictions.xxx

Restrictions.xxx常用的有

Restrictions.eq(属性名,值):相当于条件 where 字段名 =值

Restrictions.gt(属性名,值):相当于条件 where 字段名 >值

Restrictions.ge(属性名,值):相当于条件 where 字段名 >=值

Restrictions.lt(属性名,值):相当于条件 where 字段名 <值

Restrictions.in(属性名,集合):相当于条件 where 字段名 in 值

默认情况下,增加的每一个都是与的条件,要想添加或的条件,要使用Restrictions.or(多个Restrictions.xxxx),这样里面的条件都是或的了。

public void test4() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Criteria criteria = session.createCriteria(Student.class);
criteria.add(Restrictions.eq("name", "李白"));
List<Student> list = criteria.list();
for(Student s:list) {
System.out.println(s);
} }

分页查询:

criteria调用setFirstResult(第一条记录的索引),调用setMaxResults(一页显示的数量)来进行分页。

public void test3() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Criteria criteria = session.createCriteria(Student.class);
criteria.setFirstResult(0);//第一条记录的索引
criteria.setMaxResults(3);//一页显示多少
List<Student> list = criteria.list();
for(Student s:list) {
System.out.println(s);
} }

统计查询:

criteria调用setProjection(Projections.XXX)来进行统计查询

Projections.XXX有

public void test5() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Criteria criteria = session.createCriteria(Student.class);
criteria.setProjection(Projections.rowCount());
Long count = (Long) criteria.uniqueResult();
System.out.println(count); }

补充:

  • QBC中还有个离线条件查询DetachedCriteria,这里暂时不讲,以后有空再加上。

SQL查询

SQL查询就是直接使用SQL语句来查询

进行查询:SQLQuery sqlQuery = session.createSQLQuery(SQL语句)

获取结果:sqlQuery.list()

相信你是已经学过SQL语句的。所以这里就给出怎么用,不详细介绍各种查询了。

直接使用的时候,返回结果是一个个Object[]

public void test1() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
//发现提示用法过期了,不过还是介绍一下
SQLQuery sqlQuery = session.createSQLQuery("select * from student");
List<Object[] > list = sqlQuery.list();
for(Object[] o:list) {
System.out.println(Arrays.toString(o));
}
}

但可以使用sqlQuery.addEntity(持久类.class)来把数据封装到对象中;

public void test2() {
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
//发现提示用法过期了,不过还是介绍一下
SQLQuery sqlQuery = session.createSQLQuery("select * from student");
sqlQuery.addEntity(Student.class);
List<Student > list = sqlQuery.list();
for(Student s:list) {
System.out.println(s);
}
}

Hibernate:查询的更多相关文章

  1. Hibernate查询

    HIbernate查询 使用get方法 使用get方法通过持久类名和ID号查找一个对象Stu instance = (Stu) getsession() .get("com.lovo.po. ...

  2. Hibernate 查询MatchMode的四种模式

    Hibernate 查询MatchMode的四种模式 MatchMode.START:字符串在最前面的位置.相当于"like 'key%'" MatchMode.END:字符串在最 ...

  3. hibernate查询方式

    hibernate查询方式:1.本地SQL查询 2.HQL查询 3.QBC查询 HQL查询:是面向对象的查询语言,是使用最广的一种查询方法 QBC查询:Query by Criteria是一套接口来实 ...

  4. Hibernate查询出现java.lang.IllegalArgumentException异常解决方法

    Hibernate查询出现java.lang.IllegalArgumentException. 异常信息如下:java.lang.IllegalArgumentException        at ...

  5. (十)Hibernate 查询方式

     所有项目导入对应的hibernate的jar包.mysql的jar包和添加每次都需要用到的HibernateUtil.java 第一节:Hibernate 查询方式简介 1,导航对象图查询方式: 2 ...

  6. 六种方式实现hibernate查询

    最近在学习Hibernate的基本内容,刚好在项目中有用到,基本上都是用到哪就学哪. 今天看看六种方式实现hibernate查询......... 分别是HQL查询,对象化查询Criteria方法,动 ...

  7. 记录使用Hibernate查询bean中字段和数据库列类型不匹配问题

    今天在工程中遇到Hibernate查询的时候,bean中的字段和数据库中的字段不符合(bean中有pageTime字段,但是数据库中没有此列)报错问题. 具体问题环境: 在auto_off表中,off ...

  8. hibernate 查询、二级缓存、连接池

    hibernate 查询.二级缓存.连接池 查询: 1) 主键查询 Dept dept =  (Dept) session.get(Dept.class, 12); Dept dept =  (Dep ...

  9. Hibernate查询、连接池、二级缓存

    Hibernate第三天: 1. 对象状态 2. session缓存 3. lazy懒加载 4. 映射 一对一对映射 组件/继承映射 目标: 一.hibernate查询 二.hibernate对连接池 ...

  10. hibernate查询部分字段转换成实体bean

    //hibernate查询部分字段转换成实体bean /** * 查询线路信息 */ @Override public List<Line> getSimpleLineListByTj(M ...

随机推荐

  1. Docker学习之2——镜像

    镜像(Images) 镜像是Docker的三大核心之一,类似于虚拟机,作用和虚拟机是一样的,唯独是组成部分会有些区别.简单的说如果我们想启动一个容器就必须要有镜像.docker运行容器前需要本地存在对 ...

  2. CentOS7.0小随笔——运行级别

    一.Linux运行级别(通用) 0:关机(halt) 1:单用户模式(无需用户名和密码的登录,用于紧急维护系统时用,类似于Windows中的安全模式) 2:不启用网络功能的多用户模式 3:启用网络功能 ...

  3. JSON数据从MongoDB迁移到MaxCompute最佳实践

    数据及账号准备 首先您需要将数据上传至您的MongoDB数据库.本例中使用阿里云的云数据库 MongoDB 版,网络类型为VPC(需申请公网地址,否则无法与DataWorks默认资源组互通),测试数据 ...

  4. 为什么LINQ to XML的性能要优于XmlDocument?

    一直很忙,压了很多贴,今天发一篇吧.后面的看心情吧. 今天群里有人问如何解析web.config方便,然后我就推荐了Linq to XML,然后就有人说“我宁可XmlDocument,再SeleteN ...

  5. solr调用lucene底层实现倒排索引源码解析

    1.什么是Lucene? 作为一个开放源代码项目,Lucene从问世之后,引发了开放源代码社群的巨大反响,程序员们不仅使用它构建具体的全文检索应用,而且将之集成到各种系统软件中去,以及构建Web应用, ...

  6. spring-session用mysql实现session共享实践

    前段时间,写了篇<spring-session-data-redis解决session共享的问题>文章,介绍了spring-session使用redis存储实现session共享的内部机制 ...

  7. MySQL:windows中困扰着我们的中文乱码问题

    前言:什么是mysql中的中文乱码问题? 话不多说,直接上图 这个东西困扰了我好久,导致我现在对windows映像非常不好,所以就想改成Linux,行了,牢骚就发到这里,直接说问题,明眼人一眼就看出来 ...

  8. 【学习笔记】node.js重构路由功能

    摘要:利用node.js模块化实现路由功能,将请求路径作为参数传递给一个route函数,这个函数会根据参数调用一个方法,最后输出浏览器响应内容 1.介绍 node.js是一个基于Chrome V8引擎 ...

  9. Perl数据序列化和持久化(入门):Storable模块

    Perl提供了一个Storable模块,用来对数据结构进行序列化(serialization,Perl中称为冻结),也就是将数据结构保存为二进制数据. 序列化后的数据可以写入文件实现持久化,可以将持久 ...

  10. python中的模块和包

    模块 一 什么是模块 模块就是一组功能的集合体,可以通过导入模块来复用模块的功能. 比如我在同一个文件夹定义两个.py文件,分别命名为A.py和B.py,那么可以通过在A文件里通过import B来使 ...