当前位置:   article > 正文

Mybatis多表关联查询_mybatisplus多表联查

mybatisplus多表联查

用了MybatisPlus之后,感觉自己写sql的机会不多,但是一些多表关联还是需要自己写的。

今天复习一下mybatis中的多表关联查询

建两个简单的表:

emp员工表

dept部门表

 

 员工:部门=多:1

部门:员工=1:多

如果项目中有多对多的关系,需要引入中间表,比如rbac中的用户角色表就是多对多的关系

1.针对多对一的情况:

 即员工:部门=多:1

  1. public class EmpDept {
  2. private Integer id;
  3. private String userName;
  4. private Date createDate;
  5. private Integer deptId;
  6. private Dept dept ;
  7. // getter 和setter方法省略
  8. }

方式一:对象属性名.属性

  1. package com.tulingxueyuan.mapper;
  2. import com.tulingxueyuan.pojo.EmpDept;
  3. import java.util.List;
  4. public interface EmpDeptMapper {
  5. List<EmpDept> selectEmpWithDept();
  6. }
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.tulingxueyuan.mapper.EmpDeptMapper">
  4. <resultMap id="BaseResultMap" type="com.tulingxueyuan.pojo.EmpDept">
  5. <id column="id" jdbcType="INTEGER" property="id" />
  6. <result column="user_name" jdbcType="VARCHAR" property="userName" />
  7. <result column="create_date" jdbcType="TIMESTAMP" property="createDate" />
  8. <result column="dept_id" jdbcType="INTEGER" property="deptId" />
  9. <!--方式一:对象属性名.属性-->
  10. <result column="d_id" property="dept.id"></result>
  11. <result column="d_name" property="dept.deptName"></result>
  12. </resultMap>
  13. <select id="selectEmpWithDept" resultMap="BaseResultMap">
  14. SELECT
  15. e.id,
  16. e.user_name,
  17. e.dept_id,
  18. d.id as d_id,
  19. d.dept_name as d_name
  20. FROM
  21. emp e
  22. INNER JOIN dept d ON e.dept_id = d.id
  23. </select>
  24. </mapper>
  1. public class SqlTest {
  2. SqlSessionFactory sqlSessionFactory ;
  3. @Before
  4. public void init() throws IOException {
  5. String resource = "mybatis-config.xml";
  6. InputStream inputStream = Resources.getResourceAsStream(resource);
  7. sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  8. }
  9. @Test
  10. public void test01(){
  11. SqlSession sqlSession = sqlSessionFactory.openSession();
  12. EmpDeptMapper mapper = sqlSession.getMapper(EmpDeptMapper.class);
  13. List<EmpDept> empDeptList = mapper.selectEmpWithDept();
  14. System.out.println(empDeptList.size());
  15. System.out.println(empDeptList);
  16. sqlSession.commit();
  17. sqlSession.close();
  18. }
  19. }

方式二:association

1.使用association的第一种写法:指定javaType

  association中的property指定多对一种的一

                           javaType指定类型

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.tulingxueyuan.mapper.EmpDeptMapper">
  4. <resultMap id="BaseResultMap" type="com.tulingxueyuan.pojo.EmpDept">
  5. <id column="id" jdbcType="INTEGER" property="id" />
  6. <result column="user_name" jdbcType="VARCHAR" property="userName" />
  7. <result column="create_date" jdbcType="TIMESTAMP" property="createDate" />
  8. <result column="dept_id" jdbcType="INTEGER" property="deptId" />
  9. <!--方式一:对象属性名.属性-->
  10. <!-- <result column="d_id" property="dept.id"></result>-->
  11. <!-- <result column="d_dept_name" property="dept.deptName"></result>-->
  12. <!--方式二-1:association-->
  13. <association property="dept" javaType="com.tulingxueyuan.pojo.Dept">
  14. <result column="d_id" property="id"></result>
  15. <result column="d_dept_name" property="deptName"></result>
  16. </association>
  17. </resultMap>
  18. <select id="selectEmpWithDept" resultMap="BaseResultMap">
  19. SELECT
  20. e.id,
  21. e.user_name,
  22. e.create_date,
  23. e.dept_id,
  24. d.id as d_id,
  25. d.dept_name as d_dept_name
  26. FROM
  27. emp e
  28. INNER JOIN dept d ON e.dept_id = d.id
  29. </select>
  30. </mapper>

2.使用association的第二种写法:指定resultMap

   如果不想在association中再写result这种列和属性字段的映射的话,那么就用resultMap来指定一个已经写好的resultMap即可,达到重用的目的。

