1. 程式人生 > >mybatis 5:SQL對映關係

mybatis 5:SQL對映關係

※ 1 一對一對映 association         Student和Address是一個【一對一】關係         建表語言:       

        drop table students;
        drop table addresses;
        如果需要可以使用 cascade constraints;

        create table addresses(
          addr_id number primary key,
          street varchar2(50) not null,
          city varchar2(50) not null,
          state varchar2(50) not null,
          zip varchar2(10),
          country varchar2(50)
        );

        create table students(
          stud_id number primary key,
          name varchar2(50) not null,
          email varchar2(50),
          phone varchar2(15),  
          dob date ,
          addr_id number references addresses(addr_id)
        );
  java類:
        public class PhoneNumber {
            private String countryCode;
            private String stateCode;
            private String number;
            get/set
        }
        public class Address{
            private Integer addrId;
            private String street;
            private String city;
            private String state;
            private String zip;
            private String country;
            get/set
        }
        public class Student {
            private Integer studId;
            private String name;
            private String email;
            private Date dob;
            private PhoneNumber phone;
            private Address address;
            get/set
        }
 addresses 表的樣例輸入如下所示:
        addr_id  street        city     state    zip   country
        1     redSt        kunshan   W    12345  china
        2     blueST        kunshan   W     12345  china

        insert into addresses(addr_id,street,city,state,zip,country) values(1,'redSt','kunshan','W','12345','china');
        insert into addresses(addr_id,street,city,state,zip,country) values(2,'blueST','kunshan','W','12345','china');


        students 表的樣例資料如下所示:
        stud_id  name    email            phone        addr_id
           1    John  
[email protected]
123-456-7890 1 2 Paul [email protected] 111-222-3333 2 insert into students(stud_id,name,email,phone,addr_id) values(1,'John','[email protected]','123-456-7890',1); insert into students(stud_id,name,email,phone,addr_id) values(2,'Paul','[email protected]','111-222-3333',2); mapper XML: <resultMap type="Student" id="StudentWithAddressResult"> <id property="studId" column="stud_id" /> <result property="name" column="name" /> <result property="email" column="email" /> <result property="phone" column="phone" /> <result property="address.addrId" column="addr_id" /> <result property="address.street" column="street" /> <result property="address.city" column="city" /> <result property="address.state" column="state" /> <result property="address.zip" column="zip" /> <result property="address.country" column="country" /> </resultMap> <select id="selectStudentWithAddress" parameterType="int" resultMap="StudentWithAddressResult"> select stud_id, name, email, a.addr_id, street, city, state, zip, country from students s left outer join addresses a on s.addr_id=a.addr_id where stud_id=#{studid} </select>

        我們可以使用(物件.屬性名)的方式為內嵌的物件的屬性賦值。在上述的resultMap中,Student的address屬性使用該方式被賦上了 address 對應列的值。同樣地,我們可以訪問【任意深度】的內嵌物件的屬性。         

  //介面定義
        public interface Student Mapper{
            Student selectStudentWithAddress(int studId);
        }

        //方法呼叫
        int studId = 1;
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        Student student = studentMapper.selectStudentWithAddress(studId);
        System.out.println("Student :" + student);
        System.out.println("Address :" + student.getAddress());

        上面展示了一對一關聯對映的一種方法。然而,使用這種方式對映,         如果address結果需要在其他的SELECT對映語句中對映成Address物件,我們需要為每一個         語句重複這種對映關係。MyBatis提供了更好地實現一對一關聯對映的方法:         【巢狀結果】ResultMap和【巢狀查詢】select語句。接下來,我們將討論這兩種方式。

        1.1 使用巢狀結果ResultMap實現一對一關係對映         我們可以使用一個巢狀結果ResultMap方式來獲取Student及其Address資訊,程式碼如下:       

          <resultMap type="Address" id="AddressResult">
          <id property="addrId" column="addr_id" />
          <result property="street" column="street" />
          <result property="city" column="city" />
          <result property="state" column="state" />
          <result property="zip" column="zip" />
          <result property="country" column="country" />
        </resultMap>
        <resultMap type="Student" id="StudentWithAddressResult">
          <id property="studId" column="stud_id" />
          <result property="name" column="name" />
          <result property="email" column="email" />
          <association property="address" resultMap="AddressResult" />
        </resultMap>
        <select id="findStudentWithAddress" parameterType="int" resultMap="StudentWithAddressResult">
            select stud_id, name, email, a.addr_id, street, city, state,
            zip, country
            from students s left outer join addresses a on  
            s.addr_id=a.addr_id
            where stud_id=#{studid}
        </select>

                 注:association是關聯的意思         元素<association>被用來匯入“有一個”(has-one)型別的關聯。在上述的例子中,         我們使用了<association>元素引用了另外的在同一個XML檔案中定義的<resultMap>。         同時我們也可以使用<association> 定義內聯的resultMap,程式碼如下所示:         

          <resultMap type="Student" id="StudentWithAddressResult">
          <id property="studId" column="stud_id" />
          <result property="name" column="name" />
          <result property="email" column="email" />
          <association property="address" javaType="Address">
            <id property="addrId" column="addr_id" />
            <result property="street" column="street" />
            <result property="city" column="city" />
            <result property="state" column="state" />
            <result property="zip" column="zip" />
            <result property="country" column="country" />
          </association>
        </resultMap>

          1.2 使用巢狀查詢select實現一對一關係對映         我們可以通過使用巢狀select查詢來獲取Student及其Address資訊,程式碼如下:       

          <resultMap id="AddressResult" type="Address">
          <id property="addrId" column="addr_id" />
          <result property="street" column="street" />
          <result property="city" column="city" />
          <result property="state" column="state" />
          <result property="zip" column="zip" />
          <result property="country" column="country" />
        </resultMap>
        <select id="findAddressById" parameterType="int" resultMap="AddressResult">
            select * from addresses where addr_id=#{id}
        </select>

        <resultMap id="findStudentByIdWithAddress" type="Student">
          <id property="studId" column="stud_id" />
          <result property="name" column="name" />
          <result property="email" column="email" />
          <association property="address" column="addr_id" select="findAddressById" />
        </resultMap>
        <select id="findStudentWithAddress" parameterType="int" resultMap="StudentWithAddressResult">
            select * from students where stud_id=#{id}
        </select>

        在此方式中,<association>元素的select屬性被設定成了id為findAddressById的語句。這裡,兩個分開的SQL語句將會在資料庫中分別執行,第一個呼叫findStudentById載入student資訊,而第二個呼叫findAddressById來載入address資訊。         addr_id列的值將會被作為輸入引數傳遞給selectAddressById語句。                  我們可以如下呼叫findStudentWithAddress對映語句:       

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = mapper.selectStudentWithAddress(studId);
        System.out.println(student);
        System.out.println(student.getAddress());
