MyBatis的通俗理解:SqlSession.getMapper()源码解读

下面是“MyBatis的通俗理解:SqlSession.getMapper()源码解读”的完整攻略。

一、背景介绍

在MyBatis中,SqlSession.getMapper()方法是一个非常重要的方法,可以获取到Mapper接口的代理对象,从而进行数据库操作。但是,为什么可以用一个接口进行数据库操作呢?这就需要了解一下MyBatis的动态代理机制。

二、MyBatis动态代理机制

在MyBatis中,每个Mapper接口都需要对应一个Mapper XML文件,该文件中定义了该接口中所有方法的SQL语句。但是,MyBatis并不是直接将该接口转换为SQL语句执行,而是通过动态代理方式生成该接口的实现类,从而运行接口中的方法。

例如,定义如下一个UserMapper接口:

public interface UserMapper {
    User getUserById(int id);
}

对应的Mapper XML文件定义如下:

<mapper namespace="com.example.dao.UserMapper">
    <select id="getUserById" parameterType="int" resultType="User">
        select * from user where id = #{id}
    </select>
</mapper>

则通过动态代理方式,可以生成如下的UserMapper实现类:

public class UserMapperImpl implements UserMapper {
    private SqlSession sqlSession;

    public UserMapperImpl(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }

    public User getUserById(int id) {
        return sqlSession.selectOne("com.example.dao.UserMapper.getUserById", id);
    }
}

这样,通过SqlSession的getMapper()方法获取到的UserMapper实例就是通过动态代理生成的,可以使用Mapper XML文件中定义的SQL语句进行数据库操作。

三、SqlSession.getMapper()源码解读

现在,我们来看看SqlSession.getMapper()方法的源码实现:

public <T> T getMapper(Class<T> type) {
    return configuration.getMapper(type, this);
}

