1. 程式人生 > >MyBatis 關聯查詢 自關聯 (一對多、多對一)

MyBatis 關聯查詢 自關聯 (一對多、多對一)

所謂自關聯是指,自己即充當一方,又充當多方。其實就是普通1:n 和 n:1的變形

1、一對多

1)表結構
-- 新聞欄目
CREATE TABLE `news` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL,
  `pid` int(5) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


2)實體類
// 新聞欄目:當前的新聞欄目被看作是一方,即父欄目
public class News {
	private Integer id;
	private String name;
	private Set<News> childen;
	//省略get set屬性方法
	@Override
	public String toString() {
		return "News [id=" + id + ", name=" + name + ", childen=" + childen
				+ "]";
	}
}
3)Dao介面
public interface INewsDao {
	List<News> selectById(int id);//查詢指定id欄目下面的所有子孫選單

	News selectById2(int id);//查詢指定id欄目及下面的所有子孫選單	
}
4)mapper.xml檔案
	<!-- 查詢指定id欄目下面的所有子孫選單 -->
	<resultMap type="News" id="newsMapper">
		<id column="id" property="id"/>
		<result column="name" property="name"/>
		
		<collection property="childen" 
					ofType="News"
					select="selectById"
					column="id"/>
	</resultMap>
	
 	<select id="selectById" resultMap="newsMapper">
		select id,name from news where pid = #{xxx}
	</select>
	
	
	<!-- 查詢指定id欄目 及 下面的所有子孫選單 -->
	<select id="selectChilden" resultMap="newsMapper">
		select id,name from news where pid=#{ooo}
	</select>
	
	<resultMap type="News" id="newsMapper2">
		<id column="id" property="id"/>
		<result column="name" property="name"/>
		
		<collection property="childen" 
					ofType="News"
					select="selectChilden"
					column="id" />
	</resultMap>
	
	<select id="selectById2" resultMap="newsMapper2">
		select id,name from news where id=#{xxx}
	</select>

標籤屬性可以參考

5)測試輸出:
一、
[DEBUG] ==>  Preparing: select id,name from news where pid = ? 
[DEBUG] ==> Parameters: 1(Integer)
[TRACE] <==    Columns: id, name
[TRACE] <==        Row: 3, 內地娛樂
[DEBUG] ====>  Preparing: select id,name from news where pid = ? 
[DEBUG] ====> Parameters: 3(Integer)
[DEBUG] <====      Total: 0
[TRACE] <==        Row: 4, 港臺娛樂
[DEBUG] ====>  Preparing: select id,name from news where pid = ? 
[DEBUG] ====> Parameters: 4(Integer)
[DEBUG] <====      Total: 0
[DEBUG] <==      Total: 2
News [id=3, name=內地娛樂, childen=[]]
News [id=4, name=港臺娛樂, childen=[]]
二、
[DEBUG] ==>  Preparing: select id,name from news where id=? 
[DEBUG] ==> Parameters: 2(Integer)
[TRACE] <==    Columns: id, name
[TRACE] <==        Row: 2, 體育新聞
[DEBUG] ====>  Preparing: select id,name from news where pid=? 
[DEBUG] ====> Parameters: 2(Integer)
[TRACE] <====    Columns: id, name
[TRACE] <====        Row: 5, 籃球
[DEBUG] ======>  Preparing: select id,name from news where pid = ? 
[DEBUG] ======> Parameters: 5(Integer)
[TRACE] <======    Columns: id, name
[TRACE] <======        Row: 7, NBA
[DEBUG] ========>  Preparing: select id,name from news where pid = ? 
[DEBUG] ========> Parameters: 7(Integer)
[DEBUG] <========      Total: 0
[TRACE] <======        Row: 8, CBA
[DEBUG] ========>  Preparing: select id,name from news where pid = ? 
[DEBUG] ========> Parameters: 8(Integer)
[DEBUG] <========      Total: 0
[DEBUG] <======      Total: 2
[TRACE] <====        Row: 6, 足球
[DEBUG] ======>  Preparing: select id,name from news where pid = ? 
[DEBUG] ======> Parameters: 6(Integer)
[TRACE] <======    Columns: id, name
[TRACE] <======        Row: 9, 意甲
[DEBUG] ========>  Preparing: select id,name from news where pid = ? 
[DEBUG] ========> Parameters: 9(Integer)
[TRACE] <========    Columns: id, name
[TRACE] <========        Row: 12, AC米蘭
[DEBUG] ==========>  Preparing: select id,name from news where pid = ? 
[DEBUG] ==========> Parameters: 12(Integer)
[TRACE] <==========    Columns: id, name
[TRACE] <==========        Row: 14, 皮爾洛
[DEBUG] ============>  Preparing: select id,name from news where pid = ? 
[DEBUG] ============> Parameters: 14(Integer)
[DEBUG] <============      Total: 0
[DEBUG] <==========      Total: 1
[TRACE] <========        Row: 13, 國際米蘭
[DEBUG] ==========>  Preparing: select id,name from news where pid = ? 
[DEBUG] ==========> Parameters: 13(Integer)
[DEBUG] <==========      Total: 0
[DEBUG] <========      Total: 2
[TRACE] <======        Row: 10, 西甲
[DEBUG] ========>  Preparing: select id,name from news where pid = ? 
[DEBUG] ========> Parameters: 10(Integer)
[DEBUG] <========      Total: 0
[TRACE] <======        Row: 11, 中超
[DEBUG] ========>  Preparing: select id,name from news where pid = ? 
[DEBUG] ========> Parameters: 11(Integer)
[DEBUG] <========      Total: 0
[DEBUG] <======      Total: 3
[DEBUG] <====      Total: 2
[DEBUG] <==      Total: 1
News [id=2, name=體育新聞, childen=[News [id=5, name=籃球, childen=[News [id=8, name=CBA, childen=[]], News [id=7, name=NBA, childen=[]]]], News [id=6, name=足球, childen=[News [id=11, name=中超, childen=[]], News [id=10, name=西甲, childen=[]], News [id=9, name=意甲, childen=[News [id=12, name=AC米蘭, childen=[News [id=14, name=皮爾洛, childen=[]]]], News [id=13, name=國際米蘭, childen=[]]]]]]]]

2、多對一

1)實體類有變化:

去掉了private Set<News> childen;其實應該留著,刪掉只是為了便於理解多對一。

添加了private News parent; 肯定只有一個父類欄目

2個成員變數都存在的話,就一個類實現多對一一對多

// 新聞欄目:當前的新聞欄目被看作是多方,即子欄目
public class News {
	private Integer id;
	private String name;
	private News parent;
	//省略get set屬性方法
	@Override
	public String toString() {
		return "News [id=" + id + ", name=" + name + ", parent=" + parent + "]";
	}	
}
2)Dao介面
public interface INewsDao {
	News selectById(int id);//查詢指定id欄目及其所有父輩選單	
}
3)mapper.xml檔案
	<!-- 查詢指定id欄目及其所有父輩選單 -->
	<resultMap type="News" id="newsMapper">
		<id column="id" property="id"/>
		<result column="name" property="name"/>
		
		<association property="parent" 
					 javaType="News"
					 select="selectById"
					 column="pid" />
	</resultMap>
	
 	<select id="selectById" resultMap="newsMapper">
		select id,name,pid from news where id = #{xxx}
	</select>
每一個子欄目,肯定只會存在一個父欄目。所以是一對一的關係,用<association />
4)測試輸出:
測試輸出:
[DEBUG] ==>  Preparing: select id,name,pid from news where id = ? 
[DEBUG] ==> Parameters: 12(Integer)
[TRACE] <==    Columns: id, name, pid
[TRACE] <==        Row: 12, AC米蘭, 9
[DEBUG] ====>  Preparing: select id,name,pid from news where id = ? 
[DEBUG] ====> Parameters: 9(Integer)
[TRACE] <====    Columns: id, name, pid
[TRACE] <====        Row: 9, 意甲, 6
[DEBUG] ======>  Preparing: select id,name,pid from news where id = ? 
[DEBUG] ======> Parameters: 6(Integer)
[TRACE] <======    Columns: id, name, pid
[TRACE] <======        Row: 6, 足球, 2
[DEBUG] ========>  Preparing: select id,name,pid from news where id = ? 
[DEBUG] ========> Parameters: 2(Integer)
[TRACE] <========    Columns: id, name, pid
[TRACE] <========        Row: 2, 體育新聞, 0
[DEBUG] ==========>  Preparing: select id,name,pid from news where id = ? 
[DEBUG] ==========> Parameters: 0(Integer)
[DEBUG] <==========      Total: 0
[DEBUG] <========      Total: 1
[DEBUG] <======      Total: 1
[DEBUG] <====      Total: 1
[DEBUG] <==      Total: 1
News [id=12, name=AC米蘭, parent=News [id=9, name=意甲, parent=News [id=6, name=足球, parent=News [id=2, name=體育新聞, parent=null]]]]