【mybatis - 1】一文入门mybatis源码


前言

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。应该是目前最火的ORM框架。它的实现原理非常简单。我以最简单的代码示例来帮助大家入门mybatis源码。


一、mybatis源码入门

在使用mybatis开发的时候,经常会有一个名为mapper的包,里面的一般会有UserMapper等这样的java类。例如:

@Repository
public interface UserMapper 
{
	@Select("select * from t_user where id=#{id}")
	User selectById(Long id);
}

我们只需要定义一个接口,定义一些方法,通过注解或者xml写上sql语句,即可实现数据的查询。这种非常方便。mybatis通过动态代理帮助开发者创建实现类,大大提升了开发效率。其原理如下。
为了更加清晰,创建了一个纯净的maven工程。
创建Select注解。对于mybatis的注解进行高仿。

package com;
import java.lang.annotation.*;
/**
 *  2021/4/3.
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Select {
    String value();
}

创建mapper接口。

interface UserMapper{
    @Select("select * from t_user where id=#{id}")
    Object selectById(Long id);
}

对于开发者来说,一般在service中注入这个userMapper,并且调用selectById方法即可。

	//@Autowired
    UserMapper userMapper =(UserMapper) Proxy.newProxyInstance(MyBatisTest.class.getClassLoader(), new Class[]{UserMapper.class},new InvocationHandlerMy());
      
	public void selectById(Long id){
		  userMapper.selectById(2L);
	}

如上示例,一般service中由@Autowired注解进行注入,因为此为纯净的工程没有@Autowired注解,这里可以通过jdk动态代理创建一个代理对象,最后调用selectById方法,调用之后的逻辑在InvocationHandlerMy方法中进行实现。

class InvocationHandlerMy implements InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       //获取调用方法的注解信息
        Select annotation = method.getAnnotation(Select.class);
        if(annotation!=null){
        	//获取注解的value。
        	//在Select的value存放的是sql信息
            String value = annotation.value();
            System.out.println(value);
            //打印参数
            System.out.println(Arrays.asList(args));
             //创建连接
	        //执行sql
	        //封装对象
	        //关闭连接
        }
        return null;
    }
}

打印结果:

select * from t_user where id=#{id}
[2]

InvocationHandlerMy中已经成功接收到了注解的信息和入参,这个时候就可以对sql自行处理。比如参数的替换,事务的处理等等。
另外sql中需要进行将#{id}替换为对应的参数,代码示例如下:
新增@Param注解

package com;
import java.lang.annotation.*;
/**
 *   2021/4/3.
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface Param {
    String value();
}

使用@Param注解

interface UserMapper{
    @Select("select * from t_user where id=#{id} and status=#{status}")
    Object selectById(@Param("id") Long id,@Param("status")String status);
}

封装注解信息和对应的参数

	//获取
    public static Map<String, Object> getArgMap(Method method, Object[] args) {
        Map<String,  Object> argMap = new HashMap<String, Object>();
        Parameter[] par = method.getParameters();
        for(int i=0;i<par.length;i++){
            Parameter p = par[i];
            Param annotation = p.getAnnotation(Param.class);
            String value = annotation.value();
            argMap.put(value,args[i]);
        }
        return argMap;
    }
    //打印map
    //{id=2, status=on}

获取了key-value对应关系之后,可以通过apache-commons-text工具类对sql的参数进行替换
当然mybatis的功能特别多,它的源码也相对复杂一点,这只是展示了一下它最基本的思路,方便大家更加快速的学习他的源码。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叁滴水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值