Mybatis Mapper接口和xml绑定的多种方式、内部实现原理和过程解析

 更新时间:2023年11月15日 15:09:57   作者:say荣帅  
在Mybatis中,我们需要创建一个与实体类对应的Mapper接口,然后在该接口上添加方法,这些方法对应着SQL语句,这篇文章主要介绍了Mybatis Mapper接口和xml绑定的多种方式、内部实现原理和过程,需要的朋友可以参考下

一、绑定方式

1. XML文件方式

在Mybatis中,我们需要创建一个与实体类对应的Mapper接口,然后在该接口上添加方法,这些方法对应着SQL语句。然后,我们需要创建一个XML文件,这个文件中包含了SQL语句和映射关系。

例如,我们有一个User实体类和一个UserMapper接口:

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

然后,我们可以创建一个名为UserMapper.xml的文件,内容如下:

<mapper namespace="com.example.dao.UserMapper">
    <select id="getUserById" resultType="com.example.entity.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

在这个XML文件中,namespace属性指定了Mapper接口的全限定名,id属性指定了SQL语句的唯一标识符,resultType属性指定了查询结果的类型。

2. 注解方式

Mybatis也支持通过注解的方式来进行映射。首先,需要在Mapper接口上添加@Mapper注解,然后在方法上添加@Select、@Insert、@Update、@Delete等注解来指定SQL语句。

例如,我们可以将上面的UserMapper接口改为注解方式:

import org.apache.ibatis.annotations.*;
@Mapper
public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{id}")
    User getUserById(int id);
}

在这个例子中,@Mapper注解表示这是一个Mapper接口,@Select注解表示这是一个查询语句,#{id}是参数占位符。

3. 需要注意

启动类上添加@MapperScan注解指定扫描路径

@SpringBootApplication
@MapperScan("com.example.mapper") // 指定扫描路径
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

不用@MapperScan注解,也可以在mybatis-config.xml中配置mapper映射文件的位置和命名空间

<configuration>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/> // 指定Mapper映射文件的位置和名称
    </mappers>
</configuration>

二、实现原理

1. 原理

Mybatis的Mapper接口和xml绑定的原理主要依赖于JDK动态代理技术

而Mybatis中MapperProxy代理类是mybatis实现Mapper接口和xml绑定的核心类之一。它实现了InvocationHandler接口,用于拦截Mapper接口方法的调用,并将方法名和参数传递给SqlSession对象执行相应的SQL语句。

2. MapperProxy代理类的实现过程

  • 首先,通过JDK动态代理技术生成一个MapperProxy代理类实例。这个代理类实现了Mapper接口,并重写了接口中的方法。
  • 在重写的方法中,MapperProxy会拦截方法调用,并将方法名和参数传递给SqlSession对象执行相应的SQL语句。
  • SqlSession对象会根据Mapper接口的namespace值找到对应的mapper.xml文件,并根据id值找到对应的SQL语句。然后,根据返回值类型和参数类型等信息,生成相应的Java代码。这些Java代码会包含对SqlSession的操作,例如查询、更新等操作。最终,SqlSession对象会将这些Java代码编译成字节码,并加载到JVM中运行。
  • 当SQL语句执行完毕后,SqlSession对象会将结果返回给MapperProxy代理类。然后,MapperProxy代理类会将结果映射为Java对象,并返回给调用者。

3. MapperProxy代理类源码

下面是MapperProxy代理class的核心方法实现:mybatis3.5.9

