去皮卡多 发表于 2024-8-31 00:35:16

MyBatis中使用的设计模式具体剖析

一、单例模式

1. 使用位置



[*]SqlSessionFactory:用于创建SqlSession对象的工厂。
2. 设计原因



[*]节流资源:SqlSessionFactory负责管理数据库毗连,假如每次都创建新的实例,会浪费很多资源。
3. 功能实现



[*]全局访问:在整个应用中只使用一个SqlSessionFactory实例,方便同一管理。
4. 简朴例子

想象一下一个“打印机”,只有一个打印机可以为整个公司打印文件。每个人都可以使用这个打印机,而不是每个人都买一个。
public class SqlSessionFactorySingleton {
    private static SqlSessionFactory instance; // 存储SqlSessionFactory的唯一实例

    private SqlSessionFactorySingleton() {} // 私有构造函数,防止外部直接创建实例

    public static SqlSessionFactory getInstance() {
      if (instance == null) { // 如果实例不存在
            synchronized (SqlSessionFactorySingleton.class) { // 加锁,确保线程安全
                if (instance == null) { // 再次检查实例
                  instance = new SqlSessionFactoryBuilder().build(inputStream); // 创建实例
                }
            }
      }
      return instance; // 返回单例实例
    }
} 二、工厂模式

1. 使用位置



[*]SqlSessionFactory:用于创建SqlSession对象的具体工厂。
2. 设计原因



[*]解耦合:将对象的创建和使用分开,方便更换实现。
3. 功能实现



[*]灵活性:可以在不修改代码的情况下更换SqlSession的实现。
4. 简朴例子

想象你要买车,你不需要关心每个车的制造过程,只需要一个“车商”给你提供车就可以了。
public interface SqlSessionFactory {
    SqlSession openSession(); // 定义一个方法,用于创建SqlSession
}

public class DefaultSqlSessionFactory implements SqlSessionFactory {
    @Override
    public SqlSession openSession() {
      return new DefaultSqlSession(); // 创建并返回DefaultSqlSession的实例
    }
} 三、代理模式

1. 使用位置



[*]MapperProxy:拦截对Mapper接口方法的调用。
2. 设计原因



[*]动态代理:在运行时为Mapper接口生成实现类,避免重复代码。
3. 功能实现



[*]方法拦截:可以在调用Mapper方法时添加额外的处置惩罚,比如记载日志。
4. 简朴例子

想象你有一个“秘书”,每当你需要做一件事时,秘书会帮你处置惩罚一些细节,比如安排时间和准备材料。
public class MapperProxy<T> implements InvocationHandler {
    private final SqlSession sqlSession; // 用于执行SQL的SqlSession实例
    private final Class<T> mapperInterface; // Mapper接口的Class对象

    public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface) {
      this.sqlSession = sqlSession; // 初始化SqlSession
      this.mapperInterface = mapperInterface; // 初始化Mapper接口
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      // 生成SQL语句的ID,并调用SqlSession执行SQL
      return sqlSession.selectOne(getStatement(method), args); // 执行SQL
    }

    private String getStatement(Method method) {
      // 生成SQL语句ID,格式为"Mapper接口名.方法名"
      return mapperInterface.getName() + "." + method.getName();
    }
} 四、模板方法模式

1. 使用位置



[*]SqlSessionTemplate:提供一些基本的数据库操作方法。
2. 设计原因



[*]代码复用:将一些共同的操作封装在一个地方,避免重复代码。
3. 功能实现



[*]简化操作:开辟者可以使用SqlSessionTemplate提供的基本操作,而不需要重复编写雷同的代码。
4. 简朴例子

想象你有一个“食谱”,每次做饭时,你只需要按照食谱的步调去做,而不需要每次都重新想一遍。
public class SqlSessionTemplate implements SqlSession {
    private final SqlSessionFactory sqlSessionFactory; // SqlSessionFactory实例

    // 构造函数,接受SqlSessionFactory作为参数
    public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
      this.sqlSessionFactory = sqlSessionFactory; // 初始化SqlSessionFactory
    }

    @Override
    public <T> T selectOne(String statement, Object parameter) {
      // 执行查询操作,返回单个结果
      // 这里可以写具体的查询逻辑
      return null; // 这里是示例,实际实现中会返回查询结果
    }

    // 其他数据库操作方法可以在这里实现
} 五、观察者模式

