这是联合查询最简单的应用,实践场景中处处可见。MyBatis Generator 在生成代码的过程中所定义的各种方法和属性都依据数据库中的表结构而来。由于没有设置外键和约束,所以 Employee 表和 Department 表没有在数据库中实现多对一的关系,自然最终实现的单个实体并不带有其他实体的信息。所以要想做到查询员工的时候带有部门信息,需要对已经生成的代码进行一些调整。(先从简单的入手吧,下次找时间去实现查部门信息时显示部门中的员工信息列表,此为欠账 1)
9.1 修改 Employee 类
这里要给 Employee 类中增加 department 属性,添加 getter 和 setter 方法,重写 toString() 方法(最好同时重写 Department 类的 toString() 方法)。代码如下:
//希望查询员工的同时,查询部门信息
private Department department;
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
@Override
public String toString() {
return "Employee [employeeId=" + employeeId + ", employeeName=" + employeeName +
", employeeGender=" + employeeGender + ", employeeEmail=" + employeeEmail +
", departmentId=" + departmentId + ", gmtCreate=" + gmtCreate +
", gmtModified=" + gmtModified + ", department=" + department + "]";
}
9.2 修改 EmployeeMapper.java
要想实现需求,必须给 Mapper 接口中增加相应的方法,提供给业务逻辑调用,对照其他方法的写法(就算我现在不是很明白也没关系,边抄边学——老师说的)增加两个方法如下:
List<Employee> selectByExampleWithDepartment(EmployeeExample example);
Employee selectByPrimaryKeyWithDepartment(Integer employeeId);
9.3 修改 EmployeeMapper.xml
接口方法增加后,一定要在对应的配置文件中注册才会起作用。在注册过程中,还需要添加结果返回列的定义(因为增加了部门表的列)。查询方法采用了连接查询。一时半晌没想到连续连接三个表的情况(多对多?因为有中间表?),这个也等着今后找个案例实现一下(此为欠账 2)。
========================分割线==============================
Mybatis 生成的 xxxMapper.xml 文件中包括:resultMap,SQL,select,delete,insert,update 等标签。可以看出后面四个明显是增删改查(CRUD)的意思,而在 resultMap 中定义了查询返回的结果列。SQL 标签中是将一般是将一些较长的 sql 语句的子句或者其中的一段(如返回结果列)单独进行书写,算是一种抽象吧,然后再在其他四个标签中引用这个 SQL 标签,最终拼成完整的 sql 语句。如果你愿意,也可以直接写到对应的标签中,而不写 SQL 标签。select 标签是修改和编写的重点,而其他三种标签基本上不用修改,只要会用就好了。
如果要建立一种新的查询,除去要增加接口方法外,还要在这里修改(或增加)select 标签,同时可能也需要修改(或增加)resultMap 标签来指定返回结果集的内容。
========================分割线==============================
修改的代码如下:
<!-- 前面的代码 -->
<mapper namespace="com.hh.ssm.dao.EmployeeMapper">
<!-- 中间的代码 -->
<resultMap id="WithDepartmentResultMap" type="com.hh.ssm.bean.Employee">
<id column="employee_id" jdbcType="INTEGER" property="employeeId" />
<result column="employee_name" jdbcType="VARCHAR" property="employeeName" />
<result column="employee_gender" jdbcType="CHAR" property="employeeGender" />
<result column="employee_email" jdbcType="VARCHAR" property="employeeEmail" />
<result column="department_id" jdbcType="INTEGER" property="departmentId" />
<result column="gmt_create" jdbcType="TIMESTAMP" property="gmtCreate" />
<result column="gmt_modified" jdbcType="TIMESTAMP" property="gmtModified" />
<!-- 使用association指定查询部门字段的封装 -->
<association property="department" javaType="com.hh.ssm.bean.Department">
<id column="department_id" property="departmengId" />
<result column="department_name" property="departmentName" />
</association>
</resultMap>
<!-- 中间的代码 -->
<!-- 描述带部门的员工信息的返回列 -->
<sql id="WithDepartment_Column_List">
e.employee_id, e.employee_name, e.employee_gender,
e.employee_email, e.department_id,
e.gmt_create, e.gmt_modified,
d.department_id, d.department_name
</sql>
<!-- 在EmployeeMapper.java 中添加下面两个方法,用于完成查询员工信息时附带部门信息。
Employee selectByPrimaryKey(Integer employeeId);
List<Employee> selectByExampleWithDepartment(EmployeeExample example);
-->
<!-- 查询员工同时带部门信息 -->
<select id="selectByExampleWithDepartment">
select
<if test="distinct">
distinct
</if>
<include refid="WithDepartment_Column_List" />
from ssm_employee e
left join ssm_department d on
e.'department_id'==d.'department_id'
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKeyWithDepartment" parameterType="java.lang.Integer"
resultMap="WithDepartmentResultMap">
select
<include refid="WithDepartment_Column_List" />
from ssm_employee e
left join ssm_department d on
e.'department_id'==d.'department_id'
where employee_id = #{employeeId,jdbcType=INTEGER}
</select>
<!-- 查询员工不带部门信息的两个 select -->
<select id="selectByExample" parameterType="com.hh.ssm.bean.EmployeeExample"
resultMap="BaseResultMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_List" />
from ssm_employee
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer"
resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from ssm_employee
where employee_id = #{employeeId,jdbcType=INTEGER}
</select>
<!-- 后面的代码 -->
</mapper>
大功告成,开始测试!
1月28日补记:
已经将 employee 和 department 都进行了修改,分别引用了另一个对象(或 List 集合)作为属性,对应定义了接口方法,修改了映射文件并测试成功。
欠账1 的后台部分已经测试通过,前台展示待定。
欠账2 目前还没有功能用到,先欠着。