public class MapperProxy<T> implements InvocationHandler, Serializable {
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, args);
      } else {
        return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
  }
  private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {
    try {
      return MapUtil.computeIfAbsent(methodCache, method, m -> {
        if (m.isDefault()) {
          try {
            if (privateLookupInMethod == null) {
              return new DefaultMethodInvoker(getMethodHandleJava8(method));
            } else {
              return new DefaultMethodInvoker(getMethodHandleJava9(method));
            }
          } catch (IllegalAccessException | InstantiationException | InvocationTargetException
              | NoSuchMethodException e) {
            throw new RuntimeException(e);
          }
        } else {
          return new PlainMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
        }
      });
    } catch (RuntimeException re) {
      Throwable cause = re.getCause();
      throw cause == null ? re : cause;
    }
  }
  private MethodHandle getMethodHandleJava9(Method method)
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    final Class<?> declaringClass = method.getDeclaringClass();
    return ((Lookup) privateLookupInMethod.invoke(null, declaringClass, MethodHandles.lookup())).findSpecial(
        declaringClass, method.getName(), MethodType.methodType(method.getReturnType(), method.getParameterTypes()),
        declaringClass);
  }
  private MethodHandle getMethodHandleJava8(Method method)
      throws IllegalAccessException, InstantiationException, InvocationTargetException {
    final Class<?> declaringClass = method.getDeclaringClass();
    return lookupConstructor.newInstance(declaringClass, ALLOWED_MODES).unreflectSpecial(method, declaringClass);
  }
}

到此这篇关于Mybatis Mapper接口和xml绑定的多种方式、内部实现原理和过程的文章就介绍到这了,更多相关Mybatis Mapper接口和xml绑定内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Mybatis 数据库连接池的实现示例

    Mybatis 数据库连接池的实现示例

    在Java应用程序中,与数据库的连接是非常昂贵的,因此,当我们使用MyBatis进行数据操作时,需要一个连接池来分配并管理这些连接,本文主要介绍了Mybatis 数据库连接池的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • 关于maven的用法和几个常用的命令

    关于maven的用法和几个常用的命令

    这篇文章主要介绍了关于maven的用法和几个常用的命令,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • SpringBoot实现简单的登录注册的项目实战

    SpringBoot实现简单的登录注册的项目实战

    本文主要介绍了SpringBoot实现简单的登录注册的项目实战,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • JAVA OOM内存溢出问题深入解析

    JAVA OOM内存溢出问题深入解析

    这篇文章主要为大家介绍了JAVA OOM内存溢出问题深入解析,在生产环境抢修中,我们经常会碰到应用系统java内存OOM的情况,这个问题非常常见,今天我们就这个问题来深入学习探讨一下
    2023-10-10
  • 基于IDEA查看maven依赖结构流程解析

    基于IDEA查看maven依赖结构流程解析

    这篇文章主要介绍了基于IDEA查看maven依赖结构流程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • spring中@Transactional 注解失效的原因及解决办法

    spring中@Transactional 注解失效的原因及解决办法

    面试中经常会被问到事务失效的场景有哪些,本文主要介绍了spring中@Transactional 注解失效的原因及解决办法,具有一定的参考价值,感兴趣的可以了解一下
    2024-06-06
  • Java关于JDK1.8中的Optional类

    Java关于JDK1.8中的Optional类

    本文主要介绍了Optional类的一些常用方法,以及其应用场景,其主要是为了规避空指针异常(NPE)。熟练的运用Optional类可以很大的简化我们的代码,使代码简洁明了。,需要的朋友可以参考下面文章内容
    2021-09-09
  • java版实现2048游戏功能

    java版实现2048游戏功能

    这篇文章主要为大家详细介绍了java版实现2048游戏功能,相加数字出现2048即可,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • RocketMQ消息中间件超详细解读

    RocketMQ消息中间件超详细解读

    这篇文章主要介绍了RocketMQ消息中间件超详细解读,RocketMQ作为一款纯java、分布式、队列模型的开源消息中间件,支持事务消息、顺序消息、批量消息、定时消息、消息回溯等,本文就来详细解读一下,需要的朋友可以参考下
    2023-05-05
  • Java中进程与线程的区别

    Java中进程与线程的区别

    这篇文章主要介绍了Java进程与线程的区别,进程(Process)是操作系统分配资源的基本单位,线程(Thread)是操作系统能够进行运算调度的基本单位,下文更多两者区别。需要的小伙伴可以参考一下
    2022-05-05

最新评论