用了MybatisPlus之后,感觉自己写sql的机会不多,但是一些多表关联还是需要自己写的。
今天复习一下mybatis中的多表关联查询
建两个简单的表:
emp员工表
dept部门表
员工:部门=多:1
部门:员工=1:多
如果项目中有多对多的关系,需要引入中间表,比如rbac中的用户角色表就是多对多的关系
即员工:部门=多:1
public class EmpDept {
private Integer id;
private String userName;
private Date createDate;
private Integer deptId;
private Dept dept ;
// getter 和setter方法省略
}
方式一:对象属性名.属性
package com.tulingxueyuan.mapper;
import com.tulingxueyuan.pojo.EmpDept;
import java.util.List;
public interface EmpDeptMapper {
List selectEmpWithDept();
}
public class SqlTest {
SqlSessionFactory sqlSessionFactory ;
@Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void test01(){
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpDeptMapper mapper = sqlSession.getMapper(EmpDeptMapper.class);
List empDeptList = mapper.selectEmpWithDept();
System.out.println(empDeptList.size());
System.out.println(empDeptList);
sqlSession.commit();
sqlSession.close();
}
}
方式二:association
1.使用association的第一种写法:指定javaType
association中的property指定多对一种的一
javaType指定类型
2.使用association的第二种写法:指定resultMap
如果不想在association中再写result这种列和属性字段的映射的话,那么就用resultMap来指定一个已经写好的resultMap即可,达到重用的目的。
ps:这时候如果有命名重复的问题,比如emp中有id,dept种也有id,可以用as重命名查询出来的列,之后用columnPrefix="d_"来去掉这个前缀。
public class Dept {
private Integer id;
private String deptName;
//省略getter和setter方法
}
那么使用属性名.属性的方式和使用association的两种方式有什么不同呢?
使用association会强制的使我们的查询结果进行多对一,因为mybatis底层是将主键和查出来的对象放入一个类似hashmap的数据结构中,所以没有查emp的id会造成association失效。association是凭借id来组织多对一的结果。这是非常容易忽视的问题。
使用属性名.属性的方式就不会帮助我们多对一,我们查出来多少条数据就是多少条数据。
其实这种情况使我们工作中应用比较多的场景。
比如:级联查询的时候
这里其实用到了collection,这种情况不像是association还可以用属性名.属性代替一下,这个collection只能就自己这么用,哈哈~
重点 代码:
package com.tulingxueyuan.pojo;
import java.util.List;
public class DeptEmp {
private Integer id;
private String deptName;
private List emps ;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public List getEmps() {
return emps;
}
public void setEmps(List emps) {
this.emps = emps;
}
@Override
public String toString() {
return "DeptEmp{" +
"id=" + id +
", deptName='" + deptName + '\'' +
", emps=" + emps +
'}';
}
}
@Test
public void testCollection(){
SqlSession sqlSession = sqlSessionFactory.openSession();
DeptEmpMapper mapper = sqlSession.getMapper(DeptEmpMapper.class);
List deptEmpList = mapper.selectDeptWithEmp();
System.out.println(deptEmpList.size());
System.out.println(deptEmpList);
sqlSession.commit();
sqlSession.close();
}
其实collection标签的用法和association标签的属性很多用法是相同的。