MyBatis自定义映射关系和关联查询实现方法详解

 更新时间:2023年04月12日 10:59:57   作者:会洗碗的CV工程师  
这篇文章主要介绍了MyBatis自定义映射关系和关联查询实现方法,当POJO属性名与数据库列名不一致时,需要自定义实体类和结果集的映射关系,在MyBatis注解开发中,使用@Results定义并使用自定义映射,使用 @ResultMap使用自定义映射

一、使用注解实现自定义映射关系

当POJO属性名与数据库列名不一致时,需要自定义实体类和结果集的映射关系,在MyBatis注解开发中,使用 @Results 定义并使用自定义映射,使用 @ResultMap 使用自定义映射,用法如下:

前戏:为了体验这个效果,我们可以修改一下User实体类代码,如下

package com.example.pojo;
import java.io.Serializable;
public class User implements Serializable {
    private int id;
    private String username1;
    private String sex1;
    private String address1;
    public User(String programmer, String man, String shangHai) {
        this.username1 = programmer;
        this.sex1 = man;
        this.address1 = shangHai;
    }
    public User(int i, String programmer_1, String woman, String shenzhen) {
        this.id = i;
        this.username1 = programmer_1;
        this.sex1 = woman;
        this.address1 = shenzhen;
    }
    public User() {
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername1() {
        return username1;
    }
    public void setUsername1(String username1) {
        this.username1 = username1;
    }
    public String getSex1() {
        return sex1;
    }
    public void setSex1(String sex1) {
        this.sex1 = sex1;
    }
    public String getAddress1() {
        return address1;
    }
    public void setAddress1(String address1) {
        this.address1 = address1;
    }
    @Override
    public String toString() {
        return "User[ " +
                "id=" + id +
                ", username1='" + username1 + '\'' +
                ", sex1='" + sex1 + '\'' +
                ", address1='" + address1 + '\'' +
                " ]";
    }
}

1. 编写注解方法

    // 查询所有用户
    @Results(id="userDiyMapper",value = {
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "username1",column = "username"),
            @Result(property = "sex1",column = "sex"),
            @Result(property = "address1",column = "address")
    })
    @Select("select * from user")
    List<User> findAll1();
    // 根据id查询
    @ResultMap("userDiyMapper")
    @Select("select * from user where id = #{id}")
    User findById(int id);

注意啊:这里property对应的是实体类属性名,column对应的就是数据库表的列名

2. 编写测试方法

    @Test
    public void testFindAll1(){
        List<User> all = userMapper.findAll1();
        all.forEach(System.out::println);
        System.out.println("---------------------");
        System.out.println(userMapper.findById(5));
    }

看看能否查询出所有用户和id为5的用户,并且留意对应的属性名

3. 查看运行结果

OK,看来都是符合我们的预期的。

二、使用注解实现一对一关联查询

在MyBatis的注解开发中对于多表查询只支持分解查询,不支持连接查询。

这里我们采用学生表和班级表做对比,所以我们先新建Student实体类和Classes实体类

Classes实体类

package com.example.pojo;
import java.util.List;
public class Classes {
    private int cid;
    private String className;
    private List<Student> studentList;
    public int getCid() {
        return cid;
    }
    public void setCid(int cid) {
        this.cid = cid;
    }
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }
    public List<Student> getStudentList() {
        return studentList;
    }
    public void setStudentList(List<Student> studentList) {
        this.studentList = studentList;
    }
    @Override
    public String toString() {
        return "Classes[ " +
                "cid=" + cid +
                ", className='" + className + '\'' +
                ", studentList=" + studentList + 
                " ]";
    }
}

Student实体类

