MyBatis之多表关联查询

时间:2023-03-09 04:18:30
MyBatis之多表关联查询

1使用resultType、ResultMap处理返回结果

处理返回结果

resultType:指定返回值结果的完全限定名,处理多表查询的结果。

多表查询需要定义vo封装查询的结果。

需求:查询部门和部门下对应的岗位

部门名称     岗位名称

办公室        职员

办公室        主人

1.1 建立Post的实体类

 package org.guangsoft.entity;
/**
* 岗位的实体类
* @author guanghe
*/
public class Post
{
private Integer pid;
private String pname;
private String pdesc;
public Integer getPid()
{
return pid;
}
public void setPid(Integer pid)
{
this.pid = pid;
}
public String getPname()
{
return pname;
}
public void setPname(String pname)
{
this.pname = pname;
}
public String getPdesc()
{
return pdesc;
}
public void setPdesc(String pdesc)
{
this.pdesc = pdesc;
} }

1.2DeptMapper接口添加方法

 package org.guangsoft.mapper;

 import java.util.List;

 import org.guangsoft.entity.Dept;
import org.guangsoft.vo.DeptVo; public interface DeptMapper
{
public List<DeptVo> getDeptPost(); public List<Dept> getDeptPostList();
}

1.3DeptMapperImpl中重写方法

 package org.guangsoft.mapper.impl;

 import java.util.List;

 import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.guangsoft.entity.Dept;
import org.guangsoft.mapper.DeptMapper;
import org.guangsoft.vo.DeptVo; public class DeptMapperImpl implements DeptMapper
{ @Override
public List<DeptVo> getDeptPost()
{
//创建sqlSessionFactory对象
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
SqlSessionFactory ssf = ssfb.build(DeptMapperImpl.class.
getClassLoader().getResourceAsStream("MyBatis.xml"));
//产生SqlSesion兑现
SqlSession sqlSession = ssf.openSession();
//进行数据的crud操作
List<DeptVo> dlist = sqlSession.selectList("dept.getDeptPost");
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
return dlist;
} @Override
public List<Dept> getDeptPostList()
{
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
SqlSessionFactory ssf = ssfb.build(DeptMapperImpl.class.
getClassLoader().getResourceAsStream("MyBatis.xml"));
//产生SqlSesion兑现
SqlSession sqlSession = ssf.openSession();
//进行数据的crud操作
List<Dept> dlist = sqlSession.selectList("dept.getDeptPostList");
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
return dlist;
} }

1.4建立Post岗位信息表

 /*
Navicat MySQL Data Transfer Source Server : MySQL
Source Server Version : 50715
Source Host : localhost:3306
Source Database : test Target Server Type : MYSQL
Target Server Version : 50715
File Encoding : 65001 Date: 2016-12-13 20:50:00
*/ SET FOREIGN_KEY_CHECKS=0; -- ----------------------------
-- Table structure for post
-- ----------------------------
DROP TABLE IF EXISTS `post`;
CREATE TABLE `post` (
`pid` int(11) NOT NULL AUTO_INCREMENT,
`pname` varchar(255) DEFAULT NULL,
`pdesc` varchar(255) DEFAULT NULL,
`did` int(11) DEFAULT NULL,
PRIMARY KEY (`pid`),
KEY `fk_did` (`did`),
CONSTRAINT `fk_did` FOREIGN KEY (`did`) REFERENCES `dept` (`did`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

1.5DeptMapper.xml定义操作

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dept">
<select id="getDeptPost" resultType="org.guangsoft.vo.DeptVo">
select did,dname,pname from dept inner join post on dept.did = post.did
</select>
<resultMap type="org.guangsoft.entity.Dept" id="deptPost">
<id property="did" column="did"></id>
<result property="dname" column="dname" javaType="java.lang.String"></result>
<collection property="posts" ofType="org.guangsoft.entity.Post">
<id property="pid" column="pid"></id>
<result property="pname" column="pname" javaType="java.lang.String"></result>
<result property="pdesc" column="pdesc" javaType="java.lang.String"></result>
</collection>
</resultMap>
<select id="getDeptPostList" resultMap="deptPost">
select * from dept inner join post
on dept.did = post.did
</select>
</mapper>

1.6添加测试方法

 package org.guangsoft.test;

 import java.util.List;

 import org.guangsoft.entity.Dept;
import org.guangsoft.entity.Post;
import org.guangsoft.mapper.DeptMapper;
import org.guangsoft.mapper.impl.DeptMapperImpl;
import org.guangsoft.vo.DeptVo;
import org.junit.Test; public class TestDeptMapper
{
DeptMapper deptMapper = new DeptMapperImpl(); @Test
public void testGetDeptVo()
{
List<DeptVo> dlist = deptMapper.getDeptPost();
for(DeptVo deptVo : dlist)
{
System.out.println(deptVo.getDid() +
" " + deptVo.getDname() + deptVo.getPname());
}
} @Test
public void testGetDeptList()
{
List<Dept> dlist = deptMapper.getDeptPostList();
for(Dept dept : dlist)
{
System.out.println(dept.getDname());
List<Post> postList = dept.getPosts();
for(Post post : postList)
{
System.out.println(post.getPname());
}
}
} } 

2返回值结果的处理总结

使用resultType:指定的是返回值类型的完全限定名,只能用在单表查询或者定义vo的情况,如果是定义vo不能将关联的数据封装为需要获得某个类的对象

使用resultMap:不需要定义vo类,将关联数据对应的类,作为另外一个类的属性。

第一步:定义resultMap

第二步:引用resultMap

使用resultMap:用来多表关联的复杂查询中,通过需要将关联查询的数据封装为某个实体类对象,如果有特殊业务需要或者说明需要将管理数据封装为实体类的对象,使用resultMap