浅谈MyBatis 之 高级映射/关联查询(四)

来源:互联网 发布:《最强淘宝系统》 编辑:程序博客网 时间:2024/05/18 18:15

MyBatis

高级映射/关联查询:

  • 一对一/多对一
  • 一对多
  • 多对多

主要使用的是resultMapcollection属性 和 association属性的使用


association

association:用于映射关联查询到单个对象的信息,将关联查询信息映射到一个pojo对象中,多用于一对一/多对一的场景。

collection

collection:对关联查询到的多条记录映射到集合中,一般就是将关联查询信息映射到一个list集合中,用于一对多/多对多的场景。


关联查询

一个简单的例子,部门和员工的映射

部门:Dept.java

public class Dept {    private Integer id ; // 部门编号    private String name ; // 部门名称    private String address ; // 部门地址    // 部门里的员工    private List<Employee> employees ;

数据库:

create table DEMO_MAWEI_DEPT(  D_ID      NUMBER not null,  D_NAME    VARCHAR2(50) not null,  D_ADDRESS VARCHAR2(100))

数据:
这里写图片描述


员工:Employee.java

public class Employee {    private int id ; // 员工号    private String name; // 员工姓名    private Dept dept ; // 所在部门    private String address ; // 家庭地址    // 所拥有的电脑    private List<Computer> computers ;

数据库:

create table DEMO_MAWEI_EMPLOYEE(  E_ID      NUMBER not null,  E_NAME    VARCHAR2(50) not null,  D_ID      NUMBER not null,  E_ADDRESS VARCHAR2(100))

数据:
这里写图片描述


电脑:Computer.java

public class Computer {    private Integer id ; // 电脑编号    private String name ; // 电脑名称    private Double money ; // 电脑价值    // 使用者    private Employee employee;

数据库:

create table DEMO_MAWEI_COMPUTER(  C_ID    NUMBER not null,  C_NAME  VARCHAR2(50),  C_MONEY NUMBER(10,2),  E_ID    NUMBER)

数据:
这里写图片描述


其中有一些setting和getting没有写,可以自行补上,及MAVEN配置和mybatis的配置可以在前文中看见。
浅谈MyBatis 之 入门(一)


一对一/多对一

就以:员工和部门之间的映射,一个员工对应一个部门(多个员工对应一个部门)

Employee.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.wm.mybatis.dao.IEmployeeMapperDao">    <resultMap type="Employee" id="employeeMap">        <id property="id" column="e_id"/>        <result property="name" column="e_name"/>        <result property="address" column="e_address"/>        <!-- 一对一/多对一:            association:用于映射关联查询单个对象的信息            property属性: 是Employee类中的属性对应            resultMap属性: 是 可以对应Employee类中的属性Dept类映射文件中的一个结果集映射                  命名空间+resultMap的id         -->        <association property="dept" resultMap="com.wm.mybatis.dao.IDeptMapperDao.resultDept" />    </resultMap>    <!-- 通过id获取员工信息 -->    <select id="getEmployeeById" parameterType="int" resultMap="employeeMap">        <![CDATA[            select *            from  base_55demo.demo_mawei_employee t inner join                 base_55demo.demo_mawei_dept d            on d.d_id = t.d_id            and t.e_id = #{id}        ]]>    </select></mapper>

其中resultMap :association:用于映射关联查询单个对象的信息

<association property="dept" resultMap="com.wm.mybatis.dao.IDeptMapperDao.resultDept" />

它是关联的一个已经存在的一个resultMap。=命名空间+resultMap的ID。

也可以有另一种写法:

    <!-- 另一种写法 -->    <resultMap type="Employee" id="employeeMap2">        <id property="id" column="e_id"/>        <result property="name" column="e_name"/>        <result property="address" column="e_address"/>        <association property="dept" javaType="Dept" >            <id property="id" column="d_id" />            <result property="name" column="d_name"  />            <result property="address" column="d_address" />        </association>    </resultMap>

测试:

public class EmployeeMapperDaoImpl implements IEmployeeMapperDao{    @Override    public Employee getEmployeeById(int id) {        Employee employee = null ;        try {            SqlSession session = SessionManagerUtil.getSession();            employee = (Employee)session.selectOne(IEmployeeMapperDao.class.getName()+".getEmployeeById", id);        } catch (Exception e) {            e.printStackTrace();        } finally {            SessionManagerUtil.closeSession();        }        return employee;    }}

结果:

public class TestEmployeeMapper {    @Test    public void getEmployeeById(){        EmployeeMapperDaoImpl dao = new EmployeeMapperDaoImpl();        Employee employee = dao.getEmployeeById(1001);        System.out.println(employee);    }}

这里写图片描述


一对多

部门与员工的映射:一个部门中有多个员工。

Dept.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.wm.mybatis.dao.IDeptMapperDao">    <resultMap type="Dept" id="resultDeptMap">        <result property="id" column="d_id" />        <result property="name" column="d_name" />        <result property="address" column="d_address" />        <!-- 一对多 List 列表             collection:对关联查询到的多条记录映射到集合中            property:employees为Dept类中的对应的属性        -->        <collection property="employees" ofType="com.wm.mybatis.POJO.Employee" column="d_id" >            <id property="id" column="e_id" javaType="int" jdbcType="INTEGER"/>            <result property="name" column="e_name" javaType="string" jdbcType="VARCHAR"/>            <result property="address" column="e_address" javaType="string" jdbcType="VARCHAR"/>            <result property="d_id" column="d_id" javaType="int" jdbcType="INTEGER"/>        </collection>    </resultMap>        <!-- 最基本的Dept结果集映射 -->    <resultMap type="Dept" id="resultDept">        <id property="id" column="d_id" />        <result property="name" column="d_name" />        <result property="address" column="d_address" />    </resultMap>    <select id="findDeptById" parameterType="int" resultMap="resultDeptMap">        <![CDATA[            select d.*,e.*             from demo_mawei_dept d,                 demo_mawei_employee e             where d.d_id = e.d_id             and d.d_id = #{id}        ]]>    </select></mapper>

其中resultMap :collection:对关联查询到的多条记录映射到list集合中。

其实其中collection可以简写成一个已有的映射结果集。

