1. 程式人生 > >關於Mybatis的多對一和一對多查詢

關於Mybatis的多對一和一對多查詢

我們在製作web專案的時候常常會遇到點選查詢詳情資訊或者是顯示多個物件的相同點,這些都可以假想成一堆多或者多對一的情況。

那我們思考一下,能不能在不點選詳情資訊的時候不進行詳情資訊的查詢呢?這樣不是就可以減少資料庫的訪問量,降低記憶體和時間的消耗嗎?

我在使用Mybatis框架的時候,學習到了他自帶的一對多和多對一查詢,需要將sql語句分開再進行非同步載入就可以降低時間和記憶體的消耗了。

一對多(也就是通過該物件的一個特徵去抓取含有這個特徵的其他物件):

例子:一個系裡面含有的教師(通過系id關聯)

教師的bean類(set和get方法自動省略):

public class TeacherT implements Serializable{
    /**
    * 
    */
    private static final long serialVersionUID = -4767749968286241765L;
    private Integer teacherId;
    private String teacherName;
    private Date teacherBirthday;
    private Integer xiId;
    private Integer sexId;
    private Integer titleId;
    private Integer teacherWage;
    private Integer teacherParty;
    private String teacherPassword;
    private String teacherEmail;
}
系的bean類(set和get方法自動省略):
public class DepartmentT implements Serializable {
    /**
     * 
    */
    private static final long serialVersionUID = 2365509376094808947L;
    private String departmentId;
    private String departmentName;
    private String departmentDirectorId;
} 
然後當我們查詢系的資訊的時候我們需要通過系id檢視教師都有哪些,這時候我們需要新建一個bean類,其中包含系的bean和一個可以存教師的容器,在這裡我用的List:
public class DepartmentExt extends DepartmentT {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1388254472842080452L;
	private List<TeacherT> tlist;

	public List<TeacherT> getTlist() {
		return tlist;
	}

	public void setTlist(List<TeacherT> tlist) {
		this.tlist = tlist;
	}
}
bean基本完成,接下來要配置xml檔案,新建一個departmentMapper.xml,含有一個方法查詢出系的所有資訊(由於趕時間這裡用的*不要模仿),新建一個resultMap,繼承含有系資訊的resultmap,然後在裡面配置collection標籤,標籤的屬性property就是上面新建的bean類裡面的list,注意這裡的屬性要用你建立的list的名字,column就是關聯屬性,要放入department_id,oftype就是該list要存的屬性,這裡我放入的teacher的bean類(如果沒配置簡寫方法這裡需要放入bean類的全路徑比如:java.lang.String),select對應的就是通過departmnent_id查詢教師的mapper方法,使用 mapper.方法名 的形式。collection裡面的內容放的就是teacher的所有屬性。
,<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.web.map.DepartmentTMapper" >
<cache/>
  <resultMap id="BaseResultMap" type="departmentT" >
    	<id column="department_id" property="departmentId" jdbcType="CHAR" />
	    <result column="department_name" property="departmentName" jdbcType="CHAR" />
	    <result column="department_director_id" property="departmentDirectorId" jdbcType="CHAR" />
  </resultMap>
  
  
 <resultMap type="departmentExt" id="departmentExtMap" extends="BaseResultMap">
 <collection property="tlist" column="department_id" ofType="teacherT" select="com.web.map.TeacherMapper.selectByDepartmentId">
    <id column="teacher_ID" property="teacherId" jdbcType="INTEGER" />
    <result column="teacher_NAME" property="teacherName" jdbcType="VARCHAR" />
    <result column="teacher_BIRTHDAY" property="teacherBirthday" jdbcType="DATE" />
    <result column="xi_id" property="xiId" jdbcType="INTEGER" />
    <result column="sex_ID" property="sexId" jdbcType="INTEGER" />
    <result column="title_ID" property="titleId" jdbcType="INTEGER" />
    <result column="teacher_WAGE" property="teacherWage" jdbcType="INTEGER" />
    <result column="teacher_PARTY" property="teacherParty" jdbcType="INTEGER" />
    <result column="teacher_PASSWORD" property="teacherPassword" jdbcType="VARCHAR" />
    <result column="teacher_EMAIL" property="teacherEmail" jdbcType="VARCHAR" />
 </collection>
 </resultMap>
 
 <select id="selectDepartment" resultMap="departmentExtMap" >
 select * from department_t
 </select>
</mapper>
departmentMapper.java(介面):
public interface DepartmentTMapper {
    public List<DepartmentExt> selectDepartment();
}
teacher.xml檔案,包含一個selectByDepartment方法,這個方法傳入的引數就是上面配置的colum關聯的屬性。
<?xml version="1.0" encoding="UTF-8" ?>


<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- mapper只能寫一個 -->
<mapper namespace="com.web.map.TeacherMapper">
<resultMap id="BaseResultMap" type="TeacherT" >
    <id column="teacher_ID" property="teacherId" jdbcType="INTEGER" />
    <result column="teacher_NAME" property="teacherName" jdbcType="VARCHAR" />
    <result column="teacher_BIRTHDAY" property="teacherBirthday" jdbcType="DATE" />
    <result column="xi_id" property="xiId" jdbcType="INTEGER" />
    <result column="sex_ID" property="sexId" jdbcType="INTEGER" />
    <result column="title_ID" property="titleId" jdbcType="INTEGER" />
    <result column="teacher_WAGE" property="teacherWage" jdbcType="INTEGER" />
    <result column="teacher_PARTY" property="teacherParty" jdbcType="INTEGER" />
    <result column="teacher_PASSWORD" property="teacherPassword" jdbcType="VARCHAR" />
    <result column="teacher_EMAIL" property="teacherEmail" jdbcType="VARCHAR" />
  </resultMap>
 
 <select id="selectByDepartmentId" resultMap="BaseResultMap" parameterType="java.lang.String">
 	select * from teacher_t where department_id = #{id}
 </select>
