MyBatis:MyBatis的输入映射和输出映射

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis:MyBatis的输入映射和输出映射相关的知识,希望对你有一定的参考价值。

文章目录

1.MyBatis的输入映射和输出映射

1.1.输入映射总结

当sql语句需要一个参数时

  1. 接口方法参数为一个基本数据类型;parameterType配置一个基本数据类型;

当sql语句需要多个参数时

  1. 接口方法参数为一个实体对象类型;parameterType配置一个实体对象类型;
  2. 接口方法参数为一个集合类型(List、Map);parameterType配置集合中元素的类型;

注意:当sql语句中需要判断一个基本数据类型的值是否为空时

  1. 值的类型必须为包装类。
  2. 即使是只传一个基本数据类型,也要使用实体对象传值。 因为:如果在parameterType中设置Integer类型,那么Mybatis会自动寻找get方法来获取对象属性值。因此会出现没有get方法异常。

1.2.输出映射总结

当sql语句中的字段名与实体对象中的属性名一致时,使用resultType

  1. 返回一条记录时,resultType可以配置成对象类型。
  2. 返回多条记录时,resultType也要配置成对象类型(表示集合中存储的对象)。
  3. 返回一条记录,且只有一列时,resultType可以配置成简单数据类型。

当sql语句中的字段名与实体对象中的属性名不一致时,使用resultMap

  1. resultMap中,显式的书写sql字段名与实体对象属性名的映射

1.3.resultMap的使用

当sql语句中的字段名与实体对象中的字段名不一致时,可以使用resultMap来显式的进行映射。

例如下面的案例:

<!--配置字段和实体对象属性的映射关系-->
<resultMap id="oneToOne" type="card">
    <id column="cid" property="id" />
    <result column="number" property="number" />
    <!--
        association:配置被包含对象的映射关系
        property:被包含对象的变量名
        javaType:被包含对象的数据类型
    -->
    <association property="p" javaType="person">
        <id column="pid" property="id" />
        <result column="name" property="name" />
        <result column="age" property="age" />
    </association>
</resultMap>

<select id="selectAll" resultMap="oneToOne">
    SELECT c.id cid,number,pid,NAME,age FROM card c,person p WHERE c.pid=p.id
</select>

调用

@Test
public void selectAll() throws Exception
    //1.加载核心配置文件
    InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
    //2.获取SqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    //3.通过工厂对象获取SqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    //4.获取OneToOneMapper接口的实现类对象
    OneToOneMapper mapper = sqlSession.getMapper(OneToOneMapper.class);
    //5.调用实现类的方法,接收结果
    List<Card> list = mapper.selectAll();
    //6.处理结果
    for (Card c : list) 
        System.out.println(c);
    
    //7.释放资源
    sqlSession.close();
    is.close();

注意:

resultMap属性说明:

  1. resultMap标签中的 id 属性:是此resultMap的唯一标识
  2. resultMap标签中的 type 属性:是此resultMap 映射的实体对象
  3. resultMap标签中的子标签id,用来配置主键的映射;子标签 result 用来配置其它字段的映射。
  4. 子标签id 和子标签 result 中的 property 属性,对应实体类中的属性column 属性对应sql语句中的字段

association表示配置单个对象的关联映射(多对一或一对一):

  1. association标签中的property:many的一方的实体类中,添加的属性名。
  2. association标签中的javaType:many的一方的实体类中,添加的属性类型。
  3. id标签和result标签中的property:one的一方的实体类中的属性名。
  4. id标签和result标签中的column:one的一方的,查询出来的字段名。

collection标签完成一对多,多对多映射。

  1. collection标签:将关联查询信息映射到一个list集合中。
  2. collection标签的ofType属性:表示该集合中的元素对象的类型。
  3. collection标签中的select属性:表示应用哪一个关联查询。
  4. collection标签中的column属性:表示应用关联查询的条件。

2. MyBatis的多表操作

2.1 多表模型介绍

之前学习的都是基于单表操作的,而实际开发中,随着业务难度的加深,肯定需要多表操作的。

  • 多表模型分类 一对一:在任意一方建立外键,关联对方的主键。
  • 一对多:在多的一方建立外键,关联一的一方的主键。
  • 多对多:借助中间表,中间表至少两个字段,分别关联两张表的主键。

