Mybatis底层源码执行流程详解

                             Mybatis底层源码执行流程详解


目录

                             Mybatis底层源码执行流程详解

      Mybatis底层源码执行流程详解

         2.重点解析UserMapper userMapper=sqlSession.getMapper(UserMapper.class);

3.源码详解 UserMapper userMapper=sqlSession.getMapper(UserMapper.class);  


      Mybatis底层源码执行流程详解

1.UserMapper.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.tarena.dao.UserMapper">
<!-- namespace必须为包名.接口名 -->

    <!-- 根据id查询一个对象
    id="findUserById"   必须接口中的方法名称
    parameterType="java.lang.Integer"  必须对应接口方法参数类型
    resultType="User"  必须对应接口中的方法的返回类型
     -->
	<select id="findUserById"
	        parameterType="java.lang.Integer"
	        resultType="User">
		select 
		    id,
		    username name,
		    userpassword password,
		    address
		from
		t_user
		   where id=#{id}    
	</select>
</mapper>

 

 

2.重点解析UserMapper userMapper=sqlSession.getMapper(UserMapper.class);

package com.tarena.test;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.tarena.dao.UserMapper;
import com.tarena.entity.User;
import com.tarena.util.MyBatisUtil;

public class TestUserMapperClass {
	@Test
	public void testFindUserById(){
		SqlSession sqlSession=null;
		try{
			sqlSession=MyBatisUtil.getSession();
			//用UserMaper接口利用jdk动态代理生成接口儿子代理类,用代理生成代理对象
			//用代理对象调用目标方法,实际上执行的是InvocationHandler中的invoke方法
			//在invoke方法中调用selectOne等原生api方法,来做增删改查
			// 接口类型    jdk动态代理对象=sqlSession.getMapper(接口类型.class);
			UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
			User user=userMapper.findUserById(7);
			System.out.println(user);
			sqlSession.commit();
		}catch(Exception e){
			e.printStackTrace();
			sqlSession.rollback();
		}finally{
			sqlSession.close();
		}
		
	}
}

3.源码详解 UserMapper userMapper=sqlSession.getMapper(UserMapper.class);  

            进去看源码的时候getMapper会传两个参数  一个sqlSession调用者 一个是 UserMapper接口的类信息 

<T> 泛型  使用什么类 传什么类  当调用此方法会返回俩个参数  一个是 type 这是类型  为接口类型   this 就是谁调用就是谁(本类对象)  sqlSession

接着往下传  mapperRegistry  注册  还是那两个值 

创建一个代理工厂  缓存 如果有则直接从里面拿  如果没有则抛异常   代理工厂方法 把sqlsession 传进去

传进去三个参数  一个参数 一个接口  一个 方法缓存 

 

三个参数 一个类加载器 (mapperIntface  就是传进去的Classl类型对象) 一个 接口数组  一个接口子实现   这个子实现接口一定调用了

public class MapperProxy<T> implements InvocationHandler, Serializable {

首先进入里面 这个就跟之前的动态代理相似了,但是我们没有使用目标代理类 代理方法 所有不会走 第一个if 判断method是不是代理类 

也不走第二个if  判断是不是走的默认老方法 因为 我们就没有定义方法 所以关键点核心就在项目的execute 方法上 (下面的MaooerMethod 是缓存方法方面的 先不介绍)

 

execute 我们仿写的差不多  就是判断 方法 如何调用  根据 Sql 去解析XML 判断  存到 command.getType中 去一一判断 

command.getName() 是获取节点ID的

后面的源码就不一一展示了 

 总结:最终会进入到invoke方法里  去逐一判断   

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值