</mapper>
teahcerMapper.java:
public interface TeacherMapper {
	public List<TeacherT> selectByDepartmentId(String id);
}
寫到這基本上算是寫完了,現在寫一下Servlet驗證一下:
public void teachersByDepartment(){
		SqlSession session = ColinSqlSessionFactory.getSqlSessionFactory().openSession();
		DepartmentTMapper departmentMapper = session.getMapper(DepartmentTMapper.class);
		List<DepartmentExt> list = departmentMapper.selectDepartment();
		for(DepartmentExt de : list){
			System.out.println("========"+de.getDepartmentName());
			for(TeacherT t:de.getTlist()){
				if(de.getTlist()!=null)
				System.out.println(t.getTeacherName());
			}
		}
	}

可以看到,只需要呼叫DepartmentMapper裡的抽象方法就可以獲取所有資訊了

多對一(多個老師對應一個系):

首先bean前兩個型別是一樣的,我們需要新建一個擴充套件的bean在繼承teacherbean的同時具有departMent物件屬性

public class TeacherandDepartment extends TeacherT {
	/**
	 * 
	 */
	private static final long serialVersionUID = -7128097219788502461L;
	public DepartmentT departmentT;

	public DepartmentT getDepartmentT() {
		return departmentT;
	}

	public void setDepartmentT(DepartmentT departmentT) {
		this.departmentT = departmentT;
	}
}
配置teacherMapper.xml檔案,在新寫的resultmap可以看出繼承了之前的teacher屬性並在此基礎上添加了association標籤property對應的是新的bean類裡面放置的department物件屬性,javatype對應的屬性型別,column對應的關聯屬性,也就是department_id,select對應的departmentMapper裡面的查詢方法
<?xml version="1.0" encoding="UTF-8" ?>


<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- mapper只能寫一個 -->
<mapper namespace="com.web.map.TeacherMapper">
<resultMap id="BaseResultMap" type="TeacherT" >
    <id column="teacher_ID" property="teacherId" jdbcType="INTEGER" />
    <result column="teacher_NAME" property="teacherName" jdbcType="VARCHAR" />
    <result column="teacher_BIRTHDAY" property="teacherBirthday" jdbcType="DATE" />
    <result column="xi_id" property="xiId" jdbcType="INTEGER" />
    <result column="sex_ID" property="sexId" jdbcType="INTEGER" />
    <result column="title_ID" property="titleId" jdbcType="INTEGER" />
    <result column="teacher_WAGE" property="teacherWage" jdbcType="INTEGER" />
    <result column="teacher_PARTY" property="teacherParty" jdbcType="INTEGER" />
    <result column="teacher_PASSWORD" property="teacherPassword" jdbcType="VARCHAR" />
    <result column="teacher_EMAIL" property="teacherEmail" jdbcType="VARCHAR" />
  </resultMap>
 <resultMap type="TeacherandDepartment" id="teacherdepartmentmap" extends="BaseResultMap">
 	<association property="departmentT" javaType="departmentT" column="department_id" select="com.web.map.DepartmentTMapper.selectByTeacherTb">
 		<id column="department_id" property="departmentId" jdbcType="CHAR" />
	    <result column="department_name" property="departmentName" jdbcType="CHAR" />
	    <result column="department_director_id" property="departmentDirectorId" jdbcType="CHAR" />
 	</association>
 </resultMap>
 
 <select id="selectteacher" resultMap="teacherdepartmentmap">
 	select * from teacher_t
 </select>
 
</mapper>
departmentmapper.xml同樣paramenterType引數型別就是column關聯的型別,我這個表在建立的時候id是string型別的
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.web.map.DepartmentTMapper" >
<cache/>
  <resultMap id="BaseResultMap" type="departmentT" >
    	<id column="department_id" property="departmentId" jdbcType="CHAR" />
	    <result column="department_name" property="departmentName" jdbcType="CHAR" />
	    <result column="department_director_id" property="departmentDirectorId" jdbcType="CHAR" />
  </resultMap>
  

 <select id="selectByTeacherTb" resultMap="BaseResultMap" parameterType="java.lang.String">
 select * from department_t where department_id = #{id}
 </select>

</mapper>

teacherMapper.java
public interface TeacherMapper {
	
	public List<TeacherandDepartment> selectteacher();
	
}
departmentMapper.java
public interface DepartmentTMapper {
	public List<DepartmentT> selectByTeacherTb();
    
}
ok到這裡就基本完成了,Servlet測試
public void teacherAndDepartment(){
		SqlSession session = ColinSqlSessionFactory.getSqlSessionFactory().openSession();
		TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);
		List<TeacherandDepartment> list = studentMapper.selectteacher();
		for(TeacherandDepartment t : list){
			System.out.println(t.getTeacherName());
			System.out.println(t.getDepartmentT().getDepartmentName());
		}
	}
可以看到結果都出來了