MyBatis源码分析01 ---- 通过代理确定Mapper接口实现类过程

MyBatis俩种实现方式:

1:基于Mapper接口的使用方式:

InputStream inputStream = Resources.getResourceAsStream("myBatis_config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();

User user = new User();
user.setUser_name("abd");
user.setUser_id(99);
user.setPassword("12345");

UserDao userDao = session.getMapper(UserDao.class);
userDao.login(user);

2:直接使用SqlSession对象来执行SQL语句,也是更底层和更早期的MyBatis使用方式。

InputStream inputStream = Resources.getResourceAsStream("myBatis_config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();

User user = new User();
user.setUser_name("abd");
user.setUser_id(99);
user.setPassword("12345");

//另一种更底层也是更早期的执行方式
//前面一个参数是namespace(Mapper接口接口类全限定名).标签id名,后面一个参数是SQL执行所需参数
session.insert("com.example.spring_suns.Dao.UserDao.login",user);

对俩种实现方式进行分析:

事实上,第一种执行方式就是使用代理模式对第二种执行方式的封装(为了提升代码的可读性和可维护性)。

代理模式三种应用场景:

        1:给原始对象增加额外功能

        2:远程代理(网络通信,输出传输(RPC,Dubbo))

        3:无中生有,看不见类文件,却能进行使用(比如MyBatis中使用Mapper接口的实现类)

我们在使用Mapper接口时,并没有对其进行实现,却能进行使用,调用其方法,就是MyBatis内部通过代理调用了SqlSession封装的数据库操作。

具体代理过程:

MyBatis代理Mapper接口实现主要通过俩个类:MapperProxyFactory和MapperProxy

MapperProxyFactory:

MapperProxyFactory调用JDK动态代理的Proxy.newProxyInstance方法:

MapperProxy继承Invocation实现Invoke方法,Invoke方法调用上述MyBatis第二种实现方式的MapperMethod的各种方法:

查看其内部调用的invoke方法:

执行SqlSession的对应操作(调用上述第二种MyBatis实现方式)

由此印证了MyBatis使用代理进行封装的整个底层逻辑

自定义实现上述通过代理封装sqlSession数据库操作的过程:

public class SelfMapperProxy {
    @Test
    void myMapperProxy() throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("myBatis_config.xml");
        SqlSessionFactory sqlSessionFactory = new 
        SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();

        Class[] classes = new Class[]{UserDao.class};
//动态代理
        UserDao userdao = (UserDao)Proxy.newProxyInstance(SelfMapperProxy.class.getClassLoader()
                ,classes,new SelfHandler(session,UserDao.class));

//通过Mapper接口调用对应方法
        User user = new User();
        user.setUser_name("abd");
        user.setUser_id(99);
        user.setPassword("12345");
        userdao.login(user);
    }
}
public class SelfHandler implements InvocationHandler {
    private SqlSession session;
    private Class daoClass;
    public SelfHandler(SqlSession session, Class daoClass) {
        this.session = session;
        this.daoClass = daoClass;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //调用SqlSession数据库操作
        return session.insert(daoClass.getName() + "." + method.getName());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值