可以看到,这里调用了Configuration.getMapper()方法,而Configuration是MyBatis中的核心配置类,负责解析XML文件并创建相应的对象。我们可以继续查看getMapper()方法的实现:

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
    if (mapperProxyFactory == null)
        throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    try {
        return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {
        throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
}

可以看到,这里首先根据type从knownMappers中获取到MapperProxyFactory对象,MapperProxyFactory是一个代理工厂类,专门用于生成Mapper接口的代理对象。如果获取不到MapperProxyFactory对象,则说明该接口没有对应的Mapper XML文件,将抛出BindingException异常。否则,将通过mapperProxyFactory.newInstance()方法创建代理对象。

四、示例演示

下面通过两个示例演示如何使用SqlSession.getMapper()方法。

示例一

假设我们有一个UserMapper接口,定义了所有和用户相关的数据库操作方法,代码如下:

public interface UserMapper {
    User getUserById(int id);
    List<User> getUsersByGender(String gender);
    void addUser(User user);
    void updateUser(User user);
    void deleteUser(int id);
}

正确的使用方式如下:

SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(1);
assert user != null;
sqlSession.commit();
sqlSession.close();

可以看到,通过SqlSession.getMapper()方法获取到UserMapper的代理对象,然后就可以使用该对象中定义的方法进行数据库操作。

示例二

如果我们有一个ArticleMapper接口,但是没有对应的Mapper XML文件,使用SqlSession.getMapper()方法将无法获取到该接口的代理对象,代码如下:

public interface ArticleMapper {
    Article getArticleById(int id);
}

错误的使用方式如下:

SqlSession sqlSession = MyBatisUtils.getSqlSession();
ArticleMapper articleMapper = sqlSession.getMapper(ArticleMapper.class); // 会抛出BindingException异常
sqlSession.close();

可以看到,getMapper()方法将抛出BindingException异常,提示该接口对应的Mapper XML文件不存在。

五、总结

通过本文对MyBatis的通俗理解:SqlSession.getMapper()源码解读进行讲解,我们可以了解到MyBatis的动态代理机制是如何工作的,并且可以正确地使用SqlSession.getMapper()方法进行数据库操作。同时,通过示例演示,还可以更好地理解该方法的使用方式和常见错误。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:MyBatis的通俗理解:SqlSession.getMapper()源码解读 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • java多线程实现有序输出ABC

    要实现有序输出ABC,可以通过以下几种方式实现: 方式一:使用synchronized关键词 在Java中,synchronized关键字可以锁住对象,只允许一个线程访问同一时间内执行的代码块。我们可以使用该关键字来实现对三个线程输出ABC顺序的控制。 public class ABCPrinter implements Runnable { private…

    Java 2023年5月19日
    00
  • js的表单操作 简单计算器

    下面是一份详细讲解js表单操作的简单计算器的攻略,包含了实现步骤和示例说明。 实现步骤 1. 准备HTML页面 首先,我们需要准备一个HTML页面,用于实现表单操作的简单计算器。在页面中需要包含以下元素: 输入框:用于用户输入数字; 操作符选择框:用于用户选择加、减、乘、除四种操作符; “计算”按钮:用于触发计算操作; 结果展示区:用于展示计算结果。 HTM…

    Java 2023年6月15日
    00
  • Java获取当地的日出日落时间代码分享

    来讲解如何获取当地的日出日落时间。需要的工具是Java的日期时间api和一个名为SunsetSunrise的开源库。 导入SunsetSunrise库: 首先需要在Java项目中导入SunsetSunrise库。该库可以在Github上进行下载: https://github.com/davidmoten/sunsetsunrise 可以选择下载源代码然后进…

    Java 2023年5月20日
    00
  • Java Arrays工具类用法详解

    我来为您详细讲解“Java Arrays工具类用法详解”的完整攻略。 Java Arrays 工具类用法详解 简介 在 Java 中,Arrays 是一个提供了很多操作数组的静态工具类。其提供了一些静态方法,用于对数组进行操作,如排序、搜索、赋值等。本篇攻略将详细介绍 Arrays 的使用方法。 Arrays 类的静态方法 Arrays 类包含了很多静态方法…

    Java 2023年5月26日
    00
  • Struts2单选按钮详解及枚举类型的转换代码示例

    Struts2单选按钮详解及枚举类型的转换代码示例 什么是单选按钮 单选按钮是一种常见的选项表单元素,通常用于让用户在多个选项中选择一个。在Struts2中,通过使用<s:radio>标签可以轻松地创建单选按钮,并且支持流行的UI框架,如Bootstrap和jQuery UI。 Struts2中的单选按钮标签 在Struts2中,单选按钮通过&l…

    Java 2023年5月20日
    00
  • JpaRepository如何实现增删改查并进行单元测试

    JpaRepository是Spring Data JPA中的一个接口,该接口为开发人员提供了一种简单的方式来实现增删改查等常见操作。下面是JpaRepository如何实现增删改查并进行单元测试的完整攻略。 1. 增加数据 JpaRepository提供了一个save()方法来保存一个实体对象。该方法可以用于添加数据。以下是示例代码: @Service p…

    Java 2023年5月20日
    00
  • 一文教你掌握Java如何实现判空

    接下来我将为你详细讲解实现Java判空的完整攻略。 判空的概念 判空,是指对一个对象或变量进行判断,看是否为空。在Java中,判空通常指的是null。 判断不为空的方法 1.使用判断语句 我们可以使用if语句来判断一个值是否为null。例如: if(s != null){ System.out.println("s不为空"); } 这段代…

    Java 2023年5月27日
    00
  • spring boot整合spring-kafka实现发送接收消息实例代码

    下面我将为您详细讲解spring boot整合spring-kafka实现发送接收消息的攻略。 一、集成Spring-Kafka依赖 在pom.xml文件中添加spring-kafka的依赖: <dependency> <groupId>org.springframework.kafka</groupId> <art…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部