1. 使用位置



[*]二级缓存失效机制:当数据库中的数据发生变化时,相关的缓存会被清除。
2. 设计原因



[*]数据一致性:确保多个缓存能够自动响应数据库的变化。
3. 功能实现



[*]自动更新:当数据发生变化时,相关的缓存会被自动清除,避免数据过时的题目。
4. 简朴例子

想象一个“关照体系”,当一个人改变了他的接洽方式,所有相关的人都会收到关照,确保他们的信息是最新的。
观察者接口

public interface Observer {
    void update(String message); // 更新方法,接受通知
} 具体观察者(缓存)

public class Cache implements Observer {
    private String cacheData; // 缓存的数据

    @Override
    public void update(String message) {
      // 当接收到更新通知时,清空缓存
      System.out.println("Cache is being cleared due to: " + message);
      cacheData = null; // 清空缓存
    }

    // 模拟更新缓存数据的方法
    public void setCacheData(String data) {
      this.cacheData = data;
    }

    public String getCacheData() {
      return cacheData; // 返回缓存的数据
    }
} 主题(数据库)

import java.util.ArrayList;
import java.util.List;

public class Database {
    private List<Observer> observers = new ArrayList<>(); // 存储观察者

    // 添加观察者
    public void addObserver(Observer observer) {
      observers.add(observer);
    }

    // 移除观察者
    public void removeObserver(Observer observer) {
      observers.remove(observer);
    }

    // 更新数据库的方法
    public void updateData(String newData) {
      // 模拟数据更新
      System.out.println("Database is updated with new data: " + newData);
      notifyObservers("Data updated to: " + newData); // 通知所有观察者
    }

    // 通知所有观察者
    private void notifyObservers(String message) {
      for (Observer observer : observers) {
            observer.update(message); // 调用观察者的更新方法
      }
    }
} 主程序

public class Main {
    public static void main(String[] args) {
      Database database = new Database(); // 创建数据库实例
      Cache cache = new Cache(); // 创建缓存实例

      database.addObserver(cache); // 将缓存添加为观察者

      // 模拟数据更新
      database.updateData("New User Data"); // 更新数据库数据
    }
} 6. 运行结果

当运行上面的代码时,会看到如下输出:
Database is updated with new data: New User Data
Cache is being cleared due to: Data updated to: New User Data

[*]Observer接口:界说了一个更新方法,供具体观察者实现。
[*]Cache类:实现了Observer接口,当数据库数据更新时,它会清空自己的缓存。
[*]Database类:作为主题,负责管理观察者,并在数据更新时关照它们。
[*]Main类:作为主程序,创建数据库和缓存的实例,并模拟数据更新。
六、策略模式

1. 使用位置



[*]插件机制:MyBatis支持通过插件机制来增强功能。
2. 设计原因



[*]灵活性和可扩展性:可以在运行时选择不同的插件策略。
3. 功能实现



[*]功能增强:通过不同的插件,可以实现日志记载、性能监控等功能,而不需要修改MyBatis的核心代码。
4. 简朴例子

想象你有一个“工具箱”,你可以根据需要选择不同的工具来完成特定的任务,比如锤子、螺丝刀等。


public class MyPlugin implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
      // 在调用目标方法前,可以进行一些处理
      System.out.println("Before executing: " + invocation.getMethod().getName());
      // 调用原方法并返回结果
      return invocation.proceed(); // 执行目标方法
    }

    @Override
    public Object plugin(Object target) {
      // 将目标对象包装成插件
      return Plugin.wrap(target, this); // 返回插件对象
    }

    @Override
    public void setProperties(Properties properties) {
      // 设置插件的属性
    }
} 七、总结



[*]单例模式:确保一个类只有一个实例,节流资源,方便管理。
[*]工厂模式:将对象创建与使用分开,增长灵活性。
[*]代理模式:动态生成接口的实现类,方便扩展功能。
[*]模板方法模式:封装公共逻辑,简化操作。
[*]观察者模式:保持数据一致性,自动更新缓存。
[*]策略模式:实现功能扩展,允许灵活选择不同的策略。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: MyBatis中使用的设计模式具体剖析