package com.example.pojo;
public class Student {
    private int sid;
    private String name;
    private int age;
    private String sex;
    private Classes classes;
    public int getSid() {
        return sid;
    }
    public void setSid(int sid) {
        this.sid = sid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Classes getClasses() {
        return classes;
    }
    public void setClasses(Classes classes) {
        this.classes = classes;
    }
    @Override
    public String toString() {
        return "Student[ " +
                "sid=" + sid +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", classes=" + classes +
                " ]";
    }
}

1. 编写注解方法

StudentMapper添加查询所有用户

package com.example.mapper;
import com.example.pojo.Student;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface StudentMapper {
    @Select("select * from student")
    // 自定义映射关系
    @Results(id = "studentMapper",value = {
            @Result(id = true,property = "sid",column = "sid"),
            @Result(property = "name",column = "name"),
            @Result(property = "age",column = "age"),
            @Result(property = "sex",column = "sex"),
            /**
             * property:属性名
             * column:调用从表方法时传入的参数列
             * one:表示该属性是一个对象
             * select:调用的是从表方法
             * fetchType:加载方式
             */
            @Result(property = "classes",column = "classId",
                one = @One(select = "com.example.mapper.ClassesMapper.findByCid",
                        fetchType = FetchType.EAGER)
                )
    })
    List<Student> findAll();
}

ClassesMapper添加根据id查询班级

package com.example.mapper;
import com.example.pojo.Classes;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
public interface ClassesMapper {
    // 根据id查询班级
    @Select("select * from classes where cid = #{cid}")
    Classes findByCid(Integer id);
}

2. 编写测试方法

// 测试一对一查询
    @Test
    public void testFindAllStudent(){
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        List<Student> all = studentMapper.findAll();
        all.forEach(System.out::println);
    }

看看能否查询出学生对应的班级,如果可以则查询成功

3. 查看运行结果

OK,看图我们是已经成功查询出每个学生对应的班级的

三、使用注解实现一对多关联查询

在这里我们主要实现查询所有班级的时候把对应的学生列表也查询出来。

1. 编写注解方法

StudentMapper添加根据班级id查询学生

// 根据班级Id查询学生
    @Select("select * from student where ClassId = #{classId}")
    List<Student> findByClassId(int classId);

Classes添加查询所有班级

// 查询所有班级
    @Select("select * from classes")
    @Results(id = "classMapper",value = {
            @Result(id = true,property = "cid",column = "cid"),
            @Result(property = "className",column = "className"),
            // many:表示该属性是一个集合
            @Result(property = "studentList",column = "cid",
            many = @Many(select = "com.example.mapper.StudentMapper.findByClassId",
                        fetchType = FetchType.LAZY))
    })
    List<Classes> findAll();

2. 编写测试方法

// 测试一对多查询
    @Test
    public void findAllClasses(){
        ClassesMapper classesMapper = session.getMapper(ClassesMapper.class);
        List<Classes> all = classesMapper.findAll();
        all.forEach(System.out::println);
    }

观察能否查询出班级对应的学生列表

3. 查看运行结果

OK,确实也是可以查询出来了的。

四、注解文件和映射文件开发对比

注解开发更快,映射文件更方便。

MyBatis中更推荐使用映射文件开发,Spring、SpringBoot更推荐注解方式。具体使用要视项目情况而定。它们的优点对比如下:

映射文件:

  • 代码与Sql语句是解耦的,修改时只需修改配置文件,无需修改源码。
  • Sql语句集中,利于快速了解和维护项目。
  • 级联查询支持连接查询和分解查询两种方式,注解开发只支持分解查询。

注解:

  • 配置简单,开发效率高。
  • 类型安全,在编译期即可进行校验,不用等到运行时才发现错误。

我个人也是比较喜欢映射文件开发,主要更喜欢方便维护和了解。

到此这篇关于MyBatis自定义映射关系和关联查询实现方法详解的文章就介绍到这了,更多相关MyBatis自定义映射关系内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 关于SpringCloud Ribbon替换轮询算法问题

    关于SpringCloud Ribbon替换轮询算法问题

    Spring Cloud Ribbon是基于Netlix Ribbon实现的一套客户端负载均衡的工具。接下来通过本文给大家介绍SpringCloud Ribbon替换轮询算法问题,需要的朋友可以参考下
    2022-01-01
  • SpringBoot实现多数据源的切换实践

    SpringBoot实现多数据源的切换实践

    这篇主要介绍了SpringBoot实现多数据源的切换,本文基于AOP来实现数据源的切换,文中通过示例代码介绍的非常详细,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Java中正则表达式匹配过程实例详解

    Java中正则表达式匹配过程实例详解

    正则匹配即是在给定字符串中查找符合正则表达式的字符,下面这篇文章主要给大家介绍了关于Java中正则表达式匹配过程的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • 浅谈Servlet开发技术基础

    浅谈Servlet开发技术基础

    这篇文章主要介绍了浅谈Servlet开发技术基础,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • 使用java获取md5值的两种方法

    使用java获取md5值的两种方法

    本篇文章是对使用java获取md5值的两种方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • IDEA插件开发之环境搭建过程图文详解

    IDEA插件开发之环境搭建过程图文详解

    这篇文章主要介绍了IDEA插件开发之环境搭建过程,本文通过图文并茂实例代码相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • 使用SpringBoot与Thrift实现RPC通信的方式详解

    使用SpringBoot与Thrift实现RPC通信的方式详解

    在微服务架构的世界里,服务间的通信机制选择成为了关键决策之一,RPC因其简洁、高效的特点备受青睐,本文将详细探讨如何利用Spring Boot和Thrift框架构建RPC通信,让读者理解其内在原理及实现方式,需要的朋友可以参考下
    2023-10-10
  • 分享Java性能调优的11个实用技巧

    分享Java性能调优的11个实用技巧

    这些建议中的大多数都是基于Java的,但是也不一定,也有一些是可以应用于所有的应用程序和编程语言的。在我们分享基于Java的性能调优技巧之前,让我们先讨论一下这些通用的性能调优技巧
    2017-11-11
  • SpringBoot中使用@Async实现异步任务调用详解

    SpringBoot中使用@Async实现异步任务调用详解

    这篇文章主要介绍了SpringBoot中使用@Async实现异步任务调用详解,一个可以无需等待被调用函数的返回值就让操作继续进行的方法(来自百度百科),即程序在顺序执行时,不等待异步调用的语句返回结果就执行后面的程序,需要的朋友可以参考下
    2023-12-12
  • java读取文件内容为string字符串的方法

    java读取文件内容为string字符串的方法

    今天小编就为大家分享一篇java读取文件内容为string字符串的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07

最新评论