4. MyBatis关联查询

作者: 飞扬code | 来源:发表于2019-03-29 06:08 被阅读0次

4.1、 创建数据库及表

在dept表基础上,再加入emp表
sql语句

create table emp(
    emp_id varchar(18) primary key,
    emp_name varchar(50),
    emp_sex char(1),
    dept_id int
);
insert into emp(emp_id,emp_name,emp_sex,dept_id) values('44152199507052110','张大',"男","1");
insert into emp(emp_id,emp_name,emp_sex,dept_id) values('44152199507052111','张一',"女","1");
insert into emp(emp_id,emp_name,emp_sex,dept_id) values('44152199507052112','张二',"男","1");
image.png

2 基于association查询(用于多对一或一对一)

image.png

4.1 创建实体类:Dept.java/Emp.java

除部门实体类,再创建emp实体类

package com.demo.entity;
public class Emp {
    private String empId;
    private String empName;
    private String empSex;
    private Dept dept;

   ...../*省略set、get方法*/

    @Override
    public String toString() {
         return "Emp [empId=" + empId + ", empName=" + empName + ", empSex="
                 + empSex + ", dept=" + dept + "]";
    }
}

4.2 配置DeptMapper.xml/EmpMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//[mybatis.org//DTD](http://mybatis.org//DTD) Mapper 3.0//EN"
"[http://mybatis.org/dtd/mybatis-3-mapper.dtd](http://mybatis.org/dtd/mybatis-3-mapper.dtd)">
<mapper namespace="com.demo.entity.DeptMapper">
    <!-- 表字段和对应实体属性命名一致时可以不配置 -->
    <resultMap id="deptResultMap" type="Dept">
         <id property="deptId" column="dept_id" />
         <result property="deptName" column="dept_name" />
         <result property="deptAddress" column="dept_address" />
    </resultMap>
</mapper>

EmpMapper.xml,配置多对一的关联

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//[mybatis.org//DTD](http://mybatis.org//DTD) Mapper 3.0//EN" "[http://mybatis.org/dtd/mybatis-3-mapper.dtd](http://mybatis.org/dtd/mybatis-3-mapper.dtd)">
<mapper namespace="com.demo.entity.EmpMapper">
    <!--resultMap用于查询,可以把查询后字段值封装到对应类的属性, type指定的是对应的实体类 -->
    <resultMap type="Emp" id="empResultMap">
    <!-- id用来配置表的主键与类的属性的映射关系 ,column指定的是表的字段名; property指定的是类的属性名-->
         <id column="emp_id" property="empId"/>
         <!-- result用来配置 普通字段与类的属性的映射关系 ,column指定的是表的字段名; property指定的是类的属性名-->
         <result column="emp_name" property="empName"/>
         <result column="emp_sex" property="empSex"/>
         <!--association用来配置对一的关联  -->
         <association property="dept" column="dept_id" resultMap="com.demo.entity.DeptMapper.deptResultMap"></association>
    </resultMap>
    <!-- 查询员工信息(包括所在的部门信息) -->
    <select id="selectEmpDeptList" parameterType="string" resultMap="empResultMap" >
    select e.*,d.* from emp e inner join dept d on e.dept_id = d.dept_id
    where e.emp_name = #{empName}
    </select>
</mapper>

4.3 配置文件config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//[mybatis.org//DTD](http://mybatis.org//DTD) Config 3.0//EN"
"[http://mybatis.org/dtd/mybatis-3-config.dtd](http://mybatis.org/dtd/mybatis-3-config.dtd)">
<configuration>
    <!-- 引用db.properties配置文件 -->
    <properties resource="db.properties"/>
    <!-- 通过别名简化对类的使用 -->
    <typeAliases>
             <typeAlias type="com.demo.entity.Dept" alias="Dept" />
             <typeAlias type="com.demo.entity.Emp" alias="Emp" />   
    </typeAliases>
    <!--environments指定数据源环境,default指的是使用哪个数据源  -->
    <environments default="development">
         <!--environment定义数据源的信息  -->
         <environment id="development">
             <!-- type="JDBC"表示事务由jdbc连接管理,type="MANAGED"表示事务由容器来管理 -->
             <transactionManager type="JDBC" />
             <!-- type="POOLED"表示使用连接池, type="UNPOOLED"表示不使用连接池 -->
            <dataSource type="POOLED">
                <!-- value属性值引用db.properties配置文件中配置的值 -->
                <property name="driver" value="${driver}" />
                <property name="url" value="${url}" />
                <property name="username" value="${name}" />
                <property name="password" value="${password}" />
            </dataSource>
         </environment>
    </environments>

    <!-- 加入映射文件信息 -->
    <mappers>
         <mapper resource="com/demo/mapping/DeptMapper.xml" />
         <mapper resource="com/demo/mapping/EmpMapper.xml" />
    </mappers>  