例項一:一對一

1.例項類 hus和wife

 package com.briup.bean;
/*
 * create table hus(
 * id number primary key,
 * name varchar2(20),
 * age number
 * );
 * create sequence s_hus;
 */
public class Hus implements Comparable<Hus>{
	private long id;
	private String name;
	private int age;
	private Wife wife;
	
	@Override
	public String toString() {
		return "Hus [id=" + id + ", name=" + name + ", age=" + age + ", wife=" + wife + "]";
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Hus(long id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	public Hus(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Hus() {
		super();
	}
	public Wife getWife() {
		return wife;
	}
	public void setWife(Wife wife) {
		this.wife = wife;
	}
	@Override
	public int compareTo(Hus o) {
		return (int) (this.getId()-o.getId());
	}
	
}




package com.briup.bean;
/*
 * create table wife(
 * id number primary key,
 * name varchar2(20),
 * age number,
 * hus_id number  references hus(id)
 * );
 */
public class Wife {
	private long id;
	private String name;
	private int age;
	private Hus hus;
	@Override
	public String toString() {
		return "Wife [id=" + id + ", name=" + name + ", age=" + age + ", hus=" + hus + "]";
	}
	public Wife() {
		super();
	}
	public Wife(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Wife(long id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Hus getHus() {
		return hus;
	}
	public void setHus(Hus hus) {
		this.hus = hus;
	}
}



2.介面Mapper

package com.briup.One2One;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;

import org.apache.ibatis.annotations.Param;

import com.briup.bean.Hus;
import com.briup.bean.Wife;

public interface One2OneMapper {
		void saveHus(Hus hus);
		/*
		 * @Param("id")     sql->#{id}
		 */
		void updateHus(
				@Param("id") long id,
				@Param("names")String name,
				@Param("age")int age);
		
		void deleteHus(long id);
		
		Hus findhus(long id);
		//ArrayList
		List<Hus> findhuss();
		//HashSet
		Set<Hus> findhuss_set();
		//treeset
		SortedSet<Hus> findhuss_sortset();
		/*
		 * 一個Map集合對應結果集中的一行
		 * 資料,結果集的列名為key,列名對應
		 * 的值為value
		 * select * from hus where id =7
		 * id  name age
		 * 7   tom  33
		 * -->map.put("id",7)
		 */
		Map<String, Object> findhus_map(long id);
		
		List<Map<String, Object>> findhus_maps();
		
		int findhus_count();
		
		List<String> fingHus_Name();
		
		void saveWife(Wife wife);
		/*
		 * 查詢出來hus的同時通過Hus可以直接
		 * 取到Wife物件
		 * 
		 * 引數hus的id值
		 */
		Hus findHus_Wife(long id);
		
		List<Hus> findHus_Wifes();
		
		List<Hus> findHus_Wifes1();
		
		List<Hus> findHus_Wifes2();
		
		List<Hus> findHus_Wifes3();
		
}


3.響應xml檔案

<?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.briup.One2One.One2OneMapper">
	<!-- <insert id="saveHus" parameterType="hus">
		insert into hus values(#{id},#{name},#{age})
	</insert> -->
	<!-- -讓序列維護主鍵 -->
	<insert id="saveHus" parameterType="hus">
		<!-- keyProperty指向物件中的屬性(和表中主鍵對應的
		屬性)
		resultType返回的結果為java中的什麼型別(
			指向物件中的屬性型別一致) 
			order生產主鍵的順序
				BEFORE	 先執行序列,把返回的值設定
				給傳入的物件Hus的id屬性,在執行insert語句
				AFTER 先執行insert語句,在執行序列查詢
				把查詢的值賦給物件的id屬性,不對
				插入的資料生效
				注意:oracle中用BEFORE
					mysql支援after,執行insert,在執行序列查詢
				把查詢的值賦給物件的id屬性,同時修改資料庫
				該插入資料的id屬性
			-->
		<selectKey keyProperty="id" resultType="long"
			order="BEFORE">
			select s_hus.nextval from dual
		</selectKey>
		insert into hus values(#{id},#{name},#{age})
	</insert>
	<!-- mysql 主鍵auto_increment欄位修飾 
	mysql策略:useGeneratedKeys="true"開啟主鍵直接
	讓mysql資料庫維護,keyProperty指向作為引數傳入的
	物件屬性(和表中主鍵對應的屬性),
	插入資料成功,自動生產主鍵,主鍵會返回給mybatis
	mybatis基於keyProperty設定給物件的指定屬性
	-->
	<!-- <insert id="saveHus" parameterType="hus"
		useGeneratedKeys="true" keyProperty="id">
		insert into hus(name,age) values(#{name},#{age})
	</insert> -->
	 <update id="updateHus">
		update hus set name=#{names},age=#{age}
		where id=#{id}
	</update> 
	<!-- 在傳入多個引數的時候
	直接基於引數位置角標獲取值  
		#{0} 獲取第一個引數的值 #{1}獲取第二個引數的值
		param1 param2 ..param?
		param1獲取第一個引數的值
		param2獲取第二個引數的值
		
		第三種方式,給介面中方法引數加註解
		@Param("key") ,在對映檔案中直接#{key}取值
	 -->
	<!-- <update id="updateHus">
		update hus set name=#{param2},age=#{param3}
		where id=#{param1}
	</update> --> 
	<delete id="deleteHus" parameterType="long">
		delete from hus
		where id=#{id}
	</delete>
	<!-- resultType表示查詢的結構封裝的物件型別
	如果資料庫表中的列名和物件中的屬性名不一致
	,select後面查詢的列名起別名,別名是封裝物件的
	屬性名,
	如果資料庫表中的列名和物件中的屬性名一致,
	不起別名
	id  name 	age
	
	Hus h=new Hus();
	h.setId(xx)
		
	 -->
	<select id="findhus" parameterType="long"
		resultType="hus">
		select * from hus
		where id=#{id}
	</select>
	<!-- <select id="findhuss"
		resultType="hus">
		select * from hus
	</select> -->
	<resultMap type="hus" id="hus_model">
		<id property="id" column="id"></id>
		<result property="name" column="name"/>
		<result property="age" column="age"/>
	</resultMap>
	<select id="findhuss"
		resultMap="hus_model">
		select * from hus
	</select> 
	<select id="findhuss_set"
		resultMap="hus_model">
		select * from hus
	</select> 
	<select id="findhuss_sortset"
		resultMap="hus_model">
		select * from hus
	</select> 
	<!-- 當返回型別是map的時候resultType="map" -->
	<select id="findhus_map"
		resultType="map" parameterType="long">
		select * from hus
		where id=#{id}
	</select> 
	<select id="findhus_maps"
		resultType="map" >
		select * from hus
	</select> 
	<select id="findhus_count" resultType="int">
		select count(*) from hus
	</select>
	<select id="fingHus_Name" resultType="java.lang.String">
		select name from hus
	</select>
	<!-- 
	Hus  -hus_id
	 -->
	<insert id="saveWife" parameterType="wife">
		<selectKey resultType="long" keyProperty="id"
		order="BEFORE"
		>
		select s_hus.nextval from dual
		</selectKey>
		insert into wife(id,name,age,hus_id) 
		values(#{id},#{name},#{age},#{hus.id})
	</insert>
	<!-- 第一種配置 -->
	<resultMap type="hus" id="hus_modl1">
		<id property="id" column="id"/>
		<result property="name" column="name"/>
		<result property="age" column="age"/>
		<result property="wife.id" column="ids"/>
		<result property="wife.name" column="names"/>
		<result property="wife.age" column="ages"/>
	</resultMap>
	<!-- (物件級聯查詢)多表查詢 ,多個表中列名
	相同,要起別名區分-->
	<select id="findHus_Wife" resultMap="hus_modl1" 
	parameterType="long">
		select h.id,h.name,h.age,w.id ids,w.name names,w.age ages
		from hus h,wife w
		where h.id=w.hus_id and h.id=#{id}
	</select>
	<select id="findHus_Wifes" resultMap="hus_modl1" 
	>
		select h.id,h.name,h.age,w.id ids,w.name names,w.age ages
		from hus h,wife w
		where h.id=w.hus_id 
	</select>
	<!-- 第二種方法 -->
	<resultMap type="wife" id="wife_mod1">
		<id property="id" column="ids"/>
		<result property="name" column="names"/>
		<result property="age" column="ages"/>
	</resultMap>
	<resultMap type="hus" id="hus_modl2">
		<id property="id" column="id"/>
		<result property="name" column="name"/>
		<result property="age" column="age"/>
		<!-- 專門處理一對一對映關係的標籤
		property屬性指向引用變數wife
		 -->
		<association property="wife"  resultMap="wife_mod1"></association>
	</resultMap>
	<select id="findHus_Wifes1" resultMap="hus_modl2" 
	>
		select h.id,h.name,h.age,w.id ids,w.name names,w.age ages
		from hus h,wife w
		where h.id=w.hus_id 
	</select>
	<!-- 第三種形式 -->
	<resultMap type="hus" id="mod1_hus">
	<id property="id" column="id"/>
	<result property="name" column="name"/>
	<result property="age" column="age"/>
	<association property="wife" column="wife">
	   <id property="id" column="ids"/>
	   <result property="name" column="names"/>
	   <result property="age" column="ages"/>
	   </association>
	</resultMap>
	<select id="findHus_Wifes2" resultMap="hus_modl3">
	
	</select>
	<!-- 基於wife表的hus_id查詢一行記錄 -->
	<select id="selectWifeByHus_id" parameterType="long"
	resultType="wife">
	select id,name,age
	from wife
	where hus_id=#{id}
	</select>
	<!-- 查詢hus表中的記錄,通過id到wife表查詢 -->
	<resultMap type="hus" id="mod2_hus">
	<id property="id" column="id"/>
	<result property="name" column="name"/>
	<result property="age" column="age"/>
	<!-- column="id"基於該屬性查詢 -->
	<association property="wife" column="id" select="selectWifeByHus_id">
	</association>
	</resultMap>
	<select id="findHus_Wifes3" resultMap="">
	select id,name,age
	from hus
	</select>
</mapper>


4.測試類
package com.briup.One2One;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.briup.bean.Hus;
import com.briup.bean.Wife;
import com.briup.util.MyBatisSqlSessionFactory;

public class One2OneTest {
	@Test
	public void select_hus_wifes2(){
		try {
		SqlSession session=
				MyBatisSqlSessionFactory.openSession(true);
		One2OneMapper oom=
				session.getMapper(One2OneMapper.class);
		List<Hus> hus=oom.findHus_Wifes2();
		for(Hus h:hus){
			System.out.println(h);
		}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void select_hus_wifes1(){
		try {
		SqlSession session=
				MyBatisSqlSessionFactory.openSession(true);
		One2OneMapper oom=
				session.getMapper(One2OneMapper.class);
		List<Hus> hus=oom.findHus_Wifes1();
		for(Hus h:hus){
			System.out.println(h);
		}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void select_hus_wifes(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			One2OneMapper oom=
					session.getMapper(One2OneMapper.class);
			List<Hus> hus=oom.findHus_Wifes();
			for(Hus h:hus){
				System.out.println(h);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void select_hus_wife(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			One2OneMapper oom=
					session.getMapper(One2OneMapper.class);
			Hus hus=oom.findHus_Wife(11);
			System.out.println(hus);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void save_hus_wife(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			One2OneMapper oom=
					session.getMapper(One2OneMapper.class);
			Hus hus=new Hus("jake2", 33);
			Wife wife=new Wife("rose2", 22);
			wife.setHus(hus);
			oom.saveHus(hus);
			oom.saveWife(wife);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void select_hus_name(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			One2OneMapper oom=
					session.getMapper(One2OneMapper.class);
			List<String> list=oom.fingHus_Name();
			for(String n:list){
				System.out.println(n);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void select_hus_count(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			One2OneMapper oom=
					session.getMapper(One2OneMapper.class);
			int count=oom.findhus_count();
			System.out.println(count);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void select_huss_maps(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			One2OneMapper oom=
					session.getMapper(One2OneMapper.class);
			List<Map<String, Object>> list=oom.findhus_maps();
			for(Map<String, Object> map:list){
				for(Entry<String, Object> en:map.entrySet()){
					System.out.println(en.getKey()+"-"+en.getValue());
				}
				System.out.println("********");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void select_huss_map(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			One2OneMapper oom=
					session.getMapper(One2OneMapper.class);
			Map<String, Object> map=oom.findhus_map(7);
			System.out.println(map.getClass());
			for(Entry<String, Object> en:map.entrySet()){
				System.out.println(en.getKey()+"-"+en.getValue());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void select_huss_sortedset(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			One2OneMapper oom=
					session.getMapper(One2OneMapper.class);
			SortedSet<Hus> hus=oom.findhuss_sortset();
			System.out.println(hus.getClass());
			System.out.println(hus);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void select_huss_set(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			One2OneMapper oom=
					session.getMapper(One2OneMapper.class);
			Set<Hus> hus=oom.findhuss_set();
			System.out.println(hus.getClass());
			System.out.println(hus);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void select_huss(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			List<Hus> hus=session.selectList("com.briup.One2One.One2OneMapper.findhuss");
			System.out.println(hus.getClass());
			//		One2OneMapper oom=
//				session.getMapper(One2OneMapper.class);
//		List<Hus> hus=oom.findhuss();
			System.out.println(hus);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
		@Test
		public void select_hus(){
			try {
				SqlSession session=
						MyBatisSqlSessionFactory.openSession(true);
				//Hus hus=session.selectOne("com.briup.One2One.One2OneMapper.findhus", 2L);
				One2OneMapper oom=
						session.getMapper(One2OneMapper.class);
				Hus hus=oom.findhus(2);
				System.out.println(hus);
			} catch (Exception e) {
				e.printStackTrace();
			}
	}
	@Test
	public void delete_hus(){
		try {
			SqlSession session=
					MyBatisSqlSessionFactory.openSession(true);
			//session.delete("com.briup.One2One.One2OneMapper.deleteHus", 0L);
			One2OneMapper oom=
					session.getMapper(One2OneMapper.class);
			oom.deleteHus(1);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
		@Test
		public void update_hus(){
			try {
				SqlSession session=
						MyBatisSqlSessionFactory.openSession(true);
//		session
//		.update("com.briup.One2One.One2OneMapper.updateHus",hus);
				One2OneMapper oom=
						session.getMapper(One2OneMapper.class);
				oom.updateHus(2, "oooo", 30);
			} catch (Exception e) {
				e.printStackTrace();
			}
	}
	@Test
	public void insert_hus(){
		SqlSession session=
				MyBatisSqlSessionFactory.openSession(true);
		Hus hus=new Hus( "tom", 33);
		System.out.println(hus);
		//第一種方式(可以不構建實現類)
		//第一個引數表示介面中方法的全限定名
		//第二個引數是介面中方法的引數,如果有引數
		//寫在第二個位置,沒有忽略
		//session.insert("com.briup.One2One.One2OneMapper.saveHus",hus);
		//第二種方式
		One2OneMapper oom=
				session.getMapper(One2OneMapper.class);
		oom.saveHus(hus);
		System.out.println(hus);
	}
}

    ※ 2 一對多對映 collection         一個講師tutors可以教授一個或者多個課程course。這意味著講師和課程之間存在一對多的對映關係。         注意:在一對多關係中,資料庫建表的時候外來鍵一定是在多的那一方建立.         

建表語句:
        drop table tutors;
        drop table courses;
        如果需要可以使用 cascade constraints;

        create table tutors(
          tutor_id number primary key,
          name varchar2(50) not null,
          email varchar2(50) ,
          phone varchar2(15) ,  
          addr_id number(11) references addresses (addr_id)
        );

        create table courses(
          course_id number primary key,
          name varchar2(100) not null,
          description varchar2(512),
          start_date date ,
          end_date date ,
          tutor_id number references tutors (tutor_id)
        );
 tutors 表的樣例資料如下:
        tutor_id   name     email          phone        addr_id
            1        zs  [email protected]   123-456-7890    1
            2        ls  [email protected]   111-222-3333    2
        
        insert into tutors(tutor_id,name,email,phone,addr_id)
        values(1,'zs','[email protected]','123-456-7890',1);
        insert into tutors(tutor_id,name,email,phone,addr_id)
        values(2,'ls','[email protected]','111-222-3333',2);

 course 表的樣例資料如下:
        course_id  name  description  start_date   end_date  tutor_id
            1     JavaSE    JavaSE      2015-09-10  2016-02-10   1
            2     JavaEE    JavaEE      2015-09-10  2016-03-10   2
            3     MyBatis   MyBatis     2015-09-10  2016-02-20   2
        
        insert into
        courses(course_id,name,description,start_date,end_date,tutor_id)
        values(1,'JavaSE','JavaSE',to_date('2015-09-10','yyyy-mm-dd'),to_date('2016-02-10','yyyy-mm-dd'),1);

        insert into
        courses(course_id,name,description,start_date,end_date,tutor_id)
        values(2,'JavaEE','JavaEE',to_date('2015-09-10','yyyy-mm-dd'),to_date('2016-03-10','yyyy-mm-dd'),2);

        insert into
        courses(course_id,name,description,start_date,end_date,tutor_id)
        values(3,'MyBatis','MyBatis',to_date('2015-09-10','yyyy-mm-dd'),to_date('2016-02-20','yyyy-mm-dd'),1);

        在上述的表資料中,zs 講師教授一個課程,而 ls 講師教授兩個課程       

 java程式碼:
        public class Tutor{
            private Integer tutorId;
            private String name;
            private String email;
            private PhoneNumber phone;
            private Address address;
            private List<Course> courses;

            get/set
        }

        public class Course{
            private Integer courseId;
            private String name;
            private String description;
            private Date startDate;
            private Date endDate;

            get/set
        }

        <collection>元素被用來將多行課程結果對映成一個課程Course物件的一個集合。和一對一對映一樣,我們可以使用【巢狀結果ResultMap】和【巢狀查詢Select】語句兩種方式對映實現一對多對映。                        2.1 使用內嵌結果 ResultMap 實現一對多對映         我們可以使用巢狀結果resultMap方式獲得講師及其課程資訊,程式碼如下:       

          <resultMap type="Address" id="AddressResult">
          <id property="addrId" column="addr_id" />
          <result property="street" column="street" />
          <result property="city" column="city" />
          <result property="state" column="state" />
          <result property="zip" column="zip" />
          <result property="country" column="country" />
        </resultMap>
        <resultMap type="Course" id="CourseResult">
          <id column="course_id" property="courseId" />
          <result column="name" property="name" />
          <result column="description" property="description" />
          <result column="start_date" property="startDate" />
          <result column="end_date" property="endDate" />
        </resultMap>
        <resultMap type="Tutor" id="TutorResult">
          <id column="tutor_id" property="tutorId" />
          <result column="name" property="name" />
          <result column="email" property="email" />
          <result column="phone" property="phone" />
          <association property="address" resultMap="AddressResult" />
          <collection property="courses" resultMap="CourseResult" />
        </resultMap>
        
        <select id="findTutorById" parameterType="int" resultMap="TutorResult">
            select t.tutor_id, t.name, t.email, c.course_id, c.name, description, start_date, end_date
            from tutors t left outer join addresses a on t.addr_id=a.addr_id
            left outer join courses c on t.tutor_id=c.tutor_id
            where t.tutor_id=#{tutorid}
        </select>

        這裡我們使用了一個簡單的使用了JOINS連線的Select語句獲取講師及其所教課程資訊。<collection>元素的resultMap屬性設定成了CourseResult,CourseResult包含了Course物件屬性與表列名之間的對映。         如果同時也要查詢到Address相關資訊,可以按照上面一對一的方式,在配置中加入<association>即可         2.2 使用巢狀Select語句實現一對多對映         我們可以使用巢狀Select語句方式獲得講師及其課程資訊,程式碼如下:         

          <resultMap type="Address" id="AddressResult">
          <id property="addrId" column="addr_id" />
          <result property="street" column="street" />
          <result property="city" column="city" />
          <result property="state" column="state" />
          <result property="zip" column="zip" />
          <result property="country" column="country" />
        </resultMap>
        <resultMap type="Course" id="CourseResult">
          <id column="course_id" property="courseId" />
          <result column="name" property="name" />
          <result column="description" property="description" />
          <result column="start_date" property="startDate" />
          <result column="end_date" property="endDate" />
        </resultMap>

        <resultMap type="Tutor" id="TutorResult">
          <id column="tutor_id" property="tutorId" />
          <result column="tutor_name" property="name" />
          <result column="email" property="email" />
          <association property="address" column="addr_id" select="findAddressById"></association>
          <!-- 這裡要注意:是把當前tutor_id表中列的值當做引數去執行findCoursesByTutor這個查詢語句,最後把查詢結果封裝到Tutor類中的courses屬性中 -->
          <collection property="courses" column="tutor_id" select="findCoursesByTutor" />
        </resultMap>
        <select id="findTutorById" parameterType="int" resultMap="TutorResult">
            select *  
            from tutors
            where tutor_id=#{tutor_id}
        </select>
        <select id="findAddressById" parameterType="int" resultMap="AddressResult">
            select *
            from addresses
            where addr_id = #{addr_id}
        </select>
        <select id="findCoursesByTutor" parameterType="int" resultMap="CourseResult">
           select *
           from courses
           where tutor_id=#{tutor_id}
        </select>

                 在這種方式中,<aossication>元素的select屬性被設定為id為findCourseByTutor的語句,         用來觸發單獨的SQL查詢載入課程資訊。tutor_id這一列值將會作為輸入引數傳遞給 findCouresByTutor語句。         

  mapper介面程式碼:
        public interface TutorMapper{
            Tutor findTutorById(int tutorId);
        }
        
        //方法呼叫
        TutorMapper mapper = sqlSession.getMapper(TutorMapper.class);
        Tutor tutor = mapper.findTutorById(tutor Id);
        System.out.println(tutor);
        List<Course> courses = tutor.getCourses();
        for (Course course : courses){
            System.out.println(course);
        }

        【注意】巢狀查詢Select語句查詢會導致1+N選擇問題。首先,主查詢將會執行(1 次),         對於主查詢返回的每一行,另外一個查詢將會被執行(主查詢 N 行,則此查詢 N 次)。對於大量資料而言,這會導致很差的效能問題。

例項二:一對多 

1.例項類User和Order

package com.briup.bean;

import java.util.Set;
/*
 * create table s_user(
 * id number primary key,
 * name varchar2(20)
 * )
 * create sequence u_seq;
 */
public class User {
	private long id;
	private String name;
	private Set<Order> orders;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set<Order> getOrders() {
		return orders;
	}
	public void setOrders(Set<Order> orders) {
		this.orders = orders;
	}
	public User(long id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	public User() {
	}
	public User(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", orders=" + orders + "]";
	}
	
}


package com.briup.bean;
/*
 * create table s_order(
 * id number primary key,
 * name varchar2(20),
 * price number,
 * user_id number references s_user(id)
 * )
 */
public class Order {
	private long id;
	private String name;
	private double price;
	public User user;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getPrice() {
		return price;
	}
	public void setPrice(double price) {
		this.price = price;
	}
	public User getUser() {
		return user;
	}
	public void setUser(User user) {
		this.user = user;
	}
	public Order(String name, double price) {
		super();
		this.name = name;
		this.price = price;
	}
	public Order() {
		super();
	}
	@Override
	public String toString() {
		return "Order [id=" + id + ", name=" + name + ", price=" + price + ", user=" + user + "]";
	}
	
}


2.介面mapper

package com.briup.One2Many;

import java.util.List;
import java.util.Set;

import com.briup.bean.Order;
import com.briup.bean.User;

public interface One2ManyMapper {
	void saveUser(User user);
	void saveOrder(Order order);
	//基於使用者的id查詢使用者資訊(
	//級聯的查詢出所有的訂單)
	User findUserAndOrders(long id);
	/*
	 * 基於使用者的id查詢所有的order
	 */
	Set<Order> selectOrderByUser_id(long id);
	/*
	 * 查詢所有的使用者及訂單
	 */
	List<User> selectUserandOrder();
}

3.對映xml檔案

<?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.briup.One2Many.One2ManyMapper">
	<insert id="saveUser" parameterType="user">
		<selectKey keyProperty="id" resultType="long"
		order="BEFORE"
		>
			select u_seq.nextval from dual
		</selectKey>
		insert into s_user values(#{id},#{name})
	</insert>
	<insert id="saveOrder" parameterType="order">
		<selectKey keyProperty="id"
		resultType="long" order="BEFORE"
		>
		select u_seq.nextval from dual
		</selectKey>
		insert into s_order(id,name,price,user_id)
		values(#{id},#{name},#{price},#{user.id})
	</insert>
	<resultMap type="order" id="order_model">
		<id property="id" column="ids"/>
		<result property="name" column="names"/>
		<result property="price" column="price"/>
	</resultMap>
	<resultMap type="user" id="user_model">
		<id property="id" column="id"/>
		<result property="name" column="name"/>
		<!-- 表示集合的封裝  property指向
		單前封裝物件中的集合引用物件-->
		<collection property="orders" 
				resultMap="order_model"></collection>
	</resultMap>
	<select id="findUserAndOrders"
	parameterType="long" resultMap="user_model">
		select s.id,s.name,d.id ids,d.name names,d.price
		from s_user s,s_order d
		where s.id=d.user_id
		 and s.id=#{id}
	</select>
	<!-- 基於使用者的id查詢訂單物件 -->
	<select id="selectOrderByUser_id" parameterType="long"
		resultMap="order_model"
	>
	select id ids,name names,price
	from s_order
	where user_id=#{id}
	</select>
	<resultMap type="user" id="mod_user">
		<id property="id" column="id"/>
		<result property="name" column="name"/>
		<!-- 基於單前查詢的使用者id去order表找
		訂單 -->
		<collection property="orders" column="id" 
			select="selectOrderByUser_id"></collection>
	</resultMap>
	<select id="selectUserandOrder"
	 resultMap="mod_user"
	 >
		select id,name
		from s_user
	 </select>
</mapper>


4.測試類

package com.briup.One2Many;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.briup.bean.Order;
import com.briup.bean.User;
import com.briup.util.MyBatisSqlSessionFactory;

public class One2ManyTest {
	@Test
	public void find_user_order(){
		SqlSession session=
				MyBatisSqlSessionFactory
					.openSession(true);
		One2ManyMapper omm=
		session.getMapper(One2ManyMapper.class);
		List<User> user=omm.selectUserandOrder();
		System.out.println(user);
	}
	@Test
	public void select_user_order(){
		SqlSession session=
				MyBatisSqlSessionFactory
				.openSession(true);
		One2ManyMapper omm=
				session.getMapper(One2ManyMapper.class);
		User user=omm.findUserAndOrders(1L);
		System.out.println(user);
	}
	@Test
	public void save_user_order(){
		SqlSession session=
				MyBatisSqlSessionFactory
				.openSession(true);
		One2ManyMapper omm=
				session.getMapper(One2ManyMapper.class);
		User user=new User("lisi");
		Order order1=new Order("orde1", 34.55);
		order1.setUser(user);
		Order order2=new Order("orde2", 14.55);
		order2.setUser(user);
		Order order3=new Order("orde3", 24.55);
		order3.setUser(user);
		omm.saveUser(user);//id
		
		omm.saveOrder(order1);
		omm.saveOrder(order2);
		omm.saveOrder(order3);
	}
}

         ※ 3 多對多對映         對於在mybatis中的多對多的處理,其實我們可以參照一對多來解決         【注意】在這個例子中有三個欄位都是一樣的:id,這種情況一定要小心,要給列起別名的(上面的一對一和一對多中如果出現這種情況也是一樣的處理方式)         

建表語句:
        drop table student_course;
        drop table course;
        drop table student;
        如果需要可以使用 cascade constraints;

        create table course (
          id number primary key,
          course_code varchar2(30) not null,
          course_name varchar2(30) not null
        );
        create table student (
          id number primary key,
          name varchar2(10) not null,
          gender varchar2(10) ,
          major varchar2(10) ,
          grade varchar2(10)
        );
        create table student_course (
          id number primary key,
          student_id number references student(id),
          course_id number references course(id)
        );
  java程式碼:
        public class Course {
            private Integer id;
            private String courseCode; // 課程編號
            private String courseName;// 課程名稱
            private List<Student> students;// 選課學生
            get/set
        }
        public class Student {
            private Integer id;
            private String name; // 姓名
            private String gender; // 性別
            private String major; // 專業
            private String grade; // 年級
            private List<Course> courses;// 所選的課程
            get/set
        }
        
        Many2ManyMapper.java:
        public interface Many2ManyMapper {
            //插入student資料
            public void insertStudent(Student student);
            //插入course資料
            public void insertCourse(Course course);
            //通過id查詢學生
            public Student getStudentById(Integer id);
            //通過id查詢課程
            public Course getCourseById(Integer id);
            
            //學生x選課y
            public void studentSelectCourse(Student student, Course course);
            //查詢比指定id值小的學生資訊
            public List<Student> getStudentByIdOnCondition(Integer id);
            //查詢student級聯查詢出所選的course並且組裝成完整的物件
            public Student getStudentByIdWithCourses(Integer id);
        }


        Many2ManyMapper.xml:
        <insert id="insertStudent" parameterType="Student">
            <selectKey keyProperty="id" resultType="int" order="BEFORE">
                select my_seq.nextval from dual
            </selectKey>
            insert into
                student(id,name,gender,major,grade)
            values
                (#{id},#{name},#{gender},#{major},#{grade})
        </insert>
        
        <insert id="insertCourse" parameterType="Course">
            <selectKey keyProperty="id" resultType="int" order="BEFORE">
                select my_seq.nextval from dual
            </selectKey>
            insert into
                course(id,course_code,course_name)
            values
                (#{id},#{courseCode},#{courseName})
        </insert>

        <select id="getStudentById" parameterType="int" resultType="Student">
            select id,name,gender,major,grade
            from student
            where id=#{id}
        </select>
        
        <select id="getCourseById" parameterType="int" resultType="Course">
            select id,course_code as courseCode,course_name as courseName
            from course
            where id=#{id}
        </select>

        <!-- param1代表方法中第一個引數 以此類推 -->
        <insert id="studentSelectCourse">
            insert into
                student_course(id,student_id,course_id)
            values
                (my_seq.nextval,#{param1.id},#{param2.id})
        </insert>
        
        <!-- 如果有特殊符號的話 需要用 <![CDATA[ 特殊符號 ]]>  例如 < & 等等 -->
        <select id="getStudentByIdOnCondition" parameterType="int" resultType="Student">
            select *
            from student
            where id <![CDATA[ < ]]> #{id}
        </select>

        <!--
             這裡使用了巢狀結果ResultMap的方式進行級聯查詢
             當然也可以使用巢狀查詢select
        -->
        <!-- 對映一個基本的Student查詢結果 -->
        <resultMap id="StudentResult" type="Student">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <result property="gender" column="gender"/>
            <result property="major" column="major"/>
            <result property="grade" column="grade"/>
        </resultMap>
        <!-- 繼承上面那個基本的對映,再擴展出級聯查詢 -->
        <resultMap id="StudentResultWithCourses" type="Student" extends="StudentResult">
            <collection property="courses" resultMap="CourseResult"></collection>
        </resultMap>
        <!-- 這裡特別要是的是column="cid" 這是和select語句中的 c.id as cid對應的 一定一定一定要對應起來 -->
        <resultMap id="CourseResult" type="Course">
            <id property="id" column="cid"/>
            <result property="courseCode" column="course_code"/>
            <result property="courseName" column="course_name"/>
        </resultMap>
        <!--
            注意:查詢語句的中的c.id as cid這個地方,避免名字相同出現查詢結果不正確的情況
            同時在id="CourseResult"的resultMap中也有與這裡對應的設定要特別特別注意
        -->
        <select id="getStudentByIdWithCourses" parameterType="int" resultMap="StudentResultWithCourses">
            select s.id,s.name,s.gender,s.major,s.grade,c.id as cid,c.course_code,c.course_name,sc.id,sc.student_id,sc.course_id
            from student s,course c,student_course sc
            where
            s.id=#{id}
            and
            s.id=sc.student_id
            and
            sc.course_id=c.id
        </select>
        
        測試程式碼:
        @Test
        public void test_insertStudent(){
            
            SqlSession session = null;
            try {
                session = MyBatisSqlSessionFactory.openSession();
                
                Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);
                    
                mapper.insertStudent(new Student("張三","男","計算機","大四"));
                
                session.commit();
                
            } catch (Exception e) {
                e.printStackTrace();
                session.rollback();
            }finally {
                if(session!=null)session.close();
            }
            
        }
        
        @Test
        public void test_insertCourse(){
            
            SqlSession session = null;
            try {
                session = MyBatisSqlSessionFactory.openSession();
                
                Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);
                    
                mapper.insertCourse(new Course("001","corejava"));
                mapper.insertCourse(new Course("002","oracle"));
                
                session.commit();
                
            } catch (Exception e) {
                e.printStackTrace();
                session.rollback();
            }finally {
                if(session!=null)session.close();
            }
            
        }
        
        @Test
        public void test_studentSelectCourse(){
            
            SqlSession session = null;
            try {
                session = MyBatisSqlSessionFactory.openSession();
                
                Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);
                    
                Student student = mapper.getStudentById(58);
                Course course = mapper.getCourseById(59);
                
                mapper.studentSelectCourse(student, course);
                
                session.commit();
                
            } catch (Exception e) {
                e.printStackTrace();
                session.rollback();
            }finally {
                if(session!=null)session.close();
            }
            
        }
        
        @Test
        public void test_getStudentByIdOnCondition(){
            
            SqlSession session = null;
            try {
                session = MyBatisSqlSessionFactory.openSession();
                
                Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);
                
                List<Student> list = mapper.getStudentByIdOnCondition(100);
                
                for(Student s:list){
                    System.out.println(s);
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if(session!=null)session.close();
            }
            
        }
        
        @Test
        public void test_getStudentByIdWithCourses(){
            
            SqlSession session = null;
            try {
                session = MyBatisSqlSessionFactory.openSession();
                
                Many2ManyMapper mapper = session.getMapper(Many2ManyMapper.class);
                
                Student student = mapper.getStudentByIdWithCourses(58);
                
                System.out.println(student);
                
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if(session!=null)session.close();
            }
            
        }

        注:這是從student這邊出發所做的一些操作,從course一邊開始操作是一樣的,因為倆者的關係是多對多(對稱的).         同時不論是一對一還是一對多還是多對多,都不能在mybatis中進行級聯儲存、更新、刪除,我們需要使用sql語句控制每一步操作

例項3:多對多

1.例項類:student和course

package com.briup.bean;
/*
 * 學生
 * 
 * create table  s_stu(
 * id number primary key,
 * name varchar2(20)
 * )
 * create table  s_course(
 * id number primary key,
 * name varchar2(20)
 * )
 * create table stu_cou(
 * stu_id number references s_stu(id),
 * cou_id number references s_course(id),
 * primary key(stu_id,cou_id)
 * )
 * create sequence sc_seq;
 */

import java.util.Set;

import org.apache.ibatis.type.Alias;
@Alias("stud")
public class Stu {
	private int id;
	private String name;
	private Set<Course> courses;
	
	@Override
	public String toString() {
		return "Stu [id=" + id + ", name=" + name + ", courses=" + courses + "]";
	}
	public Stu() {
		super();
	}
	public Stu(String name) {
		super();
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set<Course> getCourses() {
		return courses;
	}
	public void setCourses(Set<Course> courses) {
		this.courses = courses;
	}
}


package com.briup.bean;
/*
 * 課程
 */

import java.util.Set;

public class Course {
	private long id;
	private String name;
	
	public Course() {
	}
	@Override
	public String toString() {
		return "Course [id=" + id + ", name=" + name + ", stus=" + stus + "]";
	}
	public Course(String name) {
		this.name = name;
	}
	private Set<Stu> stus;
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set<Stu> getStus() {
		return stus;
	}
	public void setStus(Set<Stu> stus) {
		this.stus = stus;
	}
	
}


2.介面mapper

package com.briup.Many2Many;

import java.util.List;
import java.util.Set;

import org.apache.ibatis.annotations.Param;

import com.briup.bean.Course;
import com.briup.bean.Stu;

public interface Many2ManyMapper {
	void saveStu(Stu stu);
	void saveCourse(Course cours);
	Stu findStuByid(int id);
	Course findCourseById(long id);
	/*
	 * 學生選課
	 */
	void saveStu_Course(@Param("stu")Stu stu,@Param("course")Course course);
	/*
	 * 查詢學生資訊及選擇的所有課程
	 */
	Stu findStuAndCourse(int id);
	/*
	 * 查詢選擇某門課程的所有學生
	 */
	List<Course> findCourseAndStu(long id);
	Set<Stu> findStuByids(int id);
}


3.對映xml檔案

<?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.briup.Many2Many.Many2ManyMapper">
	<insert id="saveStu" parameterType="stud">
		<selectKey keyProperty="id" resultType="int"
		order="BEFORE">
		select sc_seq.nextval from dual
		</selectKey>
		insert into s_stu values(#{id},#{name})
	</insert>
	<insert id="saveCourse" parameterType="course">
		<selectKey keyProperty="id" resultType="long"
		order="BEFORE">
		select sc_seq.nextval from dual
		</selectKey>
		insert into s_course values(#{id},#{name})
	</insert>
	<select id="findStuByid" parameterType="int"
	resultType="stud"
	>
		select id,name
		from s_stu
		where id=#{id}
	</select>
	<select id="findCourseById" parameterType="long"
	resultType="course"
	>
		select id,name
		from s_course
		where id=#{id}
	</select>
	
	<!-- 傳入多引數
	#{0} #{1}...
	#{param1} #{param2}
	在介面方法中使用註解@param("key")
	在對映檔案中直接#{key}
	 -->
	<!-- <insert id="saveStu_Course">
		insert into stu_cou values(#{param1.id},#{param2.id})
	</insert> -->
	<insert id="saveStu_Course">
		insert into stu_cou values(#{stu.id},#{course.id})
	</insert>
	<resultMap type="course" id="course_mod">
		<id property="id" column="ids"></id>
		<result property="name" column="names"/>
	</resultMap>
	<resultMap type="stud" id="stud_mod">
		<id property="id" column="id"></id>
		<result property="name" column="name"/>
		<collection property="courses" resultMap="course_mod"></collection>
	</resultMap>
	<select id="findStuAndCourse" parameterType="int"
	resultMap="stud_mod">
	select s.id,s.name,c.id ids,c.name names
	from s_stu s,s_course c,stu_cou sc
	where s.id=sc.stu_id and sc.cou_id=c.id
		and s.id=#{id}
	</select>
	
	<!-- <resultMap type="stud" id="stud1_mod">
		<id property="id" column="id"></id>
		<result property="name" column="name"/>
	</resultMap>
	<resultMap type="course" id="course1_mod">
		<id property="id" column="ids"></id>
		<result property="name" column="names"/>
		<collection property="stus" resultMap="stud1_mod"></collection>
	</resultMap>
	<select id="findCourseAndStu" parameterType="long"
	resultMap="course1_mod"
	>
	select s.id,s.name,c.id ids,c.name names
	from s_stu s,s_course c,stu_cou sc
	where s.id=sc.stu_id and sc.cou_id=c.id
	and c.id=#{id}
	</select> -->
	<select id="findStuByids" parameterType="int"
	resultType="stud"
	>
		select s.id,s.name
		from s_stu s,stu_cou sc
		where s.id=sc.stu_id 
			and sc.cou_id=#{id}
	</select>
	<resultMap type="course" id="course2_mod">
		<id property="id" column="id"/>
		<result property="name" column="name"/>
		<collection property="stus" column="id"
		select="findStuByids"
		></collection>
	</resultMap>
	<select id="findCourseAndStu" parameterType="long"
	resultMap="course2_mod"
	> 
	select id,name
	from s_course
	where id=#{id}
	</select> 
</mapper>

4.測試類

package com.briup.Many2Many;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.briup.bean.Course;
import com.briup.bean.Stu;
import com.briup.util.MyBatisSqlSessionFactory;

public class Many2ManyTest {
	@Test
	public void findStu_and_courses1(){
		try{
		SqlSession session=
				MyBatisSqlSessionFactory
					.openSession(true);
		Many2ManyMapper mm=
		session.getMapper(Many2ManyMapper.class);
		List<Course> c=mm.findCourseAndStu(5L);
		System.out.println(c);
		session.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void findStu_and_courses(){
		try{
			SqlSession session=
					MyBatisSqlSessionFactory
					.openSession(true);
			Many2ManyMapper mm=
					session.getMapper(Many2ManyMapper.class);
			Stu s=mm.findStuAndCourse(3);
			System.out.println(s);
			session.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void saveStu_course(){
		try{
			SqlSession session=
					MyBatisSqlSessionFactory
					.openSession(true);
			Many2ManyMapper mm=
					session.getMapper(Many2ManyMapper.class);
			Stu s=mm.findStuByid(3);
			Course c=mm.findCourseById(4L);
			//Course c1=mm.findCourseById(5L);
			mm.saveStu_Course(s, c);
			//mm.saveStu_Course(s, c1);
			session.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void selectCourse_id(){
		try{
			SqlSession session=
					MyBatisSqlSessionFactory
					.openSession(true);
			Many2ManyMapper mm=
					session.getMapper(Many2ManyMapper.class);
			Course c=mm.findCourseById(4L);
			System.out.println(c);
			session.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void selectStudent_id(){
		try{
			SqlSession session=
					MyBatisSqlSessionFactory
					.openSession(true);
			Many2ManyMapper mm=
					session.getMapper(Many2ManyMapper.class);
			Stu s=mm.findStuByid(1);
			System.out.println(s);
			session.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void saveStudent(){
		try{
			SqlSession session=
					MyBatisSqlSessionFactory
					.openSession(true);
			Many2ManyMapper mm=
					session.getMapper(Many2ManyMapper.class);
			Stu stu=new Stu("lisi");
			Stu stu1=new Stu("jake");
			Stu stu2=new Stu("tom");
			mm.saveStu(stu);
			mm.saveStu(stu1);
			mm.saveStu(stu2);
			session.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	@Test
	public void saveCourse(){
		try{
			SqlSession session=
					MyBatisSqlSessionFactory
					.openSession(true);
			Many2ManyMapper mm=
					session.getMapper(Many2ManyMapper.class);
			Course c=new Course("java");
			Course c1=new Course("oracle");
			mm.saveCourse(c);
			mm.saveCourse(c1);
			session.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
}