    <!-- 另一种写法 -->    <resultMap type="Dept" id="resultDeptMap2">        <id property="id" column="d_id"/>        <result property="name" column="d_name"/>        <result property="address" column="d_address"/>        <!--             property:对应的Dept类中的属性            resultMap:对应的Employee的一个最简单的一个结果集映射 = 命名空间+resultMap的ID         -->        <collection property="employees" resultMap="com.wm.mybatis.dao.IEmployeeMapperDao.basicEmployee" />    </resultMap>

而Employee.xml中:对应的最基本的结果集映射:
(com.wm.mybatis.dao.IEmployeeMapperDao.basicEmployee)

    <!-- 最基本的Employee结果集 -->    <resultMap type="Employee" id="basicEmployee">        <id property="id" column="e_id"/>        <result property="name" column="e_name"/>        <result property="address" column="e_address"/>    </resultMap>

测试:

public class DeptMapperDaoImpl implements IDeptMapperDao{    @Override    public Dept findDeptById(int id) {        Dept dept = null ;        try {            SqlSession session = SessionManagerUtil.getSession();            dept = session.selectOne(IDeptMapperDao.class.getName()+".findDeptById", id) ;        } catch (Exception e) {            e.printStackTrace();        } finally{            SessionManagerUtil.closeSession();        }        return dept;    }}

结果:

public class TestDeptMapper {    @Test    public void findDeptById(){        IDeptMapperDao dao = new DeptMapperDaoImpl();        Dept dept = dao.findDeptById(1);        System.out.println(dept);    }}

这里写图片描述


多对多

就以:部门里有多个员工,每一个员工又有多台电脑。

Dept.xml

    <select id="getDeptByIdWithComputer" parameterType="int" resultMap="deptMore2More2">        <![CDATA[             select *                 from base_55demo.demo_mawei_dept d,                     base_55demo.demo_mawei_employee e,                     base_55demo.demo_mawei_computer c            where d.d_id = e.d_id            and e.e_id = c.e_id            and d.d_id = #{id}        ]]>    </select>    <!-- 多对多 -->    <resultMap type="Dept" id="deptMore2More2">        <id property="id" column="d_id"/>        <result property="name" column="d_name"/>        <result property="address" column="d_address"/>        <!-- 部门 与 员工   property:Dept类的属性   ofType:对应的类型(配置了别名的) -->        <collection property="employees" ofType="Employee">            <id property="id" column="e_id"/>            <result property="name" column="e_name"/>            <result property="address" column="e_address"/>            <!-- 员工 与 电脑  property:Computer类的属性   ofType:对应的类型(配置了别名的)-->            <collection property="computers" ofType="Computer">                <id property="id" column="c_id"/>                <result property="name" column="c_name"/>                <result property="money" column="c_money"/>            </collection>        </collection>    </resultMap>

其中:resultMap采用了嵌套 collection 实现的。

但是也可以引用已有的结果集:

resultMap 简化:

    <!-- 另一种写法 -->    <resultMap type="Dept" id="deptMore2More">        <id property="id" column="d_id"/>        <result property="name" column="d_name"/>        <result property="address" column="d_address"/>        <!-- 已有的结果集映射 部门和员工的映射 -->        <collection property="employees" resultMap="com.wm.mybatis.dao.IEmployeeMapperDao.employeeWithComputer" />    </resultMap>

部门和员工的映射:
(com.wm.mybatis.dao.IEmployeeMapperDao.employeeWithComputer)

    <!-- 连带电脑拥有者 -->    <resultMap type="Employee" id="employeeWithComputer">        <id property="id" column="e_id"/>        <result property="name" column="e_name"/>        <result property="address" column="e_address"/>        <!-- 已有的结果集映射  员工 和 电脑的映射 -->        <collection property="computers" resultMap="com.wm.mybatis.dao.IComputerMapperDao.basicComputer" />    </resultMap>

员工 和 电脑的映射:
(com.wm.mybatis.dao.IComputerMapperDao.basicComputer)

Computer.xml:

<mapper namespace="com.wm.mybatis.dao.IComputerMapperDao">    <resultMap type="Computer" id="basicComputer">        <id property="id" column="c_id"/>        <result property="name" column="c_name"/>        <result property="money" column="c_money"/>    </resultMap></mapper>

测试:
DeptMapperDaoImpl.java

    @Override    public Dept getDeptByIdWithComputer(int id) {        Dept dept = null ;        try {            SqlSession session = SessionManagerUtil.getSession();            dept = session.selectOne(IDeptMapperDao.class.getName()+".getDeptByIdWithComputer", id) ;        } catch (Exception e) {            e.printStackTrace();        } finally{            SessionManagerUtil.closeSession();        }        return dept;    }

结果:

    @Test    public void getDeptByIdWithComputer(){        IDeptMapperDao dao = new DeptMapperDaoImpl();        Dept dept = dao.getDeptByIdWithComputer(19);        System.out.println(dept);    }

这里写图片描述


高级映射:关联查询基本上都是对 resultMap 的标签:collection 和 association 的一些嵌套使用。

1 0
原创粉丝点击