</configuration>

4.4 编写EmpDaoImpl.java实现查询

package com.demo.dao.imp;**
import java.util.List;**
import org.apache.ibatis.session.SqlSession;**
import com.demo.entity.Emp;**
import com.demo.util.MyBatisUtil;**
public class EmpDaoImpl {**
    //根据员工姓名查询多个员工信息(包括员工所在部门信息)**
         public List<Emp> selectList(String empName){**
             List<Emp> emps =null;**
             try {
                 session = MyBatisUtil.getSession();
                 emps = session.selectList("com.demo.entity.EmpMapper.selectEmpDeptList",empName);
             } catch (Exception e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }finally{
                 try {
                      MyBatisUtil.closeSession();
                 } catch (Exception e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                 }
             }
             return emps;
         }
}

2.5 编写测试类

EmplTest.java

package com.demo.test;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.demo.dao.imp.EmpDaoImpl;
import com.demo.entity.Emp;
public class TestEmpDaoImpl {
    private static EmpDaoImpl empDaoImpl;
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
         empDaoImpl = new EmpDaoImpl();
    }
    @AfterClass
    public static void tearDownAfterClass() throws Exception {
         empDaoImpl = null;
    }
    @Test
    public void testSelectList() {
         List<Emp> emps = empDaoImpl.selectList("张大");
         for (Emp emp : emps) {
             System.out.println("员工信息:"+emp);
         }
    }
}

测试效果


image.png

4.3 基于collection查询(用于一对多或多对多)

4.3.1 编写 Dept.java实体类

package com.demo.entity;
import java.util.List;
public class Dept {
    private Integer deptId; //部门编号
    private String deptName;//部门名称
    private String deptAddress;//部门地址
    private List<Emp> emps;//部门员工

...//set、get

    @Override
    public String toString() {
         return "Dept [deptId=" + deptId + ", deptName=" + deptName
                 + ", deptAddress=" + deptAddress + ", emps=" + emps +"]";
    }   
}

4.3.2 编写Emp.java实体类

package com.demo.entity;
public class Emp {
    private String empId;
    private String empName;
    private String empSex;
    private Dept dept;

...//set、get

    @Override
    public String toString() {
         return "Emp [empId=" + empId + ", empName=" + empName + ", empSex="
                 + empSex + ", dept=" + dept + "]";
    }
}

4.3.3 修改DeptMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//[mybatis.org//DTD](http://mybatis.org//DTD) Mapper 3.0//EN"
"[http://mybatis.org/dtd/mybatis-3-mapper.dtd](http://mybatis.org/dtd/mybatis-3-mapper.dtd)">
<mapper namespace="com.demo.entity.DeptMapper">
    <!-- 表字段和对应实体属性命名一致时可以不配置 -->
    <resultMap id="deptResultMap" type="Dept">
         <id property="deptId" column="dept_id" />
         <result property="deptName" column="dept_name" />
         <result property="deptAddress" column="dept_address" />
         <!--collection用来配置对多的关联  -->
         <collection property="emps" resultMap="com.demo.entity.EmpMapper.empResultMap"></collection>
    </resultMap>
    <!-- 根据部门名称查询部门信息(包括部门员工信息) -->
    <select id="selectDeptEmpList" parameterType="string" resultMap="deptResultMap">
         select e.*,d.* from emp e inner join dept d on e.dept_id = d.dept_id
         where d.dept_name = #{deptName}
    </select>
</mapper>

4.3.4 EmpMapper.xml注释掉查询员工信息部分和一对一关联

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//[mybatis.org//DTD](http://mybatis.org//DTD) Mapper 3.0//EN" "[http://mybatis.org/dtd/mybatis-3-mapper.dtd](http://mybatis.org/dtd/mybatis-3-mapper.dtd)">
<mapper namespace="com.demo.entity.EmpMapper">
<!--resultMap用于查询,可以把查询后字段值封装到对应类的属性, type指定的是对应的实体类 -->
    <resultMap type="Emp" id="empResultMap">
         <!-- id用来配置表的主键与类的属性的映射关系 ,column指定的是表的字段名; property指定的是类的属性名-->
         <id column="emp_id" property="empId"/>
         <!-- result用来配置 普通字段与类的属性的映射关系 ,column指定的是表的字段名; property指定的是类的属性名-->
         <result column="emp_name" property="empName"/>
         <result column="emp_sex" property="empSex"/>
         <!--association用来配置对一的关联  -->
         <!-- <association property="dept" column="dept_id" resultMap="com.demo.entity.DeptMapper.deptResultMap"></association>-->
    </resultMap>

    <!-- 查询员工信息(包括所在的部门信息) -->
    <!-- <select id="selectEmpDeptList" parameterType="string" resultMap="empResultMap" >
    select e.*,d.* from emp e inner join dept d on e.dept_id = d.dept_id
    where e.emp_name = #{empName}
    </select> -->
