MyBatis-映射文件07-discriminator标签
discriminator鉴别器:mybatis可以使用该鉴别器来判断某列的值,然后根据判断的结果改变封装行为 (类似于switch-case)
需求描述:
根据id查询员工的信息(tbl_employee表),如果查询出来的员工是女生(gender=0),则进而把该员工的部门信息查询出来;如果查询到的是男生(gender=1),就把last_name这一列的值封装到email这一JavaBean变量
解决方案:
1.使用resulyMap封装结果集
2.在resultMap标签内使用标签来进行性别的判断
1)判断结果为0时,使用标签来调用部门的映射文件中的查询方法
2)判断结果为1时,重新定义封装规则
具体代码实现:
EmployeeMapper.class
package dao;
import bean.Employee;
public interface EmployeeMapper {
// 使用鉴别器查询
public Employee getEmpByDis(Integer id);
}
EmployeeMapper.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="dao.EmployeeMapper">
<resultMap type="bean.Employee" id="MyEmpsDis">
<id column="id" property="id" />
<result column="last_name" property="lastName" />
<result column="email" property="email" />
<result column="gender" property="gender" />
<!-- column:指定要判别的列名 javaType:要判别的列的值对应的java类型(数据类型or对象类型) -->
<discriminator javaType="string" column="gender">
<!-- value为要判别的列的不同取值 ,0为女生,1为男生 resultType:指定封装的结果类型 ,不能缺省,也可以使用resultMap -->
<!-- 女生:查部门 -->
<case value="0" resultType="bean.Employee">
<association property="dept" select="dao.DepartmentMapper.getDeptById" column="d_id"></association>
</case>
<!-- 男生:重新定义封装方法 -->
<case value="1" resultType="bean.Employee">
<id column="id" property="id" />
<result column="last_name" property="lastName" />
<result column="last_name" property="email" /> <!-- 把last_name赋值给email -->
<result column="gender" property="gender" />
</case>
</discriminator>
</resultMap>
<!-- 对应的接口中的方法:public Employee getEmpByDis(Integer id); -->
<select id="getEmpByDis" resultMap="MyEmpsDis">
select * from tbl_employee where id = #{id}
</select>
</mapper>
DepartmentMapper.java
package dao;
import bean.Department;
public interface DepartmentMapper {
public Department getDeptById(Integer id);
}
DepartmentMapper.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="dao.DepartmentMapper">
<!-- 对应的接口方法:public Department getDeptById(Integer id); -->
<select id="getDeptById" resultType="bean.Department">
select id,dept_name departmentName from tbl_dept where id = #{id}
</select>
</mapper>
测试方法:
package test;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import bean.Employee;
import dao.EmployeeMapper;
public class MyBatisTest {
// 获取SqlSessionfactory对象的方法
public SqlSessionFactory getSqlSessionFactory() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
return new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void test() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
Employee empByDis = mapper.getEmpByDis(1);
System.out.println(empByDis);
System.out.println(empByDis.getDept());
Employee empByDis2 = mapper.getEmpByDis(4);
System.out.println(empByDis2);
System.out.println(empByDis2.getDept());
} finally {
openSession.close();
}
}
}
测试结果:
DEBUG 11-02 15:05:26,487 ==> Preparing: select * from tbl_employee where id = ? (BaseJdbcLogger.java:145)
DEBUG 11-02 15:05:26,520 ==> Parameters: 1(Integer) (BaseJdbcLogger.java:145)
DEBUG 11-02 15:05:26,541 <== Total: 1 (BaseJdbcLogger.java:145)
Employee [id=1, lastName=Admin, email=Admin, gender=1]
null
DEBUG 11-02 15:05:26,545 ==> Preparing: select * from tbl_employee where id = ? (BaseJdbcLogger.java:145)
DEBUG 11-02 15:05:26,548 ==> Parameters: 4(Integer) (BaseJdbcLogger.java:145)
DEBUG 11-02 15:05:26,552 ====> Preparing: select id,dept_name departmentName from tbl_dept where id = ? (BaseJdbcLogger.java:145)
DEBUG 11-02 15:05:26,553 ====> Parameters: 1(Integer) (BaseJdbcLogger.java:145)
DEBUG 11-02 15:05:26,556 <==== Total: 1 (BaseJdbcLogger.java:145)
DEBUG 11-02 15:05:26,557 <== Total: 1 (BaseJdbcLogger.java:145)
Employee [id=4, lastName=tina, email=tina.com, gender=0]
Department [id=1, departmentName=开发部]
从查询结果可以开出,查询到男生时,并没有去查他的部门信息,因此输出部门时输出结果为null,反而他的email的值与lastName的值相同,因此时使用了重新定义的封装规则;查询到女生时,可以输出她所在的部门信息,且email与lastName值不相同,并且查询女生的部门信息这里使用到了分步查询,利用懒加载,使得只有再需要输出部门信息时才会去发送查询部门的sql请求
p.s.具体的JavaBean实体类的定义与数据库表的定义、以及全局配置文件可参考其他博客