ps:这时候如果有命名重复的问题,比如emp中有id,dept种也有id,可以用as重命名查询出来的列,之后用columnPrefix="d_"来去掉这个前缀。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.tulingxueyuan.mapper.EmpDeptMapper">
  4. <resultMap id="BaseResultMap" type="com.tulingxueyuan.pojo.EmpDept">
  5. <id column="id" jdbcType="INTEGER" property="id" />
  6. <result column="user_name" jdbcType="VARCHAR" property="userName" />
  7. <result column="create_date" jdbcType="TIMESTAMP" property="createDate" />
  8. <result column="dept_id" jdbcType="INTEGER" property="deptId" />
  9. <!--方式一:对象属性名.属性-->
  10. <!-- <result column="d_id" property="dept.id"></result>-->
  11. <!-- <result column="d_dept_name" property="dept.deptName"></result>-->
  12. <!--方式二-1:association-->
  13. <!-- <association property="dept" javaType="com.tulingxueyuan.pojo.Dept">-->
  14. <!-- <result column="d_id" property="id"></result>-->
  15. <!-- <result column="d_dept_name" property="deptName"></result>-->
  16. <!-- </association>-->
  17. <!--方式二-2:association-->
  18. <association property="dept" columnPrefix="d_"
  19. resultMap="com.tulingxueyuan.mapper.DeptMapper.BaseResultMap">
  20. </association>
  21. </resultMap>
  22. <select id="selectEmpWithDept" resultMap="BaseResultMap">
  23. SELECT
  24. e.id,
  25. e.user_name,
  26. e.create_date,
  27. e.dept_id,
  28. d.id as d_id,
  29. d.dept_name as d_dept_name
  30. FROM
  31. emp e
  32. INNER JOIN dept d ON e.dept_id = d.id
  33. </select>
  34. </mapper>
  1. public class Dept {
  2. private Integer id;
  3. private String deptName;
  4. //省略getter和setter方法
  5. }

那么使用属性名.属性的方式和使用association的两种方式有什么不同呢?

       使用association会强制的使我们的查询结果进行多对一,因为mybatis底层是将主键和查出来的对象放入一个类似hashmap的数据结构中,所以没有查emp的id会造成association失效。association是凭借id来组织多对一的结果。这是非常容易忽视的问题。

使用属性名.属性的方式就不会帮助我们多对一,我们查出来多少条数据就是多少条数据。

2.针对一对多的情况:

   其实这种情况使我们工作中应用比较多的场景。

   比如:级联查询的时候

  这里其实用到了collection,这种情况不像是association还可以用属性名.属性代替一下,这个collection只能就自己这么用,哈哈~

重点 代码:

  1. package com.tulingxueyuan.pojo;
  2. import java.util.List;
  3. public class DeptEmp {
  4. private Integer id;
  5. private String deptName;
  6. private List<Emp> emps ;
  7. public Integer getId() {
  8. return id;
  9. }
  10. public void setId(Integer id) {
  11. this.id = id;
  12. }
  13. public String getDeptName() {
  14. return deptName;
  15. }
  16. public void setDeptName(String deptName) {
  17. this.deptName = deptName;
  18. }
  19. public List<Emp> getEmps() {
  20. return emps;
  21. }
  22. public void setEmps(List<Emp> emps) {
  23. this.emps = emps;
  24. }
  25. @Override
  26. public String toString() {
  27. return "DeptEmp{" +
  28. "id=" + id +
  29. ", deptName='" + deptName + '\'' +
  30. ", emps=" + emps +
  31. '}';
  32. }
  33. }

  

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.tulingxueyuan.mapper.DeptEmpMapper">
  4. <resultMap id="BaseResultMap" type="com.tulingxueyuan.pojo.DeptEmp">
  5. <id column="id" jdbcType="INTEGER" property="id" />
  6. <result column="dept_name" jdbcType="VARCHAR" property="deptName" />
  7. <collection property="emps" columnPrefix="e_"
  8. resultMap="com.tulingxueyuan.mapper.EmpMapper.BaseResultMap"></collection>
  9. </resultMap>
  10. <select id="selectDeptWithEmp" resultMap="BaseResultMap">
  11. SELECT
  12. d.id,
  13. d.dept_name,
  14. e.id as e_id,
  15. e.user_name as e_user_name,
  16. e.create_date as e_create_date,
  17. e.dept_id as e_dept_id
  18. FROM
  19. dept d
  20. INNER JOIN emp e ON d.id = e.dept_id
  21. </select>
  22. </mapper>
  1. <mapper namespace="com.tulingxueyuan.mapper.EmpMapper">
  2. <resultMap id="BaseResultMap" type="com.tulingxueyuan.pojo.Emp">
  3. <id column="id" jdbcType="INTEGER" property="id" />
  4. <result column="user_name" jdbcType="VARCHAR" property="userName" />
  5. <result column="create_date" jdbcType="TIMESTAMP" property="createDate" />
  6. <result column="dept_id" jdbcType="INTEGER" property="deptId" />
  7. </resultMap>
  8. ​​​​​​​</mapper>
  1. @Test
  2. public void testCollection(){
  3. SqlSession sqlSession = sqlSessionFactory.openSession();
  4. DeptEmpMapper mapper = sqlSession.getMapper(DeptEmpMapper.class);
  5. List<DeptEmp> deptEmpList = mapper.selectDeptWithEmp();
  6. System.out.println(deptEmpList.size());
  7. System.out.println(deptEmpList);
  8. sqlSession.commit();
  9. sqlSession.close();
  10. }

其实collection标签的用法和association标签的属性很多用法是相同的。

ps:

记录mapper.xml中的关于不等于的写法:

重点看注释部分

  1. <select id="selectProductCategoryWithChildren" resultMap="selectProductCategoryWithChildrenMap">
  2. SELECT
  3. t1.id,
  4. t1.`name`,
  5. t2.id AS son_id,
  6. t2.`name` AS son_name
  7. FROM
  8. pms_product_category t1
  9. INNER JOIN pms_product_category t2 ON t1.id = t2.parent_id
  10. and t1.parent_id=0
  11. and t2.parent_id<![CDATA[<>]]>0 <!--或者使用尖括号 但是尖括号会报错 可以使用&lt;&gt; 或者使用<![CDATA[<>]]> 还可以直接使用!= -->
  12. ORDER BY t1.id
  13. </select>

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/624984
推荐阅读
相关标签
  

闽ICP备14008679号