</mapper>

4.3.5 DeptDaoImpl.java修改

package com.demo.dao.imp;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.demo.entity.Dept;
import com.demo.util.MyBatisUtil;
public class DeptDaoImpl {
    SqlSession session;
    //根据员工姓名查询多个员工信息(包括员工所在部门信息)
         public List<Dept> selectList(String deptName){**
             List<Dept> depts =null;
             try {
                 session = MyBatisUtil.getSession();
                 depts = session.selectList("com.demo.entity.DeptMapper.selectDeptEmpList",deptName);
             } catch (Exception e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }finally{
                 try {
                      MyBatisUtil.closeSession();
                 } catch (Exception e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                 }
             }
             return depts;
         }
}

4.3.6 测试类TestDeptDaoImpl.java

package com.demo.test;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.demo.dao.imp.DeptDaoImpl;
import com.demo.entity.Dept;
public class TestDeptDaoImpl {
    private static DeptDaoImpl deptDaoImpl;
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
         deptDaoImpl = new DeptDaoImpl();
    }
    @AfterClass
    public static void tearDownAfterClass() throws Exception {
         deptDaoImpl = null;
    }
    @Test
    public void testSelectList() {
         List<Dept> depts = deptDaoImpl.selectList("研发部一部");
         for (Dept dept : depts) {
             System.out.println("部门信息:"+dept);
         }
    }
}

4.4 多对多双向关联查询(多对多)

查部门包括员工


image.png

查员工包括部门


image.png image.png

4.4.1 编写实体类:Dept.java/Emp.java(略)

4.4.2 编写DeptMapper.xml/EmpMapper.xml文件

DeptMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//[mybatis.org//DTD](http://mybatis.org//DTD) Mapper 3.0//EN" "[http://mybatis.org/dtd/mybatis-3-mapper.dtd](http://mybatis.org/dtd/mybatis-3-mapper.dtd)">
<mapper namespace="com.demo.entity.DeptMapper">
    <!--resultMap用于查询,可以把查询后字段值封装到对应类的属性, type指定的是对应的实体类 -->
    <resultMap type="Dept" id="deptResultMap">
         <!-- id用来配置表的主键与类的属性的映射关系 ,column指定的是表的字段名; property指定的是类的属性名-->
         <id column="dept_id" property="deptId"/>
         <!-- result用来配置 普通字段与类的属性的映射关系 ,column指定的是表的字段名; property指定的是类的属性名-->
         <result column="dept_name" property="deptName"/>
         <result column="dept_address" property="deptAddress"/>
    </resultMap>
    <resultMap type="dept" id="deptExtResultMap" extends="deptResultMap">
         <!--collection用来配置对多的关联  -->
         <collection property="emps" resultMap="com.demo.entity.EmpMapper.empResultMap"></collection>
    </resultMap>
    <!-- 根据部门名称查询部门信息(包括部门员工信息) -->
    <select id="selectDeptEmpList" parameterType="string" resultMap="deptExtResultMap">
         select e.*,d.* from emp e inner join dept d on e.dept_id = d.dept_id
         where d.dept_name = #{deptName}
    </select>
</mapper>

EmpMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//[mybatis.org//DTD](http://mybatis.org//DTD) Mapper 3.0//EN" "[http://mybatis.org/dtd/mybatis-3-mapper.dtd](http://mybatis.org/dtd/mybatis-3-mapper.dtd)">
<mapper namespace="com.demo.entity.EmpMapper">
    <!--resultMap用于查询,可以把查询后字段值封装到对应类的属性, type指定的是对应的实体类 -->
    <resultMap type="Emp" id="empResultMap">
         <!-- id用来配置表的主键与类的属性的映射关系 ,column指定的是表的字段名; property指定的是类的属性名-->
         <id column="emp_id" property="empId"/>
         <!-- result用来配置 普通字段与类的属性的映射关系 ,column指定的是表的字段名; property指定的是类的属性名-->
         <result column="emp_name" property="empName"/>
         <result column="emp_sex" property="empSex"/>
    </resultMap>
     <resultMap type="Emp" id="empExtResultMap" extends="empResultMap">
        <!--association用来配置对一的关联  -->
         <association property="dept" column="dept_id" resultMap="com.demo.entity.DeptMapper.deptResultMap"></association>
    </resultMap>

    <!-- 查询员工信息(包括所在的部门信息) -->
    <select id="selectEmpDeptList" parameterType="string" resultMap="empExtResultMap" >
    select e.*,d.* from emp e inner join dept d on e.dept_id = d.dept_id
    where e.emp_name = #{empName}
    </select>
