mybatis源码中的设计模式

装饰器设计模式

下面通过一个小例子描述了装饰器的概念

package com.example.zhuangshiqi;

/**
 * @author Tao
 * @date 2022/7/10 23:04
 * @desciption: 装饰器设计模式
 */
public class Decorator {

    //房子
    public interface House{
        //卧室
        void bedroom();
    }
    //小房子
    public static class SmallHouse implements House{
        public SmallHouse(){

        }

        @Override
        public void bedroom() {
            System.out.println("小卧室");
        }
    }
    //大房子
    public static class BigHouse implements House{
        public BigHouse(){

        }

        @Override
        public void bedroom() {
            System.out.println("大卧室");
        }
    }

    //给房子按空调房子
    public static class ConditionerHouse implements House{
        //装饰者模式,维护一个对象。交给指定对象去实现
        private final House delegate;

        public ConditionerHouse(House delegate) {
            this.delegate = delegate;
        }

        @Override
        public void bedroom() {
            delegate.bedroom();
            buyAirConditioner();
        }

        public void buyAirConditioner(){
            System.out.println("购买空调");
        }

    }

    public static void main(String[] args) {
        //给房子装空调
        House house = roomSelection(true,"有钱");
        house.bedroom();
    }

    //选房
    public static House roomSelection(Boolean b,String status){
        House house;
        if (status.equals("没钱")){
            house = new SmallHouse();
        }else {
            house = new BigHouse();
        }
        //天气太热是否安装空调
        if (b){
            house = new ConditionerHouse(house);
        }
       return house;
    }
}

在mybatis 的Executor中体现
在这里插入图片描述
在这里插入图片描述
判断了在创建Executor的时候是否开启了缓存,如果开启了就利用缓存执行器装饰前面三种执行器。

模版设计模式

还是利用执行器举例 uml图
在这里插入图片描述
在抽象类里面出现下面这种抽象方法没有方法体的方法,这写称为模版方法
在这里插入图片描述
继承基础的执行器
在这里插入图片描述
在这里插入图片描述
总结: 这种将具体的实现方式交给 子类去实现 父类本身只是实现基本的方法的设计模式 称为 模板的设计模式

代理设计模式

先来个测试类,只要看过mybatis源码的都应该不陌生。

/**
 * @Auther: xiaotao
 * @Date: 2020/09/02/23:40
 * @Description:
 */
public class Test001 {

    @Test
    public void testA() throws Exception{
        //加载配置文件
        Reader resourceAsReader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsReader);

        //获取一个事物
        //SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();


        //获取接口
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User userById = mapper.queryById(1);

        System.out.println("查询出来的对象是"+userById);

        sqlSession.commit();
        sqlSession.close();
    }
}

是否有过这样的疑问?
mybatis明明就只写了一个简单的接口,如下面的UserMapper 。在使用的时候就能把数据从数据库中查询出来?

/**
 * @Auther: xiaotao
 * @Date: 2020/09/03/0:26
 * @Description:
 */
public interface UserMapper {

    User queryById(Integer id);

//    @Select("select * from t_user where id = #{id}")
//    User selectById(int id);

    @Select("select * from user")
    List<User> userPage(Page page);
}

解惑:使用了JDK动态代理,生成了代理类。
在这里插入图片描述
2:传入的是一个接口
1:返回的却是一个对象。
3:Proxy 关键字动态代理。

是整么实现的?

请下载源码,在上面图片处打断点,可以追一下流程。
描述一下大致流程。
mybatis 在项目启动的时候就会扫描所有的xml文件,根据xml中的标签,解析成一个一个的MappedStatement对象,放入Configuration 类的 mappedStatements 属性里面

  //存放xml解析后的数据存放地方(描述xml的 增删改查 每一个节点放了一个在里面)。key为UserMapper.queryById
  protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection")
      .conflictMessageProducer((savedValue, targetValue) ->
          ". please check " + savedValue.getResource() + " and " + targetValue.getResource());

这个map 的结构
在这里插入图片描述

到这一步。就会想。上面明明说的是 mapper接口为啥就能查出数据。那跟mybatis 启动的时候解析这些参数放入configuration中有什么关系呢?
有很大的关系。你想生成的代理类中的 sql,sqlSession,等 信息哪里来的?
肯定就是从这个map中取的晒。不然后面整么执行sql。整么处理数据?
下面就是对生成的代理类进行参数组装。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:就是把configuration中存的mappedStatements 赋值给代理对象,让他去执行mybatis的代码

责任链设计模式

mybatis的插件
项目启动将所有的插件放入集合中。每次执行sql语句的时候遍历插件集合。执行插件集合中具体的拦截器。实现数据的处理和实现。
分页插件 拦截器实现。
spring和mybatis和pageHelper整合的原理下次在记录一下

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

单线程bug

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

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

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

打赏作者

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

抵扣说明:

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

余额充值