1. 程式人生 > >MyBatis-級聯

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

鑑別器

不知道什麼時候派上用場。略。