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

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

一对多映射很容易出现n+1问题,比如一个班级有n个老师和m个学生,我想查询出一个班级及班级的所有学生和老师,
如果按照ibatis普通的一对多映射方法配置的话,就会出现n+1问题。其实ibatis有种方法可以避免的,代码如下。
ibatis配置文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">
<sqlMap namespace="Classes">

	<typeAlias alias="classes" type="com.alibaba.webx.biz.dataobject.Classes" />
	<typeAlias alias="student" type="com.alibaba.webx.biz.dataobject.Student" />
	<typeAlias alias="teacher" type="com.alibaba.webx.biz.dataobject.Teacher" />
	
	<resultMap class="student" id="studentResultMap" groupBy="id">
		<result property="id" column="stuId" />
		<result property="name" column="stuName" />
	</resultMap>	

	<resultMap class="teacher" id="teacherResultMap" groupBy="id">
		<result property="id" column="terId" />
		<result property="name" column="terName" />
	</resultMap>
	
	<resultMap class="classes" id="classesResultMap" groupBy="id">
		<result property="id" column="id" />
		<result property="name" column="name" />
		<result property="studentList" resultMap="Classes.studentResultMap"/>
		<result property="teacherList" resultMap="Classes.teacherResultMap"/>
	</resultMap>
	<select id="findAllClasses" resultMap="Classes.classesResultMap">
		SELECT c.id,c.name,s.id stuId,s.name stuName,t.id terId,t.name terName 
		  FROM class c 
		  JOIN student s 
		    ON c.id=s.classid 
		  JOIN teacher t 
		    ON c.id=t.classid 
	  ORDER BY c.id;
	</select>

</sqlMap>

 

类:

public class Classes {
	private Integer id;
	private String name;
	private List<Student> studentList;
	private List<Teacher> teacherList;

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<Student> getStudentList() {
		return studentList;
	}
	public void setStudentList(List<Student> studentList) {
		this.studentList = studentList;
	}
	public List<Teacher> getTeacherList() {
		return teacherList;
	}
	public void setTeacherList(List<Teacher> teacherList) {
		this.teacherList = teacherList;
	}

	
}

public class Student {
	private Integer id;
	private String name;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

public class Teacher {
	private Integer id;
	private String name;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

 

上面的方法可以一次性查询出所有的记录,ibatis会自动分组,这个可以解决数据量比较小的情况。

但是如果多的一端比如班级的学生数据量比较大,需要分页的话,就不行了。

如果一的一端数据量比较大,比如班级比较多,需要分页的话,我的解决方法是:首先只查询出一页数据的ids,然后再通过ids,

用in的方法查询出数据,很多人说in的性能差,但总比n+1的性能要好很多吧。

 

 

更新

 上传了mybatis的例子代码,使用hsqldb做数据库,直接运行DbManager类的main方法就行了

 

1 楼 Angi 2012-04-05  
例子是不是上传错了呢?
跟ibatis解决多对一n+1问题(更新上传例子(mybatis)代码)中的代码一模一样?