mybatis一对一的三种实现方式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wrp920227/article/details/54017835

mybatis一对一的三种实现方式

数据准备:

使用mysql数据库作为测试。建表语句及测试数据:

CREATE TABLE `classes` (
  `class_id` int(11) NOT NULL AUTO_INCREMENT,
  `class_name` varchar(255) DEFAULT NULL,
  KEY `class_id` (`class_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1003 DEFAULT CHARSET=utf8;

insert  into `classes`(`class_id`,`class_name`) values (1001,'一班'),(1002,'二班');

CREATE TABLE `student` (
  `student_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `class_id` int(11) DEFAULT NULL,
  KEY `student_id` (`student_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10004 DEFAULT CHARSET=utf8;

insert  into `student`(`student_id`,`name`,`age`,`class_id`) values (10001,'张三',20,1001),(10002,'李四',21,1001),(10003,'王五',22,1002);

model类:

Student.java

package com.example.model;

/**
 * @author wrp
 * @Description com.example.model.Student
 * @Date 2017/1/4
 */
public class Student {

    private Integer studentId;

    private String name;

    private Integer age;

    private Integer classId;

    private Classes classes;

    public Integer getStudentId() {
        return studentId;
    }

    public void setStudentId(Integer studentId) {
        this.studentId = studentId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getClassId() {
        return classId;
    }

    public void setClassId(Integer classId) {
        this.classId = classId;
    }

    public Classes getClasses() {
        return classes;
    }

    public void setClasses(Classes classes) {
        this.classes = classes;
    }
}

Classes.java

package com.example.model;

/**
 * @author wrp
 * @Description com.example.model.Class
 * @Date 2016/12/30
 */
public class Class {

    private Integer classId;

    private String className;

    public Integer getClassId() {
        return classId;
    }

    public void setClassId(Integer classId) {
        this.classId = classId;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }
}

mybatis xml:

Classes.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.example.dao.ClassesDao">

    <resultMap id="ClassesMap" type="com.example.model.Classes">
        <id property="classId" column="class_id" />
        <result property="className" column="class_name" />
    </resultMap>

    <select id="getClasses" parameterType="java.lang.Integer" resultMap="ClassesMap">
        SELECT
        t.class_id,
        t.class_name
        FROM classes t
        WHERE t.class_id = #{classId}
    </select>

</mapper>

Student.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.example.dao.StudentDao">

    <!-- 一对一关联 方式一 begin -->
    <select id="selectAllStudent1" resultType="com.example.model.Student">
        SELECT
        t.student_id as studentId,
        t.name as name,
        t.age as age,
        t.class_id as classId,
        t2.class_id "classes.classId",
        t2.class_name "classes.className"
        FROM student t
        LEFT JOIN classes t2 ON t.class_id=t2.class_id
    </select>
    <!-- 一对一关联 方式一 end -->

    <!-- 一对一关联 方式二 begin -->
    <resultMap id="StudentMap2" type="com.example.model.Student">
        <id property="studentId" column="student_id" />
        <result property="name" column="name" />
        <result property="age" column="age" />
        <result property="classId" column="class_id" />
        <association property="classes" resultMap="com.example.dao.ClassesDao.ClassesMap" />
    </resultMap>
    <!--<resultMap id="StudentMap2" type="com.example.model.Student">
        <id property="studentId" column="student_id" />
        <result property="name" column="name" />
        <result property="age" column="age" />
        <result property="classId" column="class_id" />
        <association property="classes" javaType="com.example.model.Classes">
            <id property="classId" column="class_id" />
            <result property="className" column="class_name" />
        </association>
    </resultMap>-->
    <select id="selectAllStudent2" resultMap="StudentMap2">
        SELECT
        t.student_id,
        t.name,
        t.age,
        t.class_id,
        t2.class_name
        FROM student t
        LEFT JOIN classes t2 ON t.class_id=t2.class_id
    </select>
    <!-- 一对一关联 方式二 end -->

    <!-- 一对一关联 方式三 begin -->
    <resultMap id="StudentMap3" type="com.example.model.Student">
        <id property="studentId" column="student_id" />
        <result property="name" column="name" />
        <result property="age" column="age" />
        <result property="classId" column="class_id" />
        <association property="classes" column="class_id" select="com.example.dao.ClassesDao.getClasses" />
    </resultMap>
    <select id="selectAllStudent3" resultMap="StudentMap3">
        SELECT
        t.student_id,
        t.name,
        t.age,
        t.class_id
        FROM student t
    </select>
    <!-- 一对一关联 方式三 end -->

</mapper>

dao类:

ClassesDao.java

package com.example.dao;

import com.example.model.Classes;

/**
 * @author wrp
 * @Description com.example.dao.Classes
 * @Date 2017/1/4
 */
public interface ClassesDao {

    Classes getClasses(Integer classId);

}

StudentDao.java

package com.example.dao;

import com.example.model.Student;

import java.util.List;

/**
 * @author wrp
 * @Description com.example.dao.StudentDao
 * @Date 2017/1/4
 */
public interface StudentDao {

    List<Student> selectAllStudent1();

    List<Student> selectAllStudent2();

    List<Student> selectAllStudent3();

}

测试用例:

StudentDaoTest.java

package com.example.dao;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.example.model.Student;
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;

import java.util.List;

/**
 * @author wrp
 * @Description com.example.dao.StudentDaoTest
 * @Date 2017/1/4
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class StudentDaoTest {

    @Autowired
    private StudentDao studentDao;

    @Test
    public void selectAllStudent1() {
        List<Student> students = studentDao.selectAllStudent1();
        System.out.println(JSON.toJSONString(students));
        //[{"age":20,"classId":1001,"classes":{"classId":1001,"className":"一班"},"name":"张三","studentId":10001},{"age":21,"classId":1001,"classes":{"classId":1001,"className":"一班"},"name":"李四","studentId":10002},{"age":22,"classId":1002,"classes":{"classId":1002,"className":"二班"},"name":"王五","studentId":10003}]
    }

    @Test
    public void selectAllStudent2() {
        List<Student> students = studentDao.selectAllStudent2();
        System.out.println(JSON.toJSONString(students));
    }

    @Test
    public void selectAllStudent3() {
        List<Student> students = studentDao.selectAllStudent3();
        // 禁用FastJson的“循环引用检测”特性。
        System.out.println(JSON.toJSONString(students, SerializerFeature.DisableCircularReferenceDetect));
    }

}

注意:

1:本文三种方式排序按照个人建议,第三种可能会带来N+1的查询次数。

2:FastJson转换json,会有循环引用检测的特性,需要加SerializerFeature.DisableCircularReferenceDetect参数禁用。


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页