Java-18 深入浅出 MyBatis - 用到的设计模式 源码剖析 建造者模式、工厂模式

点一下关注吧!!!非常感谢!!持续更新!!!

大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html

目前已经更新到了:

  • MyBatis(正在更新)

基本介绍

MyBatis 中用到了如下的设计模式:

  • 建造者模式:SqlSessionFactoryBuilder、Environment
  • 工厂方法模式:SqlSessionFactory、TransactionFactory、LogFactory
  • 单例模式:ErrorContext、LogFactory
  • 代理模式:MapperProxy、ConnectionLogger
  • 组合模式:SqlNode、ChooseSqlNode
  • 模板方法方式:BaseExecutor、SimpleExecutor
  • 适配器模式:Log
  • 装饰者模式:Cache
  • 迭代起模式:PropertyTokenizer

具体如下图所示:

建造者模式

概念介绍

该模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。它属于创建类模式,一般来说,如果一个对象的构建比较复杂,超出了构造函数所能包含的范围,就可以使用工厂模式和 Builder 模式,相对于工厂模式会产出一个完整的产品,Builder 应用与更加复杂的对象构建,甚至只会构建产品的一个部分。

简单来说,就是通过简单的对象来一步一步构建复杂的对象。

简单案例

比如要组装一台电脑,我们需要:

  • 主机
  • 显示器
  • 键盘
  • 鼠标
  • 音响

此时我们 :

  • 目标类
  • 构建类
  • 依次创建部件
  • 组装结果

编写代码

WzkComputer

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WzkComputer {

    private String displayer;
    private String mouse;
    private String keyword;
    private String sound;

}

WzkComputerBuilder

java 复制代码
package icu.wzk.design.builder;

import javafx.util.Builder;

public class WzkComputerBuilder {

    private WzkComputer wzkComputer = new WzkComputer();

    public WzkComputerBuilder installDisplay(String displayName) {
        wzkComputer.setDisplayer(displayName);
        return this;
    }

    public WzkComputerBuilder installMouse(String mouseName) {
        wzkComputer.setMouse(mouseName);
        return this;
    }

    public WzkComputerBuilder installKeyboard(String keyboardName) {
        wzkComputer.setKeyword(keyboardName);
        return this;
    }

    public WzkComputerBuilder installSound(String soundName) {
        wzkComputer.setSound(soundName);
        return this;
    }

    public WzkComputer build() {
        return wzkComputer;
    }
}

WzkBuilderTest

java 复制代码
package icu.wzk.design.builder;

public class WzkBuilderTest {

    public static void main(String[] args) {
        WzkComputer wzkComputer = new WzkComputerBuilder()
                .installDisplay("三星")
                .installMouse("罗技")
                .installKeyboard("罗技")
                .installSound("破喇叭")
                .build();
        System.out.println(wzkComputer);
    }

}

测试运行

执行上述的 WzkBuilderTest,控制台输出结果如下:

shell 复制代码
WzkComputer(displayer=三星, mouse=罗技, keyword=罗技, sound=破喇叭)
Process finished with exit code 0

对应的截图如下所示:

MyBatis 的体现

SqlSessionFactory 的构建过程:MyBatis 的初始化工作非常复杂,不是只用了一个构造函数就能搞定的,所以使用了建造者模式,使用了大量的 Builder,进行分层构造,核心对象是 Configuration,使用了 XMLConfigBuilder 来进行构造。

在 MyBatis 环境的初始化过程中,SqlSessionFactoryBuilder 会调用 XMLConfigBuilder 读取所有的 MyBatisMapConfig.xmk 和 所有的 mapper.xml 文件。

java 复制代码
private void parseConfiguration(XNode root) {
    try {
        // Issue #117: Read properties first
        // Parse <properties /> tag
        propertiesElement(root.evalNode("properties"));

        // Parse <settings /> tag
        Properties settings = settingsAsProperties(root.evalNode("settings"));

        // Load custom VFS implementation class
        loadCustomVfs(settings);

        // Parse <typeAliases /> tag
        typeAliasesElement(root.evalNode("typeAliases"));

        // Parse <plugins /> tag
        pluginElement(root.evalNode("plugins"));

        // Parse <objectFactory /> tag
        objectFactoryElement(root.evalNode("objectFactory"));

        // Parse <objectWrapperFactory /> tag
        objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));

        // Parse <reflectorFactory /> tag
        reflectorFactoryElement(root.evalNode("reflectorFactory"));

        // Set <settings /> to Configuration property
        settingsElement(settings);

        // Issue #631: Read it after objectFactory and objectWrapperFactory
        // Parse <environments /> tag
        environmentsElement(root.evalNode("environments"));

        // Parse <databaseIdProvider /> tag
        databaseIdProviderElement(root.evalNode("databaseIdProvider"));
    } catch (Exception e) {
        // Handle exceptions
        e.printStackTrace();
    }
}

其次,在 XMLConfigBuilder 在构建 Configuration 对象时,也会调用 XMLMapperBuilder 用于读取 Mapper 文件,而 XMLMapperBuilder 会使用 XMLStatementBuilder 来读取和 build 所有 SQL 语句。

可以看到 SqlSessionFactoryBuilder 类根据不同的参数输入参数来构建,这么多的工作不是一个构造函数能够完成的。

工厂模式

概念介绍

在 MyBatis 中比如 SqlSessionFactory 使用的是工厂模式,该工厂没有那么复杂的逻辑,是一个简单工厂模式。

简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于创建型模式。

在简单工厂模式中,可以根据参数的不同返回不同类的实例,简单工厂模式专门定义了一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

简单案例

假设有一个电脑的生产商,之前能生产联想电脑,随着业务的发展,现在可以生成惠普电脑了。我们可以用简单工厂来实现。

编写代码

WzkComputer

java 复制代码
package icu.wzk.design.factory;

public abstract class WzkComputer {

    public abstract void start();

}

LenovoComputer

java 复制代码
package icu.wzk.design.factory;

import icu.wzk.design.factory.WzkComputer;

public class LenovoComputer extends WzkComputer {

    @Override
    public void start() {
        System.out.println("生产联想电脑");
    }
}

HpComputer

java 复制代码
package icu.wzk.design.factory;

public class HpComputer extends WzkComputer {

    @Override
    public void start() {
        System.out.println("生产惠普电脑");
    }
}

ComputerFactory

java 复制代码
package icu.wzk.design.factory;

import icu.wzk.design.factory.WzkComputer;

public class ComputerFactory {

    public static WzkComputer createComputer(String type) {
        switch (type) {
            case "lenovo":
                return new LenovoComputer();
            case "hp":
                return new HpComputer();
            default:
                throw new IllegalArgumentException("Invalid computer type: " + type);
        }
    }

}

WzkComputerTest

java 复制代码
package icu.wzk.design.factory;

public class WzkComputerTest {

    public static void main(String[] args) {
        ComputerFactory.createComputer("lenovo").start();
        ComputerFactory.createComputer("hp").start();
    }

}

测试运行

控制台输出的内容如下所示:

MyBatis 的体现

MyBatis 中执行 SQL 语句,获取 Mappers,管理事务的核心接口 SqlSession 的创建过程使用到了工厂模式。

可以看到有很多的重载方法,DefaultSqlSessionFactory 中有默认的工厂实现。

相关推荐
reddingtons2 小时前
【游戏宣发】PS “生成式扩展”流,30秒无损适配全渠道KV
游戏·设计模式·新媒体运营·prompt·aigc·教育电商·游戏美术
李慕婉学姐2 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆4 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin4 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20054 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉4 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国4 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882485 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈5 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_995 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc