MyBatis-級聯
元素 | 代表 | 說明 |
---|---|---|
association | 多對一關係 | 比如一個兒子只對應一個親生父親 |
collection | 一對多關係 | 一個父親可以有很多兒女 |
discriminator | 鑑別器 | 可以根據實際選擇採用哪個類作為例項,允許你根據特定的條件去關聯不同的結果集。 |
association多對一級聯
為方便說明,這裡切換到Oracle.scott下的emp和dept表,emp中有deptno欄位,根據deptno可以獲取dept物件,當然可以獲得其下所有欄位資訊,如部門名稱dname和地理位置loc,做法如下:
在com.yan.po.Emp原有基礎上
新增型別為Dept的成員變數dept,程式碼略;在com.yan.dao.mapper.EmpMapper中新增findByAss方法:
Emp findByAss(short empno);
- 在com.yan.dao.mapper.EmpMapper.xml定義一個含有association子元素的resultMap:
<resultMap id="BaseResultMap1" type="com.yan.po.Emp" >
<id column="EMPNO" property="empno" jdbcType ="DECIMAL" />
<result column="ENAME" property="ename" jdbcType="VARCHAR" />
<result column="JOB" property="job" jdbcType="VARCHAR" />
<result column="MGR" property="mgr" jdbcType="DECIMAL" />
<result column="HIREDATE" property="hiredate" jdbcType="DATE" />
<result column="SAL" property="sal" jdbcType="DECIMAL" />
<result column="COMM" property="comm" jdbcType="DECIMAL" />
<association property="dept" column="deptno" select="com.yan.dao.mapper.DeptMapper.selectByPrimaryKey"></association>
</resultMap>
- 在com.yan.dao.mapper.EmpMapper.xml定義含有級聯關係的SQL語句:
<select id="findByAss" resultMap="BaseResultMap1" parameterType="short">
select a.ename,a.job,a.mgr,a.hiredate,a.sal,a.comm,a.deptno
from emp a,dept b
where a.deptno=b.deptno and a.empno=#{empno}
</select>
- 通過以上的配置就可以進行測試了:
SqlSession sqlSession=null;
sqlSession=OrclSqlSessionFactoryUtil.openSqlSession();
EmpMapper empMapper=sqlSession.getMapper(com.yan.dao.mapper.EmpMapper.class);
Emp emp=new Emp();
emp=empMapper.findByAss((short)7369);
/*取得部門名稱*/
System.out.println(emp.getDept().getDname());
/*取得部門位置*/
System.out.println(emp.getDept().getLoc());
可以通過普通的resultMap配置來理解association元素,如果按照基礎用法,Dept物件無法像ename等使用property和column屬性來定義result元素,因而使用association來代替,它代表的是一個自定義類,而非基礎類。
collection一對多
需求:根據部門名稱查詢對應的員工們。
1.與association類似的操作,首先在dept下新增一個emp型別的集合,以Set<Emp>
為例,程式碼略。
2.定義含有Emp集合的resultMap
<resultMap id="collection" type="com.yan.po.Dept" >
<id column="DEPTNO" property="deptno" jdbcType="DECIMAL" />
<result column="DNAME" property="dname" jdbcType="VARCHAR" />
<result column="LOC" property="loc" jdbcType="VARCHAR" />
<collection property="emps" ofType="com.yan.po.Emp">
<id column="EMPNO" property="empno" jdbcType="DECIMAL" />
<result column="ENAME" property="ename" jdbcType="VARCHAR" />
<result column="JOB" property="job" jdbcType="VARCHAR" />
<result column="MGR" property="mgr" jdbcType="DECIMAL" />
<result column="HIREDATE" property="hiredate" jdbcType="DATE" />
<result column="SAL" property="sal" jdbcType="DECIMAL" />
<result column="COMM" property="comm" jdbcType="DECIMAL" />
<result column="DEPTNO" property="deptno" jdbcType="DECIMAL" />
</collection>
</resultMap>
其中collection就代表了Emp的集合,property就是Dept中定義的成員變數的名字,比如Set<Emp> emps
,那麼property就相應定義為emps,ofType就是組成這個集合的基礎類的全類名,現在是Emp的集合,所以寫上它的全類名com.yan.po.Emp
即可。
以上例子中collection的子元素有id和result兩種,都起到規範java與jdbc型別的對映關係,區別是id代表主鍵,而其他result均表示普通欄位。
3.定義好了我們想要的結果和它的結構,就相當於完成了‘前端’的設計,接下來就是要將‘前端’和後臺結合了:
首先定義dao介面:
Dept findEmpsByDname(String dname);
其次定義它的實現:
<select id="findEmpsByDname" resultMap="collection">
select e.* from emp e,dept d where e.deptno=d.deptno and d.dname=#{dname}
</select>
可以看到,在xml檔案中,我們通過select的id屬性標明瞭這是名叫findEmpsByDname的介面的實現,運用resultMap關聯了上面定義的名叫collection的結果集,這樣就完成了‘前端’和後臺的連線。
4.測試程式碼
SqlSession sqlSession=null;
sqlSession=OrclSqlSessionFactoryUtil.openSqlSession();
Dept dept =new Dept();
DeptMapper dm=sqlSession.getMapper(com.yan.dao.mapper.DeptMapper.class);
dept=dm.findEmpsByDname("RESEARCH");
Set<Emp> set=new HashSet<Emp>();
set=dept.getEmps();
for(Emp e:set){
System.out.println(e.getEname());
}
日誌輸出:
2016-12-22 23:01:46,211 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] - Opening JDBC Connection
2016-12-22 23:01:46,325 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] - Created connection 1159656515.
2016-12-22 23:01:46,325 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@451ef443]
2016-12-22 23:01:46,331 DEBUG [com.yan.dao.mapper.DeptMapper.findEmpsByDname] - ==> Preparing: select e.* from emp e,dept d where e.deptno=d.deptno and d.dname=?
2016-12-22 23:01:46,823 DEBUG [com.yan.dao.mapper.DeptMapper.findEmpsByDname] - ==> Parameters: RESEARCH(String)
2016-12-22 23:01:47,074 DEBUG [com.yan.dao.mapper.DeptMapper.findEmpsByDname] - <== Total: 5
FORD
SCOTT
SMITH
JONES
ADAMS
鑑別器
不知道什麼時候派上用場。略。