继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

【MyBatis】学习纪要二:一对一,一对多,多对一,多对多

冯文议
关注TA
已关注
手记 82
粉丝 1.4万
获赞 707
引言

接上篇【MyBatis】学习纪要一:SpringBoot集成MyBatis完成增删查改,本节我们来研究一下常用的关联关系:一对一一对多多对一多对多

看了我的第一篇,大家可能有一个疑问,我提供的代码(github上)有采用注解的方式,多简洁啊,为什么在这个学习系列要用 XML 的方式啊,这种写起来好麻烦啊。

其实,我也不喜欢这种方式,这也是我最初学习Hibernate(JPA),不学习MyBatis的原因,相反,我还觉得它非常难学。这个问题的在开篇之处就告诉大家了,采用 XML 的方式,我们可以自己写 SQL,后期也好优化。大抵就这两点。其他的话,可能有的人有,有的人没有。

SQL

以前在学 SQL 的时候,关联关系,我们会以外键的方式存取,因此,这四种关系,可以用一个关键词解决—— association

没错就是它,只要学了它,基本就够用了,但是MyBatis还为我们提供了一个关键词——collection

所以,下面我们就来学习这两个关键词。

association

假设一个班级一个班主任,一个老师也只能是一个班的班主任,这样班级和班主任之前就是一一对应的关系的,相当于一对一

Teacher

package com.fengwenyi.demo1.entity;

/**
 * @author Wenyi Feng
 */
public class Teacher {

    private Long id;
    private String name;
    // getter and setter
}

Cls

package com.fengwenyi.demo1.entity;

/**
 * @author Wenyi Feng
 */
public class Cls {

    private Long id;
    private String name;
    private Teacher teacher;
    // getter and setter
}

建数据表

DROP TABLE IF EXISTS `cls`;
CREATE TABLE `cls` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `teacher_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk` (`teacher_id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `cls_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk` (`cls_id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

ClsDao

package com.fengwenyi.demo1.dao;

import com.fengwenyi.demo1.entity.Cls;
import org.apache.ibatis.annotations.Mapper;

/**
 * @author Wenyi Feng
 */
@Mapper
public interface ClsDao {

    Cls findByTeacherId (Long teacherId);

}

ClsMapper

<?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.fengwenyi.demo1.dao.ClsDao" >
    <resultMap id="BaseResultMap" type="com.fengwenyi.demo1.entity.Cls" >
        <id column="cId" property="id" jdbcType="BIGINT" />
        <result column="cName" property="name" jdbcType="VARCHAR" />
        <association property="teacher" javaType="com.fengwenyi.demo1.entity.Teacher">
            <id column="tId" property="id" jdbcType="BIGINT" />
            <result column="tName" property="name" jdbcType="VARCHAR" />
        </association>
    </resultMap>

    <select id="findByTeacherId" resultMap="BaseResultMap" parameterType="java.lang.Long" >
        SELECT
          c.id as cId,
          c.name as cName,
          t.id as tId,
          t.name as tName
        FROM
          cls c, teacher t
        WHERE
          c.teacher_id = t.id
          AND
          c.teacher_id = #{teacherId}
    </select>
</mapper>

ClsService

package com.fengwenyi.demo1.service;

import com.fengwenyi.demo1.dao.ClsDao;
import com.fengwenyi.demo1.entity.Cls;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author Wenyi Feng
 */
@Service
public class ClsService {

    @Autowired
    private ClsDao clsDao;

    public Cls findByTeacherId (Long teacherId) {
        return clsDao.findByTeacherId(teacherId);
    }

}

测试一下:

package com.fengwenyi.demo1;

import com.fengwenyi.demo1.entity.Cls;
import com.fengwenyi.demo1.service.ClsService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @author Wenyi Feng
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestOne2One {

    @Autowired
    private ClsService clsService;

    @Test
    public void test1 () {
        Cls cls = clsService.findByTeacherId(1L);

        System.out.println(cls.toString());
    }

}

结果:

one2one

数据库只有一条数据,没问题。

collection

如果把上面那个看懂的话,这个不就简单,因此,我只给出关键代码。

这次我们以班级和学生为例。

Cls

package com.fengwenyi.demo1.entity;

import java.util.List;

/**
 * @author Wenyi Feng
 */
public class Cls {

    private Long id;
    private String name;
    private List<Student> students;
    private Teacher teacher;
    // getter and setter
}

Student

package com.fengwenyi.demo1.entity;

/**
 * @author Wenyi Feng
 */
public class Student {

    private Long id;
    private String name;
    private Cls cls;
    // getter and setter
}

student.sql

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `cls_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk` (`cls_id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;

ClsMapper

<?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.fengwenyi.demo1.dao.ClsDao" >
    <resultMap id="BaseResultMap" type="com.fengwenyi.demo1.entity.Cls" >
        <id column="cId" property="id" jdbcType="BIGINT" />
        <result column="cName" property="name" jdbcType="VARCHAR" />
        <association property="teacher" javaType="com.fengwenyi.demo1.entity.Teacher">
            <id column="tId" property="id" jdbcType="BIGINT" />
            <result column="tName" property="name" jdbcType="VARCHAR" />
        </association>
        <collection property="students" ofType="com.fengwenyi.demo1.entity.Student">
            <id column="sId" property="id" jdbcType="BIGINT" />
            <result column="sName" property="name" jdbcType="VARCHAR" />
        </collection>
    </resultMap>

    <select id="findByTeacherId" resultMap="BaseResultMap" parameterType="java.lang.Long" >
        SELECT
          c.id as cId,
          c.name as cName,
          t.id as tId,
          t.name as tName
        FROM
          cls c, teacher t
        WHERE
          c.teacher_id = t.id
          AND
          c.teacher_id = #{teacherId}
    </select>

    <select id="findById" resultMap="BaseResultMap" parameterType="java.lang.Long" >
        SELECT
          c.id as cId,
          c.name as cName,
          t.id as tId,
          t.name as tName,
          s.id as sId,
          s.name as sName
        FROM
          cls c, teacher t, student s
        WHERE
          c.teacher_id = t.id
          AND
          s.cls_id = c.id
          AND
          c.id = #{id}
    </select>
</mapper>

测试代码:

@Test
public void test2 () {
    Cls cls = clsService.findById(1L);
    System.out.println(cls.toString());
    List<Student> students = cls.getStudents();
    for (Student student : students) {
        System.out.println(student.toString());
    }
}

测试结果:

Many2One

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP