`

iBatis双向一对多映射中解决N+1查询问题

阅读更多
为了方便,用一个小例子说明问题。有两个实体类,Department和Employee。
Department为一,Employee为多。

package cn.com.legendapl.ibatis.domain;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public class Employee implements java.io.Serializable {

	private static final long serialVersionUID = 8830655291098555343L;

	private Integer id;
	private String name;
	private String title;
	private Department department;

	// getter and setter and constrctor
}

package cn.com.legendapl.ibatis.domain;

import java.util.Set;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public class Department implements java.io.Serializable {

	private static final long serialVersionUID = 133006271347210670L;

	private Integer id;
	private String name;
	private String location;
	private Set<Employee> employees;

	// getter and setter and constrctor
}


两个实体类分别对应数据库的两张表
mysql> desc t_dep;
+-----------+-------------+------+-----+---------+----------------+
| Field     | Type        | Null | Key | Default | Extra          |
+-----------+-------------+------+-----+---------+----------------+
| _id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| _name     | varchar(30) | NO   |     | NULL    |                |
| _location | varchar(50) | YES  |     | NULL    |                |
+-----------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql> desc t_emp;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| _id     | int(11)     | NO   | PRI | NULL    | auto_increment |
| _name   | varchar(30) | NO   |     | NULL    |                |
| _title  | varchar(5)  | YES  |     | NULL    |                |
| _dep_id | int(11)     | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+


在“一”的一方配置时映射时
<resultMap class="Department" id="dep" groupBy="id">
	<result property="id" column="_id"/>
	<result property="name" column="_name"/>
	<result property="location" column="_location"/>
	<result property="employees" resultMap="department.emp"/>
</resultMap>

<resultMap class="cn.com.legendapl.ibatis.domain.Employee" id="emp">
	<result property="id" column="e_id"/>
	<result property="name" column="e_name"/>
	<result property="title" column="e_title"/>
</resultMap>

<select id="query" parameterClass="java.util.Map" resultMap="dep">
	select
		d._id,
		d._name,
		d._location,
		e._id as e_id,
		e._name as e_name,
		e._title as e_title
	from
		t_dep as d
	left join
		t_emp as e
	on
		d._id = e._dep_id
	<dynamic prepend="where">
		<isNotEmpty property="id" prepend="and"> d._id = #id# </isNotEmpty>
	</dynamic>
   </select>


在名为dep的resultMap中配置一项groupBy="id",这样,ibatis在处理结果集时,把id相同的几项“看成”一项来处理。
注意:groupBy属性的配置,是指的映射到的模型的property name 而不是查询的结果集的列名。

dao 实现中
@Repository("departmentDao")
public class DepartmentDaoIbatisImpl implements DepartmentDao {

	@Resource(name="sqlMapClientTemplate")
	private SqlMapClientTemplate sqlMapClientTemplate;

	public Department findDepartmentById(Integer id) {
		Map<String, Object> map = new HashMap<String, Object>(1);
		map.put("id", id);
		Department dep = (Department) sqlMapClientTemplate.queryForObject("department.query", map);
		for (Employee emp : dep.getEmployees()) {
			emp.setDepartment(dep);
		}
		return dep;
	}
}
分享到:
评论
4 楼 Bactryki 2014-04-23  
3 楼 xyz872389734 2012-07-18  
2 楼 a2397772 2012-04-25  
1 楼 wowo365 2011-11-01  

相关推荐

    ibatis解决多对一n+1问题(更新上传例子(mybatis)代码)

    "ibatis解决多对一n+1问题"这个主题聚焦于MyBatis框架中如何高效地处理多对一关联查询,避免出现性能瓶颈的“n+1”问题。这个问题通常发生在查询一对多关系时,如果不对查询进行优化,会导致大量的额外数据库访问,...

    ibatis 一对多 多对多完整映射

    本文将深入探讨如何在iBATIS中实现一对多和多对多的关系映射,并提供相关的源码分析和工具使用技巧。 **一对多关系映射** 在数据库设计中,一对多关系是指一个父记录可以与多个子记录关联,例如,一个用户可以有多...

    ibatis 一对多关系映射

    首先,我们需要在映射文件中定义主表(一对一端)和从表(多对一端)的映射。假设我们有一个`User`类对应`users`表,一个`Order`类对应`orders`表,其中`orders`表有一个`user_id`字段作为外键关联到`users`表。 在...

    ibatis N+1问题

    在IT行业中,数据库查询优化是提升系统性能的关键环节之一,而"Ibatis N+1问题"是使用MyBatis框架时常见的性能瓶颈。这个问题通常出现在一对多或者多对多的关联查询中,导致了大量的数据库交互,严重影响了应用的...

    ibatis n+1选择问题 的几种解决方案

    在数据库查询优化中,"N+1 选择问题"是一个常见的性能瓶颈,特别是在使用ORM(对象关系映射)框架如iBATIS时。N+1问题发生在当我们执行一系列单独的SQL查询来获取关联数据,而不是一次性加载所有所需数据。这可能...

    Ibatis一对一映射提示

    一对一映射是iBATIS中处理关联关系的一种方式,它允许你在查询一个实体对象时,同时获取与其关联的另一个实体对象。这种映射通常涉及到主表和从表,主表中的一条记录对应从表中的唯一一条记录。 **配置一对一映射:...

    ibatis+spring+struts

    在IT行业中,集成框架是构建复杂企业级应用的常用手段,而"Ibatis+Spring+Struts"就是一个经典的Java Web开发组合,也被称作SSM框架。这个框架集合了Struts的MVC设计模式、Spring的依赖注入和事务管理以及Ibatis的...

    ibatis 一对多

    本文将深入探讨`iBatis` 中的一对多映射关系,以及如何通过源码理解和使用这个特性。 一对多映射是数据库关系模型中的常见概念,指的是一个父表(如部门表)可以对应多个子表(如员工表),每个部门可以有多个员工...

    ibatis配置多表关联(一对一、一对多、多对多

    ibatis配置多表关联(一对一、一对多、多对多

    ibatis 用HashMap解决resultClass映射

    ibatis 用HashMap解决Ibatis未知列名和列数的查询结果的resultClass映射

    ibatis 的关系映射

    标题 "ibatis 的关系映射" 指的是在使用 iBATIS(一款优秀的Java持久层框架)时,如何处理数据库中的对象关系映射(ORM)问题。在Java应用程序中,iBATIS 提供了一种方便的方式来将数据库操作与业务逻辑解耦,使得...

    Ibatis+Spring+struts1框架搭建

    【标题】:Ibatis+Spring+Struts1框架搭建 在Web开发中,Ibatis、Spring和Struts1是三个非常重要的组件,它们分别负责不同的职责。Ibatis是一个优秀的持久层框架,Spring是一个全面的后端应用框架,而Struts1则是一...

    iBATIS-SqlMaps,ibatis映射文件

    iBATIS-SqlMaps是Java开发中的一个持久层框架,它提供了一种将SQL语句与Java代码分离的解决方案,从而使得数据库访问更加灵活和易于维护。iBATIS的核心概念是SqlMapConfig.xml配置文件和一系列的SqlMap.xml映射文件...

    struts2+spring+ibatis+mysql

    "Struts2+Spring+Ibatis+MySQL" 是一个经典的Java Web开发框架组合,用于构建高效、可扩展的企业级应用程序。这个组合集成了强大的MVC(Model-View-Controller)框架Struts2、依赖注入与面向切面编程的Spring框架、...

    struts+ibatis登录

    在iBatis的配置文件(通常为`sqlmapconfig.xml`)中,你需要定义一个SQL映射,用于查询用户信息。例如,你可以创建一个名为`getUserByLogin`的SQL语句,该语句接受用户名作为参数,返回用户对象。当用户名和密码匹配...

    spring+struts+ibatis

    在SSM架构中,iBatis作为数据访问层,负责与数据库交互,执行SQL查询,将结果映射为Java对象。 4. ExtJS:ExtJS是一个JavaScript库,用于构建富客户端的Web应用。它提供了丰富的组件和数据绑定功能,可以创建复杂的...

    ibatis实战之一对多关联(源代码)

    在IT领域,特别是Java开发中,iBatis是一个非常受欢迎的...以上是关于iBatis一对多关联映射的实战介绍,希望对您在开发过程中有所帮助。更多关于iBatis的高级用法和最佳实践,可以通过文章链接中的资源进行深入学习。

    Spring+Struts+ibatis讲解

    在Spring+Struts+ibatis这种经典的Java Web开发框架组合中,主要涉及到三层架构:表现层(Action)、业务逻辑层(Service)和数据访问层(DAO)。这些组件协同工作,实现了应用程序的功能。以下是对各部分的详细解释...

    springboot+mysql+ibatis完整整合案例

    在本项目中,"springboot+mysql+ibatis完整整合案例"是一个针对初学者的教程,旨在演示如何将Spring Boot、MySQL数据库和MyBatis框架有效地集成在一起,创建一个可运行的应用程序。以下是对这些技术及其整合过程的...

    spring+ibatis+oracle分页缓存源码

    在Spring+iBatis+Oracle体系中,缓存可以分为两种类型:一级缓存(本地缓存)和二级缓存。 一级缓存是iBatis默认提供的,它存在于SqlSession级别,同一SqlSession内的多次查询会共享结果,避免了重复的数据库访问。...

Global site tag (gtag.js) - Google Analytics