Mybatis源码分析Mapper文件的注册和绑定

本文深入探讨了Mybatis如何注册与绑定Mapper。通过解析Mybatis源码,详细介绍了从SqlSessionFactory的创建到Mapper接口的实例化过程,涉及到XMLMapperBuilder、MapperRegistry和MapperProxyFactory等关键步骤,揭示了Mapper方法与数据库交互的底层机制。
摘要由CSDN通过智能技术生成

Mybatis 是一个「面向 sql」的持久层框架,它可实现动态拼装 sql,极其灵活,同时避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集,其插件机制允许在已映射语句执行过程中的某一点进行拦截调用等等。
我们都知道 Mapper 是一个接口,它的每个方式是我们与数据库交互的入口,每个 Mapper 都有与之相对应的一个 XML 文件,我们可以在 XML 里面自由快活地写 sql,当然我们也可以用注解的形式写在接口方法上,但终究还是没 XML 灵活,那么问题来了,Mybatis 是如何注册与绑定 Mapper 的呢?下面我带你揭开这个神秘的面纱。
首先我们来看看用 Mybatis 执行 sql 的两种方法

直接操作 SqlSession 方法

public User findUserById(Integer userId) {
   
  SqlSession sqlSession = MyBatisSqlSessionFactory.getSqlSession();
  try {
   
    // namespace + statementId
    return sqlSession.selectOne("com.objcoding.mybatis.UserMapper.findUserById", userId);
  } finally {
   
    sqlSession.close();
  }
}

通过 Mapper 接口

public User findUserById(Integer userId) {
   
  SqlSession sqlSession = MyBatisSqlSessionFactory.getSqlSession();
  try {
   
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    return userMapper.findUserById(userId);
  } finally {
   
    sqlSession.close();
  }
}
public class UserMapper {
   
  User findUserById(@Param("userId") String userId);
}
<?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.objcoding.mybatis.UserMapper">
  <select id="findUserById" resultType="com.objcoding.mybatis.User">
    SELECT * FROM user WHERE user_id=#{
   userId}
  </select>
</mapper>

很明显,第二种方法可以大大降低了手工写 namespace 出现错误的概率,且用 Mapper 可以直接操作方法来实现数据链接,看起来优雅很多。

那么 Mapper 是如何示例化的,它是通过 Java 动态代理生成的一个代理类,并与 sqlSession 关联一起,看如下图:
在这里插入图片描述
看得出来,此时的 Mapper 是 Spring Bean 容器里面的一个 Bean,它是一个代理类,那么这个代理类的生成过程是怎样的呢?下面带你一起看看 mybatis 源码。

创建一个 SqlSessionFactory 实例并注入 Bean 容器中:

@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
   
  PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
  SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

  // 此处省略部分代码

  bean.setMapperLocations(resolver.getResources("classpath*:com/**/*Mapper.xml"));//
  return bean.getObject();
}

bean.getObject():

@Override
public SqlSessionFactory getObject() throws Exception {
   
  if (this.sqlSessionFactory == null) {
   
    afterPropertiesSet();
  }

  return this.sqlSessionFactory;
}
@Override
public void afterPropertiesSet() throws Exception {
   
  // 此处省略部分代码
  this.sqlSessionFactory = buildSqlSessionFactory();
}

sqlSessionFactory.buildSqlSessionFactory()

protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
   
  Configuration configuration;
  // 此处省略部分代码
  SqlSessionFactory sqlSessionFactory =this.sqlSessionFactoryBuilder.build(configuration);
  // 此处省略部分代码
  if (!isEmpty(this.mapperLocations)) {
   
    <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值