zoukankan      html  css  js  c++  java
  • MyBatis的对象关系映射---多对一关系★★★★★

    在实际开发中,一个业务可能涉及到多个数据表的查询,那么多表查询就涉及连接查询(等值连接), 等值连接 表与表之间有一个外键关键,但是程序中最终获取的表封装的对象, 对象与对象之间是没有外键关系的,对象和对象之间只有依赖关系;

     对象之间关系主要是四种:

    一对一 关系
    一个人对应身份证id,一个QQ号对应一个QQ空间

    一对多 关系

    一个部门对应多个员工

    多对一 关系

    多个员工对应一个部门

    多对多 关系

    多个学生对应多个老师,多个学生对应多个课程

    什么关系应该从哪个对象作为中心点来看

    一对多, 以one方作为中心点

    MyBatis框架支持多表查询封装对象之间关系

    <collection> 一对多查询 <association>多对一和一对一查询

    mapper表:

     1 package top.abcdit.mybatis.mapper;
     2 
     3 import top.abcdit.mybatis.pojo.Employee;
     4 
     5 public interface Many2OneMapper {
     6     
     7     /**
     8      * 查询指定id员工的所有信息(包括部门信息)
     9      * @param id 员工id
    10      * @return 员工对象
    11      */
    12     Employee selectByPrimaryKey(Integer id);
    13     
    14 }

    Many2OneMapper.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">
    
    <!--  映射标签,内部就编写具体的映射sql语句
        namespace :命名空间,值 必须是 对应接口的全限定名 = 包名 +简单类名
            top.abcdit.mybatis.mapper.Many2OneMapper
     -->
    <mapper namespace="top.abcdit.mybatis.mapper.Many2OneMapper">
        
        <select id="selectByPrimaryKey" resultType="top.abcdit.mybatis.pojo.Employee" parameterType="int">
            select * from employee where id = #{id}
        </select>
        
    </mapper>

    mybatis-config.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
      PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-config.dtd">
      
      <!-- mybatis配置标签 内部就是mybatis具体配置 -->
    <configuration>
        <!-- mybatis的配置环境 
            default:默认使用环境,值就是下面的环境id
        -->
        <settings>
        <!-- 开启二级缓存 -->
            <setting name="cacheEnabled" value="true"/>
        </settings>
            
      <environments default="mysql">
          <!-- 具体某一个环境 -->
        <environment id="mysql">
        <!-- MyBatis操作需要事务管理,默认使用JDBC
                JDBC:mybatis的别名
         -->
          <transactionManager type="JDBC"/>
          <!--配置mybatis的数据源(连接池)
          POOLED(别名) :mybatis内置的一个连接池
              后期和spring集成使用,druid阿里巴巴连接池
     -->
          <dataSource type="POOLED">
              <!-- 数据库驱动 -->
            <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
            <!-- url地址 -->
            <property name="url" value="jdbc:mysql://localhost:3306/gzmybatis1?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=GMT"/>
            <!-- 数据库的账号 -->
            <property name="username" value="root"/>
            <!-- 数据库的密码 -->
            <property name="password" value="myroot"/>
          </dataSource>
        </environment>
      </environments>
      
      <!-- 配置映射文件 -->
      <mappers>
              <!-- 读取单个映射文件 -->
        <mapper resource="top/abcdit/mybatis/mapper/Many2OneMapper.xml"/>
      </mappers>
    </configuration>

    员工和部门表:

     1 package top.abcdit.mybatis.pojo;
     2 
     3 public class Department {
     4     private Integer id;
     5     private String name;
     6     public Integer getId() {
     7         return id;
     8     }
     9     public void setId(Integer id) {
    10         this.id = id;
    11     }
    12     public String getName() {
    13         return name;
    14     }
    15     public void setName(String name) {
    16         this.name = name;
    17     }
    18     public Department(Integer id, String name) {
    19         super();
    20         this.id = id;
    21         this.name = name;
    22     }
    23     public Department() {
    24         super();
    25         // TODO Auto-generated constructor stub
    26     }
    27     @Override
    28     public String toString() {
    29         return "Department [id=" + id + ", name=" + name + "]";
    30     }
    31     
    32 }
     1 package top.abcdit.mybatis.pojo;
     2 
     3 public class Employee {
     4     
     5     private Integer id;
     6     private String name;
     7     //以员工为中心,多个与员工对应一个部门:多对一关系
     8     private Department dept;
     9     public Integer getId() {
    10         return id;
    11     }
    12     public void setId(Integer id) {
    13         this.id = id;
    14     }
    15     public String getName() {
    16         return name;
    17     }
    18     public void setName(String name) {
    19         this.name = name;
    20     }
    21     public Department getDept() {
    22         return dept;
    23     }
    24     public void setDept(Department dept) {
    25         this.dept = dept;
    26     }
    27     public Employee(Integer id, String name, Department dept) {
    28         super();
    29         this.id = id;
    30         this.name = name;
    31         this.dept = dept;
    32     }
    33     public Employee() {
    34         super();
    35     }
    36     @Override
    37     public String toString() {
    38         return "Employee [id=" + id + ", name=" + name + ", dept=" + dept + "]";
    39     }
    40     
    41     
    42     
    43 }

    测试表:

     1 package top.abcdit.mybatis.test;
     2 
     3 import static org.junit.Assert.*;
     4 
     5 import org.apache.ibatis.session.SqlSession;
     6 import org.junit.Test;
     7 import top.abcdit.mybatis.mapper.Many2OneMapper;
     8 import top.abcdit.mybatis.pojo.Employee;
     9 import top.abcdit.mybatis.util.MyBatisUtil;
    10 
    11 public class Many2OneMapperTest {
    12 
    13     @Test
    14     public void testselectByPrimaryKey() {
    15         
    16         SqlSession session = MyBatisUtil.openSession();
    17         
    18         Many2OneMapper mapper = session.getMapper(Many2OneMapper.class);
    19         
    20         Employee emp = mapper.selectByPrimaryKey(2);
    21         System.out.println(emp);
    22     }
    23 
    24 
    25 }

    输出结果:

    DEBUG [main] - ==>  Preparing: select * from employee where id = ? 
    DEBUG [main] - ==> Parameters: 2(Integer)
    TRACE [main] - <==    Columns: id, name, dept_id
    TRACE [main] - <==        Row: 2, 虚竹, 2
    DEBUG [main] - <==      Total: 1
    Employee [id=2, name=虚竹, dept=null]

    可以看到,采用自动映射,只得到部门编号,无法获取部门名称;

    所以采用手动映射:

     把Many2OneMapper.xml:配置文件修改为:

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE mapper
     3   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     4   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     5 
     6 <!--  映射标签,内部就编写具体的映射sql语句
     7     namespace :命名空间,值 必须是 对应接口的全限定名 = 包名 +简单类名
     8         top.abcdit.mybatis.mapper.Many2OneMapper
     9  -->
    10 <mapper namespace="top.abcdit.mybatis.mapper.Many2OneMapper">
    11     
    12     <select id="selectByPrimaryKey" resultMap="emp_map" parameterType="int">
    13         select * from employee where id = #{id}
    14     </select>
    15     
    16     <!-- 手动映射 -->
    17       <resultMap type="top.abcdit.mybatis.pojo.Employee" id="emp_map">
    18           <id column="id" property="id"/> 
    19           <result column="name" property="name"/>
    20           
    21           <!-- 
    22               问题: private Department dept; 部门对象如何映射?
    23                
    24                解决方案:使用 联合查询标签 
    25                 <association property="" column="" select=""/>
    26                  property :需要映射的pojo对象的属性此时就是  dept
    27                 column :已知对应dept对象的外键列
    28                 select :需要去查询的功能id -->
    29           
    30           <association property="dept" column="dept_id" select="findByDeptId"/>
    31       </resultMap>
    32       
    33     <!-- 联合查询的功能 -->
    34       <!-- 根据部门的id查询出对应的部门对象-->
    35     
    36     <select id="findByDeptId" parameterType="int" resultType="top.abcdit.mybatis.pojo.Department">
    37         select * from department where id = #{dept_id}
    38     </select>
    39     
    40 </mapper>

    测试结果:

    DEBUG [main] - ==>  Preparing: select * from employee where id = ? 
    DEBUG [main] - ==> Parameters: 2(Integer)
    TRACE [main] - <==    Columns: id, name, dept_id
    TRACE [main] - <==        Row: 2, 虚竹, 2
    DEBUG [main] - ====>  Preparing: select * from department where id = ? 
    DEBUG [main] - ====> Parameters: 2(Integer)
    TRACE [main] - <====    Columns: id, name
    TRACE [main] - <====        Row: 2, 研发部
    DEBUG [main] - <====      Total: 1
    DEBUG [main] - <==      Total: 1
    Employee [id=2, name=虚竹, dept=Department [id=2, name=研发部]]
  • 相关阅读:
    leetcode--Populating Next Right Pointers in Each Node II
    leetcode—Populating Next Right Pointers in Each Node
    Pascal's Triangle II
    leetcode—pascal triangle
    leetcode—triangle
    October 23rd, 2017 Week 43rd Monday
    October 22nd, 2017 Week 43rd Sunday
    October 21st 2017 Week 42nd Saturday
    October 20th 2017 Week 42nd Friday
    October 19th 2017 Week 42nd Thursday
  • 原文地址:https://www.cnblogs.com/abcdjava/p/11191796.html
Copyright © 2011-2022 走看看