当我们需要从数据库获取的数据不光是一张表的数据,而是两张或两张表以上整合或分别提取的字段时,例如拿员工和部门的关系来说,查一个部门内所有员工的信息,因为部门表和员工表是分开定义的,这时候就需要用到多表联合查询。
一对一关系
我们还是拿员工和部门的例子来说,要查一个员工所在部门的信息,一个员工对应着一个部门,所以是一对一的关系。前期的准备工作这里就不讲了,我这里是创建了两个实体类员工和部门,也在数据库创建了两张对应的表,并且员工表里保存了部门号且是部门表部门号的外键,接下来看代码的实现。
方式一
<select id="selectbyid" resultMap="result">
select * from tbl_emp,tnl_dept where emp_id=#{id} and d_id=dept_id
</select>
<resultMap id="result" type="Userinfo">
<id property="empId" column="emp_id"></id>
<result property="empName" column="emp_name"></result>
<result property="gender" column="gender"></result>
<result property="email" column="email"></result>
<result property="dId" column="d_id"></result>
<association property="dept" javaType="Dept">
<id property="deptId" column="dept_id"></id>
<result property="DeptName" column="dept_name"></result>
</association>
</resultMap>
当然你也可以用自然连接写上面的查询语句,把select里面的语句换下就行
select * from tbl_emp INNER JOIN tnl_dept on d_id=dept_id where emp_id=#{id}
这种方式只要你查询语句没有写错都能成功,以下是查询出来的结果
可以看到我们查到了员工以及对应部门的信息,忽略这里的userinfos,这是后面一对多查询时候用到的字段。
方式二
方式二比较复杂,需要分布查询,写多个query语句,以下是实现
<select id="selectbyid" resultMap="result" flushCache="true">
select * from tbl_emp where emp_id=#{id}
</select>
<resultMap id="result" type="Userinfo" >
<id property="empId" column="emp_id"></id>
<result property="empName" column="emp_name"></result>
<result property="gender" column="gender"></result>
<result property="email" column="email"></result>
<result property="dId" column="d_id"></result>
<association property="dept" javaType="Dept" column="d_id" select="selectdp">
<id property="deptId" column="dept_id"></id>
<result property="DeptName" column="dept_name"></result>
</association>
</resultMap>
<select id="selectdp" resultType="Dept">
select * from tnl_dept where dept_id=#{d_id}
</select>
依然查询到了结果
一对多,多对一
我觉得一对多和多对一查询起来都一样,比如说一个老师对应多个学生,反过来就是多个学生对应一个老师,只是站的角度不一样,查询出来的结果是一样的,这里例子给出的是查询一个部门的所有员工信息。
方式一
<select id="finddept" resultMap="result2">
select * from tbl_emp,tnl_dept where dept_id=d_id and dept_id=#{id}
</select>
<resultMap id="result2" type="Dept">
<id property="deptId" column="dept_id"></id>
<result property="DeptName" column="dept_name"></result>
<collection property="userinfos" ofType="userinfo">
<id property="empId" column="emp_id"></id>
<result property="empName" column="emp_name"></result>
<result property="gender" column="gender"></result>
<result property="email" column="email"></result>
<result property="dId" column="d_id"></result>
</collection>
</resultMap>
查询结果如下
方式二
<select id="finddept" resultMap="result5">
select * from tnl_dept where dept_id=#{id}
</select>
<resultMap id="result5" type="Dept">
<id property="deptId" column="dept_id"></id>
<result property="DeptName" column="dept_name"></result>
<collection property="userinfos" column="{did=dept_id}" select="selectUsers" ofType="Userinfo">
<id property="empId" column="emp_id"></id>
<result property="empName" column="emp_name"></result>
<result property="gender" column="gender"></result>
<result property="email" column="email"></result>
<result property="dId" column="d_id"></result>
</collection>
</resultMap>
<select id="selectUsers" resultType="Userinfo">
select * from tbl_emp where d_id=#{did}
</select>
查询结果也一样
多对多
如果要查所有的员工信息以及员工所在的部门信息,这里就用分步查询查了,一次性查的就不写出来了,方法如下
<select id="findAll" resultMap="result3">
select * from tbl_emp
</select>
<resultMap id="result3" type="Userinfo">
<id property="empId" column="emp_id"></id>
<result property="empName" column="emp_name"></result>
<result property="gender" column="gender"></result>
<result property="email" column="email"></result>
<result property="dId" column="d_id"></result>
<association property="dept" javaType="Dept" column="{deptId=d_id}" select="selectDept">
<id property="deptId" column="dept_id"></id>
<result property="DeptName" column="dept_name"></result>
</association>
</resultMap>
<select id="selectDept" resultType="Dept">
select * from tnl_dept where dept_id=#{deptId}
</select>
查询结果如下
如果想一次查询的话查询语句就写
select * from tbl_emp,tnl_dept where dept_id=d_id
然后处理好映射关系就行。
总结
一次性查询的话sql语句可能比较难写,分步查询的话sql语句比较简单,但是一次性查询只需要执行一次sql语句,分布查询需要执行多次,性能的话一次性查询会好点。