手写超简易版mybatis源码

流程图
在这里插入图片描述
测试类

/**
 * @Authror PABLO
 * @Date 2022/4/26 22:18
 * @Desc 手写简单版mybatis
 */
public class MybatisTest {
    
    
    public static void main(String[] args) {
    
    
        DefaultSqlSession defaultSqlSession = new DefaultSqlSession(new Configuration(),new Executor());
        BlogMapper mapper = defaultSqlSession.getMapper(BlogMapper.class);
        User user = mapper.getBlogById(1);
        System.out.println(user.toString());
    }
}

SqlSession

package com.mybatis.sqlsesson;

/**
 * @Authror PABLO
 * @Date 2022/4/26 21:23
 * @Desc mybatis接口层
 */
public interface SqlSession {
    
    

    /**
     * @Description: 获取代理对象
     * @Author: PABLO
     * @Date: 2022/4/26 21:24
     * @Params:
     * @Return:
     **/
    <T> T getMapper(Class<T> clazz);

    /**
     * @Description: 简单查询
     * @Author: PABLO
     * @Date: 2022/4/26 21:24
     * @Params:
     * @Return:
     **/
    <T> T selectOne(String statementId, Object param);


}

DefaultSqlSession

package com.mybatis.sqlsesson;

import com.learn.shejimoshi.combination.Clazz;
import com.mybatis.configuration.Configuration;
import com.mybatis.executor.Executor;

/**
 * @Authror PABLO
 * @Date 2022/4/26 21:29
 * @Desc
 */
public class DefaultSqlSession implements SqlSession {
    
    


    public DefaultSqlSession(Configuration configuration, Executor executor) {
    
    
        this.configuration = configuration;
        this.executor = executor;
    }

    private Configuration configuration;

    private Executor executor;


    /**
     * @Description: 动态代理获取接口映射器实例对象
     * @Author: PABLO
     * @Date: 2022/4/26 22:57
     * @Params: [clazz]
     * @Return: T
     **/
    @Override
    public <T> T getMapper(Class<T> type) {
    
    

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

    /**
     * @Description: 代理类调用,执行invoke
     * @Author: PABLO
     * @Date: 2022/4/26 22:59
     * @Params: 
     * @Return: 
     **/
    @Override
    public <T> T selectOne(String statementId, Object param) {
    
    
        //获取SQL语句
        String sql = configuration.sqlMappings.getString(statementId);
        return (T) executor.query(sql, param);
    }

}

Configuration


```java
package com.mybatis.configuration;

import com.mybatis.sqlsesson.DefaultSqlSession;
import com.mybatis.sqlsesson.SqlSession;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ResourceBundle;

/**
 * @Authror PABLO
 * @Date 2022/4/26 21:28
 * @Desc 配置类  保存接口映射器和sql语句
 */
public class Configuration {
    
    


    public static final ResourceBundle sqlMappings;
    
    //类加载解析配置文件SQL语句
    static {
    
    
        sqlMappings = ResourceBundle.getBundle("mybatis");
    }


    /**
     * @Description: 根据clazz动态代理获取代理对象
     * @Author: PABLO
     * @Date: 2022/4/26 21:45
     * @Params:
     * @Return:
     **/
    public <T> T getMapper(Class<T>  clazz, SqlSession sqlSession) {
    
    
        return  (T)Proxy.newProxyInstance(
                clazz.getClassLoader(),
                new Class[]{
    
    clazz}, new MyInvocation(sqlSession) {
    
    
                });
    }


}

class MyInvocation implements InvocationHandler{
    
    

    private SqlSession sqlSession;

    public MyInvocation(SqlSession sqlSession){
    
    
        this.sqlSession = sqlSession;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
    
    
        String statementId = method.//被代理的方法
                getDeclaringClass().//namespace
                        getName() + "." +
                method.getName();//methodName
        return sqlSession.selectOne(statementId, args[0]);
    }
}

Executor

package com.mybatis.executor;

import com.mybatis.entity.User;

import java.sql.*;

/**
 * @Authror PABLO
 * @Date 2022/4/26 21:26
 * @Desc 执行核心类
 */
public class Executor<T> {
    
    
    public T query(String sql, Object param) {
    
    

        User user = new User();
        Connection c = null;
        PreparedStatement p = null;
        ResultSet r = null;
        try {
    
    
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获得连接对象
            c = DriverManager.getConnection("jdbc:mysql://localhost:3306/****", "***", "***");
            //获得编译语句对象
            p = c.prepareStatement(sql);
            //在?占位符上设置参数
            p.setInt(1, (Integer) param);
            //语句对象查询获得结果集
            r = p.executeQuery();
            //遍历结果集
            while (r.next()) {
    
    
                Integer id = r.getInt("id");
                Integer age = r.getInt("age");
                String name = r.getString("name");
                user.setId(id);
                user.setAge(age);
                user.setName(name);
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            //释放资源
            try {
    
    
                r.close();
                p.close();
                c.close();
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        }

        return (T) user;
    }
}

mybatis.properties

com.mybatis.mapper.BlogMapper.getBlogById = select * from user where id = ?

在这里插入图片描述
V2版本新增了paramterHandler,resultHandler,StatementHandler,注解,plugin,cache等,就不往上贴了

原创不易,谢谢大家支持,如对你有帮助,请留下你的足迹
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/GiantCrocodile/article/details/124439797