</mapper>

4.4.3 编写数据操作类:DeptDaoImpl.java/EmpDaoImpl.java

DeptDaoImpl.java
package com.demo.dao.imp;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.demo.entity.Dept;
import com.demo.util.MyBatisUtil;
public class DeptDaoImpl {
    SqlSession session;
    //根据员工姓名查询多个员工信息(包括员工所在部门信息)
         public List<Dept> selectList(String deptName){
             List<Dept> depts =null;
             try {
                 session = MyBatisUtil.getSession();
                 depts = session.selectList("com.demo.entity.DeptMapper.selectDeptEmpList",deptName);
             } catch (Exception e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }finally{
                 try {
                      MyBatisUtil.closeSession();
                 } catch (Exception e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                 }
             }
             return depts;
         }
}

EmpDaoImpl.java

package com.demo.dao.imp;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.demo.entity.Emp;
import com.demo.util.MyBatisUtil;
public class EmpDaoImpl {
    SqlSession session;
    //根据员工姓名查询多个员工信息(包括员工所在部门信息)
        public List<Emp> selectList(String empName){
            List<Emp> emps =null;
            try {
                session = MyBatisUtil.getSession();
                emps = session.selectList("com.demo.entity.EmpMapper.selectEmpDeptList",empName);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                try {
                    MyBatisUtil.closeSession();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return emps;
        }
}

4.4.4 编写测试类:

TestDeptDaoImpl.java
package com.demo.test;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.demo.dao.imp.DeptDaoImpl;
import com.demo.entity.Dept;

public class TestDeptDaoImpl {
    private static DeptDaoImpl deptDaoImpl;
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        deptDaoImpl = new DeptDaoImpl();
    }
    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        deptDaoImpl = null;
    }
    //查询部门信息(包括员工信息)
    @Test
    public void testSelectList() {
        List<Dept> depts = deptDaoImpl.selectList("研发部一部");
        for (Dept dept : depts) {
            System.out.println("部门信息:"+dept);
        }
    }
}

测试效果:


image.png

TestEmpDaoImpl .java

package com.demo.test;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.demo.dao.imp.EmpDaoImpl;
import com.demo.entity.Emp;
public class TestEmpDaoImpl {
    private static EmpDaoImpl empDaoImpl;
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
         empDaoImpl = new EmpDaoImpl();
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
         empDaoImpl = null;
    }

    //查询员工信息(包括部门信息)
    @Test
    public void testSelectList() {
         List<Emp> emps = empDaoImpl.selectList("张大");
         for (Emp emp : emps) {
             System.out.println("员工信息:"+emp);
         }
    }
}

测试效果:


image.png

相关文章

  • 4. MyBatis关联查询

    4.1、 创建数据库及表 在dept表基础上,再加入emp表sql语句 2 基于association查询(用于...

  • MyBatis 最佳实践篇 3:关联查询懒加载

    MyBatis 中联合查询可分为关联查询和关联结果两种方式(具体查看 Mybatis 文档篇 3.5:Mapper...

  • 关于关联查询的处理

    mybatis关联查询配置有2种:关联嵌套结果,关联嵌套查询关联的查询过程中如果关联的表可能查到很多数据,应该考虑...

  • mybatis进阶2——关联查询

    关联查询代码参考mybatis-demo测试代码AssociationQueryTest.java 0.关联查询的...

  • Mybatis关联查询

    1. mysql中的LEFT JOIN 使用left join是以左表为主,即使右表没有数据,也会出来左表的所有数...

  • Mybatis | 关联查询

    使用Mybatis进行关联查询,之前发在我的CSDN博客中,现在搬到简书上来。 数据库关系图 如图是一个博客系统的...

  • MyBatis关联查询

    【目录】1 一对一2 一对多 在项目开始之前准备好数据库。数据库database: 1 一对一 相关代码:主配置文...

  • MyBatis学习:MyBatis中的延迟加载

    MyBatis中的延迟加载。 1. 什么是延迟加载 例子:如果查询订单并且关联查询用户信息。如果先查询订单信息...

  • InvalidDefinitionException: No s

    在使用springboot + mybatis实现多表关联查询时报以下错误:com.fasterxml.jacks...

  • mybatis笔记整理

    mybatis的基本用法及配置: 本文涉及知识点: 1、mybatis入门2、配置版CRUD3、关联查询(1:1&...

网友评论

    本文标题:4. MyBatis关联查询

    本文链接:https://www.haomeiwen.com/subject/frhkbqtx.html