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=研发部]]
  • 相关阅读:
    线性分类器之感知机算法
    字符串包含判断
    王家林 云计算分布式大数据Hadoop实战高手之路从零开始 第二讲:全球最详细的从零起步搭建Hadoop单机和伪分布式开发环境图文教程
    王家林 第六讲Hadoop图文训练课程:使用HDFS命令行工具操作Hadoop分布式集群初体验
    王家林的“云计算分布式大数据Hadoop实战高手之路从零开始”的第五讲Hadoop图文训练课程:解决典型Hadoop分布式集群环境搭建问题
    王家林的 第三讲Hadoop图文训练课程:证明Hadoop工作的正确性和可靠性只需4步图文并茂的过程
    王家林 第四讲Hadoop图文训练课程:实战构建真正的Hadoop分布式集群环境
    麻雀GUIv1.0整理好咯,发个开源上来。
    body设置背景色异常
    safari浏览器placeholder垂直居中
  • 原文地址:https://www.cnblogs.com/abcdjava/p/11191796.html
Copyright © 2011-2022 走看看