元素 | 代表 | 说明 |
---|---|---|
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
鉴别器
不知道什么时候派上用场。略。