Hibernate 效率分析:
连接查询:
说明:在使用hibernate的时候,如果是一个双向的一对多的关联映射,如:(环境)
public class Student {
private int id;
private String name;
private TheClass includeClass;
}
public class TheClass {
private int id;
private String name;
private Set<Student> stuList;
}
在 数据库中的表student中有一个字段theclassid(但是并没有建立数据库外键关联)
下面是hibernate映射文件:
<class name="TheClass" table="class">
<id name="id" column="classid"></id>
<property name="name"></property>
<set name="stuList" cascade="all" inverse="true">
<key column="theclassid"/>
<one-to-many class="Student"/>
</set>
</class>
<class name="Student" table="student">
<id name="id" column="studentid">
</id>
<property name="name"></property>
<many-to-one name="includeClass" column="theclassid" fetch="join" lazy="false"/>
</class>
这是双向的。单向也是一样。这里面使用的是set而非list。(建议使用set而非list)
1. 使用原生sql进行查询
使用原生Sql可以直接通过一条sql语句将全部的字段查询出来,然后自己根据需要进行组装。查询速度会较快,只是组装会比较费时。
2. 使用hql进行查询
Hql查询:在我们一对多关联映射的时候如果想查询一的那一方。如果我们希望将与其关联的child都查出来的话。我们可以在配置set的地方添加一个lazy=”false”,这样的话在查询的时候会自动的将其child查询出来。只不过他查询的方式是,先发出一条sql语句将全部的一的那一方的记录查出来。然后遍历该list。根据关联的字段再发一条sql语句将与该一条记录关联的子记录都查询出来。这样就需要共发出1+n条sql语句。解决它的方式中有一种就是使用连接查询。
连接查询即使用join(还有fetch)来进行查询。
例如我们想把class查出来并且想把所有与他关联的student查询出来,一共有几种方法:
1. 普通的左外连接:
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Query query = session.createQuery("from TheClass t left join t.stuList");
List list = query.list();
System.out.println(list.size());
for(Iterator it = list.iterator();it.hasNext();)
{
Object[] arr = (Object[])it.next();
System.out.println(arr.length);
for(int i=0;i<arr.length;i++)
{
if(arr[i]==null)
{
System.out.println(i+"--is null");
continue;
}
System.out.println(arr[i].getClass().getName());
if(i==0)
{
TheClass tempClass = (TheClass)arr[i];
System.out.println(((TheClass)arr[i]).getName());
Set theSet = tempClass.getStuList();
if(theSet!=null&&theSet.size()>0)
{
Iterator it2 = theSet.iterator();
while(it2.hasNext())
{
Student tempStu = (Student)it2.next();
System.out.println(tempStu.getName());
}
}
}
else
{
System.out.println(((Student)arr[i]).getName());
}
}
}
session.getTransaction().commit();
session.close();
这里使用这种查询方式的时候得到的list里面的每一项是一个Object的数组。其中arr[0]是TheClass对象。Arr[1]是与改TheClass的关联的Student对象。如果与一个TheClass关联的Student一共有五个。那么这个list中会有5个该TheClass对象。他们的arr【1】是与之关联的五个Student。如果一个student也没有。那么会只有一个THeClass对象。且他的arr[1]是null。我们可以自己手动解析该list。然后可以得到我们想要的数据结构。而如果我们通过我们拿到的TheClass对象来获取其中的theStuSet的时候。他里面在此刻并没有值,而当我们一去获取并访问他的时候他也会根据当前的theClass对象发出一条sql语句来查询与之关联的student对象并且组装到这个成员变量中去。
但是这种情况会有所改变:如果我们查询多的一方,然后使用这种方式的话,他会帮助我们把与之相关联的TheClass对象放到Student里面的includeClass成员变量。这时我们可以通过这个直接访问。虽然如此,但是查询得到的list也是object[]。他的结果和上面是一样的。
2. 使用添加fetch的join查询:
Query query = session.createQuery("from TheClass t left join fetch t.stuList as c");
List list = query.list();
System.out.println(list.size());
for(Iterator it = list.iterator();it.hasNext();)
{
TheClass theClass = (TheClass)it.next();
System.out.println(theClass.getName());
Set<Student> stuSet = theClass.getStuList();
if(stuSet!=null&&stuSet.size()>0)
{
Iterator it2 = stuSet.iterator();
while(it2.hasNext())
{
Student stu = (Student)it2.next();
System.out.println(stu.getName());
}
}else
{
System.out.println(" i s null");
}
}
from TheClass t left join fetch t.stuList as c。这里我们在left join后面添加了一个fetch。这样的话查询得到的list就和上面的不一样了。而是一个TheClass对象的List。所以我们可以直接遍历他,然后访问其中的theStuSet。这就是因为hibernate容器帮我们将join查询出来的数据组装到TheClass的成员变量中去了。
分享到:
相关推荐
12.6.1 Struts、Spring和Hibernate的整合方式 12.6.2 编写用户注册画面regedit.jsp 12.6.3 编写用户登录画面login.jsp 12.6.4 编写注册控制器RegeditAction.java 12.6.5 编写登录控制器LoginAction.java 12.6.6 建立...
12.6.1 Struts、Spring和Hibernate的整合方式 12.6.2 编写用户注册画面regedit.jsp 12.6.3 编写用户登录画面login.jsp 12.6.4 编写注册控制器RegeditAction.java 12.6.5 编写登录控制器LoginAction.java 12.6.6 建立...
12.6.1 Struts、Spring和Hibernate的整合方式 12.6.2 编写用户注册画面regedit.jsp 12.6.3 编写用户登录画面login.jsp 12.6.4 编写注册控制器RegeditAction.java 12.6.5 编写登录控制器LoginAction.java 12.6.6 建立...
案例6-1 基于Hibernate连接MySQL数据库实现员工信息查询 214 6.3 Hibernate与Struts的结合应用 223 案例6-2 结合Hibernate和Struts实现商务系统身份验证 224 第7章 Eclipse中SWT/JFace开发 237 7.1 安装...
提供230个实例和4个综合案例,可以作为案头必备的查询手册 一线开发人员全力打造,分享技术盛宴! 重点内容及特色 《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax》介绍了Web开发中客户端技术的...
12.6.1 Struts、Spring和Hibernate的整合方式 12.6.2 编写用户注册画面regedit.jsp 12.6.3 编写用户登录画面login.jsp 12.6.4 编写注册控制器RegeditAction.java 12.6.5 编写登录控制器LoginAction.java 12.6.6 建立...
《Java Web开发技术大全:JSP+Servlet+Struts+Hibernate+Spring+Ajax+》讲解了JSP/S rvlet技术的基础知识,并提供了一个综合案例展示其具体应用,它们是Java Web服务端技术的基石,也是学习Java Web开发所要必须掌握...
本文将包含以下内容(因为篇幅范围,可根据需要选择阅读): c3p0的使用方法(入门案例, JDNI使用) c3p0的配置参数详解c3p0主要源码分析使用示例-入门需求使用C3P0连接池获取连接对象,对用户数据进行简单的增删改...
9.2.3 创建Hibernate使用的数据库连接 140 9.2.4 创建SessionFactory类 140 9.2.5 使用Hibernate配置文件编辑器 141 9.2.6 使用反向工程生成持久化对象、映射文件和DAO类 143 9.2.7 使用Hibernate功能 151 9.3 ...
第3篇 项目案例实战 第23章 在线音乐管理系统(ajax+jsp+struts 2.x) 23.1 在线音乐管理系统简述 23.2 在线音乐管理系统前期准备 23.3 在线音乐管理系统具体实现——超级管理员操作 23.4 在线音乐...
│ │ 13.RPC底层通讯原理之Netty线程模型源码分析.wmv │ │ │ ├─14.分库分表之后分布式下如何保证ID全局唯一性 │ │ 14.分库分表之后分布式下如何保证ID全局唯一性.mp4 │ │ │ └─15.大型公司面试必答之...
主要包括Java Web开发环境、JSP语法、JSP内置对象、Java Bean技术、Servlet技术、EL与JSTL标签库、数据库应用开发、初识Struts2基础、揭密Struts2高级技术、Hib锄劬e技术入门、Hibernate高级应用、Spring核心之IoC、...
3.3.2 Jakarta Commons数据库连接池 49 3.3.3 分布式高速缓存 49 3.4 将iBATIS添加到应用程序中 49 3.4.1 在独立应用程序中使用iBATIS 50 3.4.2 在Web应用程序中使用iBATIS 50 3.5 iBATIS和JDBC 51 3.5.1 释放JDBC...