2.2 多表模型一对一操作

  1. 一对一模型: 人和身份证,一个人只有一个身份证,人和身份证就属于一对一关系

  2. 代码实现

    • 步骤一: sql语句准备

      CREATE TABLE person(
      	id INT PRIMARY KEY AUTO_INCREMENT,
      	NAME VARCHAR(20),
      	age INT
      );
      INSERT INTO person VALUES (NULL,'张三',23);
      INSERT INTO person VALUES (NULL,'李四',24);
      INSERT INTO person VALUES (NULL,'王五',25);
      
      CREATE TABLE card(
      	id INT PRIMARY KEY AUTO_INCREMENT,
      	number VARCHAR(30),
      	pid INT,
      	CONSTRAINT cp_fk FOREIGN KEY (pid) REFERENCES person(id)
      );
      INSERT INTO card VALUES (NULL,'12345',1);
      INSERT INTO card VALUES (NULL,'23456',2);
      INSERT INTO card VALUES (NULL,'34567',3);
      
    • 步骤二:配置文件

      <?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.yyl.table01.OneToOneMapper">
          <!--配置字段和实体对象属性的映射关系-->
          <resultMap id="oneToOne" type="card">
              <id column="cid" property="id" />
              <result column="number" property="number" />
              <!--
                  association:配置被包含对象的映射关系
                  property:被包含对象的变量名
                  javaType:被包含对象的数据类型
              -->
              <association property="p" javaType="person">
                  <id column="pid" property="id" />
                  <result column="name" property="name" />
                  <result column="age" property="age" />
              </association>
          </resultMap>
      
          <select id="selectAll" resultMap="oneToOne">
              SELECT c.id cid,number,pid,NAME,age FROM card c,person p WHERE c.pid=p.id
          </select>
      </mapper>
      
    • 步骤三:测试类

       @Test
          public void selectAll() throws Exception
              //1.加载核心配置文件
              InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
      
              //2.获取SqlSession工厂对象
              SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
      
              //3.通过工厂对象获取SqlSession对象
              SqlSession sqlSession = sqlSessionFactory.openSession(true);
      
              //4.获取OneToOneMapper接口的实现类对象
              OneToOneMapper mapper = sqlSession.getMapper(OneToOneMapper.class);
      
              //5.调用实现类的方法,接收结果
              List<Card> list = mapper.selectAll();
      
              //6.处理结果
              for (Card c : list) 
                  System.out.println(c);
              
      
              //7.释放资源
              sqlSession.close();
              is.close();
          
      

    运行结果如下:
    3.一对一配置总结:

    <resultMap>:配置字段和对象属性的映射关系标签。
        id 属性:唯一标识
        type 属性:实体对象类型
    <id>:配置主键映射关系标签。
    <result>:配置非主键映射关系标签。
        column 属性:表中字段名称
        property 属性: 实体对象变量名称
    <association>:配置被包含对象的映射关系标签。
        property 属性:被包含对象的变量名
        javaType 属性:被包含对象的数据类型
    

