• 手写MyBatis,纯手工打造开源框架(第四篇:决胜千里)- 第272篇


    说明

    MyBatis版本:3.5.1

    相关历史文章(阅读本文之前,您可能需要先看下之前的系列

    Spring Boot MyBatis最全教程:你值得拥有
    MyBatis能脱离Spring吗一图纵览MyBatis的工作原理从源码看MyBatis,竟如此简单MyBatis的Mapper是什么`垃圾` 

    手写MyBatis,纯手工打造开源框架(第一篇:风云再起) 

    手写MyBatis,纯手工打造开源框架(第二篇:君临天下) 

    手写MyBatis,纯手工打造开源框架(第三篇:运筹帷幄) 

     

    前言

           运筹帷幄之中,决胜千里之外,是该做个了结了,把你的家伙掏出来,上刺刀。

           上一篇已经能够使用SqlSession进行查询返回结果了。这一篇我们就是加入瑞士军刀Mapper。

     

    一、分析

           在SqlSession会提供getMapper的方法,在DefaultSqlSession会使用Proxy实例化一个MapperProxy代理,而MapperProxy代理会获取SqlSession,在这里进行Sql的操作,然后结果。

     

    二、编码

    2.1 MapperProxy

           MapperProxy是mapper最终执行的核心:

    package com.kfit.mybatis.session.impl;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.util.Collection;
    
    import com.kfit.mybatis.session.SqlSession;
    
    public class MapperProxy implements InvocationHandler{
        private SqlSession sqlSession;
        public MapperProxy(SqlSession sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            String statement = method.getDeclaringClass().getName()+"."+method.getName();
            //isAssignableFrom方法是判断是否为某个类的父类
            if(Collection.class.isAssignableFrom(method.getReturnType())) {
                //返回值是集合的话,那么是调用selectList
                return sqlSession.selectList(statement,null==args?null:args[0]);
            }else {
                return sqlSession.selectOne(statement,null==args?null:args[0]);
            }
        }
    
    }
     

    说明:

    (1)由于MapperProxy是一个代理类,所以需要实现接口InvocationHandler的Invoke方法。

    (2)在Invoke方法中直接使用SqlSession进行执行,那么主要的核心就是要判断具体执行什么方法,这里现在通过返回值是否是集合来判断是否是执行selectOne还是SelectList。

     

    2.2 SqlSession

           在SqlSession中添加getMapper方法:

    public interface SqlSession {
         <T> T selectOne(String statement, Object parameter);
         <E> List<E> selectList(String statement);
         <E> List<E> selectList(String statement, Object parameter);
         <T> T getMapper(Class<T> type);
    }
     

           在DefaultSqlSession中进行实现getMapper方法:

     
       @SuppressWarnings("unchecked")
        public <T> T getMapper(Class<T> type) {
            T newProxyInstance = (T) Proxy.newProxyInstance(type.getClassLoader(),new Class[]{type},new MapperProxy(this));
            return newProxyInstance;
        }
     

     

    2.3 测试下

           好了写段代码测试下吧:

    public static void main(String[] args) {
            String resource = "mybatis-config.xml";
            InputStream inputStream = App.class.getClassLoader().getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            System.out.println(sqlSessionFactory);
            System.out.println(sqlSessionFactory.getConfiguration().getJdbcProperties().getUrl());
    
            SqlSession sqlSession = sqlSessionFactory.openSession();
    
    
            Demo demo = null;
            List<Demo> demos = null;
    
    
            //使用Mapper
            DemoMapper demoMapper = sqlSession.getMapper(DemoMapper.class);
            demo = demoMapper.getById(1);
            System.out.println(demo);
            demos = demoMapper.getAll();
            System.out.println(demos);
        }
     

    运行看下结果:

    Demo [id=1,name=张三1]

    [Demo [id=1, name=张三1], Demo [id=9, name=张三], Demo [id=10, name=张三], Demo [id=11, name=张三], Demo [id=12, name=张三], Demo [id=13, name=张三]]

           很明显执行的结果和直接使用SqlSession调用的结果是一样的。

            好了有关手写MyBatis的文章就先到此告一段落了,通过手写mybatis,想必大家对于MyBatis的认知又高了一个等级了。

    我就是我,是颜色不一样的烟火。
    我就是我,是与众不同的小苹果。

    à悟空学院:http://t.cn/Rg3fKJD

    学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!

    SpringBoot视频:http://t.cn/R3QepWG

    Spring Cloud视频:http://t.cn/R3QeRZc

    SpringBoot Shiro视频:http://t.cn/R3QDMbh

    SpringBoot交流平台:http://t.cn/R3QDhU0

    SpringData和JPA视频:http://t.cn/R1pSojf

    SpringSecurity5.0视频:http://t.cn/EwlLjHh

    Sharding-JDBC分库分表实战:http://t.cn/E4lpD6e

  • 相关阅读:
    二叉树的层序遍历-102
    剑指offer 06 从尾到头打印链表
    替换空格:剑指offer05
    面试题16.11.跳水板----leetcode
    JVM——垃圾回收
    新生代Eden与两个Survivor区的解释
    JVM 1.8 永久代---元空间 的变动
    Git拉取项目避坑
    python-装饰器
    python-Queue
  • 原文地址:https://www.cnblogs.com/springboot-wuqian/p/11430906.html
Copyright © 2020-2023  润新知