2.3 多表模型一对多操作

  1. 一对多模型: 一对多模型:班级和学生,一个班级可以有多个学生。

  2. 代码实现

    • 步骤一: sql语句准备

      CREATE TABLE classes(
      	id INT PRIMARY KEY AUTO_INCREMENT,
      	NAME VARCHAR(20)
      );
      INSERT INTO classes VALUES (NULL,'极地一班');
      INSERT INTO classes VALUES (NULL,'基地二班');
      
      
      CREATE TABLE student(
      	id INT PRIMARY KEY AUTO_INCREMENT,
      	NAME VARCHAR(30),
      	age INT,
      	cid INT,
      	CONSTRAINT cs_fk FOREIGN KEY (cid) REFERENCES classes(id)
      );
      INSERT INTO student VALUES (NULL,'张三',23,1);
      INSERT INTO student VALUES (NULL,'李四',24,1);
      INSERT INTO student VALUES (NULL,'王五',25,2);
      INSERT INTO student VALUES (NULL,'赵六',26,2);
      
    • 步骤二:配置文件

      <mapper namespace="com.yyl.table02.OneToManyMapper">
          <resultMap id="oneToMany" type="classes">
              <id column="cid" property="id"/>
              <result column="cname" property="name"/>
      
              <!--
                  collection:配置被包含的集合对象映射关系
                  property:被包含对象的变量名
                  ofType:被包含对象的实际数据类型
              -->
              <collection property="students" ofType="student">
                  <id column="sid" property="id"/>
                  <result column="sname" property="name"/>
                  <result column="sage" property="age"/>
              </collection>
          </resultMap>
          <select id="selectAll" resultMap="oneToMany">
              SELECT c.id cid,c.name cname,s.id sid,s.name sname,s.age sage FROM classes c,student s WHERE c.id=s.cid
          </select>
      </mapper>
      
    • 步骤三:测试类

          @Test
          public void selectAll() throws Exception
              //1.加载核心配置文件
              InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
      
              //2.获取SqlSession工厂对象
              SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
      
              //3.通过工厂对象获取SqlSession对象
              SqlSession sqlSession = sqlSessionFactory.openSession(true);
      
              //4.获取OneToManyMapper接口的实现类对象
              OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);
      
              //5.调用实现类的方法,接收结果
              List<Classes> classes = mapper.selectAll();
      
              //6.处理结果
              for (Classes cls : classes) 
                  System.out.println(cls.getId() + "," + cls.getName());
                  List<Student> students = cls.getStudents();
                  for (Student student : students) 
                      System.out.println("\\t" + student);
                  
              
      
              //7.释放资源
              sqlSession.close();
              is.close();
          
      

    运行结果如下:

    3.一对多配置文件总结:

    <resultMap>:配置字段和对象属性的映射关系标签。
        id 属性:唯一标识
        type 属性:实体对象类型
    <id>:配置主键映射关系标签。
    <result>:配置非主键映射关系标签。
        column 属性:表中字段名称
        property 属性: 实体对象变量名称
    <collection>:配置被包含集合对象的映射关系标签。
        property 属性:被包含集合对象的变量名
        ofType 属性:集合中保存的对象数据类型
    

2.4 多表模型多对多操作

  1. 多对多模型:学生和课程,一个学生可以选择多门课程、一个课程也可以被多个学生所选择。

  2. 代码实现

    • 步骤一: sql语句准备

      CREATE TABLE course(
      	id INT PRIMARY KEY AUTO_INCREMENT,
      	NAME VARCHAR(20)
      );
      INSERT INTO course VALUES (NULL,'语文');
      INSERT INTO course VALUES (NULL,'数学');
      
      
      CREATE TABLE stu_cr(
      	id INT PRIMARY KEY AUTO_INCREMENT,
      	sid INT,
      	cid INT,
      	CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id),
      	CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id)
      );
      INSERT INTO stu_cr VALUES (NULL,1,1);
      INSERT INTO stu_cr VALUES (NULL,1,2);
      INSERT INTO stu_cr VALUES (NULL,2,1);
      INSERT INTO stu_cr VALUES (NULL,2,2);
      
    • 步骤二:配置文件

      <?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.yyl.table03.ManyToManyMapper">
          <resultMap id="manyToMany" type="student">
              <id column="sid" property="id"/>
              <result column="sname" property="name"/>
              <result column="sage" property="age"/>
      
              <collection property="courses" ofType="course">
                  <id column="cid" property="id"/>
                  <result column="cname" property="name"/>
              </collection>
          </resultMap>
          <select id="selectAll" resultMap="manyToMany">
              SELECT sc.sid,s.name sname,s.age sage,sc.cid,c.name cname FROM student s,course c,stu_cr sc WHERE sc.sid=s.id AND sc.cid=c.id
          </select>
      </mapper>
      
    • 步骤三:测试类

       @Test
         public void selectAll() throws Exception
             //1.加载核心配置文件
             InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
      
             //2.获取SqlSession工厂对象
             SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
      
             //3.通过工厂对象获取SqlSession对象
             SqlSession sqlSession = sqlSessionFactory.openSession(true)以上是关于MyBatis:MyBatis的输入映射和输出映射的主要内容,如果未能解决你的问题,请参考以下文章

      Mybatis输入映射和输出映射

      MyBatis总结之输入和输出映射

      Mybatis_7输入映射和输出映射

      mybatis的映射

      mybatis系列笔记---输入输出映射

      Mybatis学习输入映射输出映射动态sql