Mybatis datasource 包里的工厂模式

本文解析了工厂模式在数据源创建中的应用,通过UnpooledDataSourceFactory和PooledDataSourceFactory实例展示了如何解耦对象创建与使用,遵循单一职责和开闭原则。

结构图

在这里插入图片描述
如图所示,UnpooledDataSourceFactory 生产 UnpooledDataSource,PooledDataSourceFactory 生产 PooledDataSource;UnpooledDataSourceFactoryPooledDataSourceFactory 实现了 DataSourceFactory 接口,UnpooledDataSource 和 PooledDataSource 实现了(JDK的)DataSource 接口。这就是一种工厂模式。

在这里插入图片描述

代码展示

在这里插入图片描述
在这里插入图片描述

工厂模式的好处

创建对象常用的三种方式:

  1. 使用new关键字直接创建对象
  2. 通过反射机制创建对象
  3. 通过工厂类创建对象

前两种方式的缺点:

  1. 对象创建和对象使用的职责耦合在一起,违反单一职责原则
  2. 当业务扩展时,必须修改代业务代码,违反开闭原则

通过工厂类创建对象的好处:

  1. 把对象的创建和使用的过程分开,对象创建和对象使用的职责解耦
  2. 如果创建对象的过程很复杂,创建过程统一到工厂里管理,既减少了重复代码,也方便以后对创
    过程的修改维护
  3. 当业务扩展时,只需要增加工厂子类,符合开闭原则
<think>好的,我现在要回答用户关于如何将MyBatis-Plus与工厂模式结合使用的问题。首先,我需要理解用户的需求。用户可能在使用MyBatis-Plus时,希望引入工厂模式来管理对象的创建,以提高代码的灵活性和可维护性。接下来,我需要回顾工厂模式的基本概念以及MyBatis-Plus的相关特性,确保自己正确掌握相关知识。 工厂模式主要分为简单工厂工厂方法和抽象工厂。用户提到的可能是工厂方法或抽象工厂,但根据引用[1]和[2],用户可能更关注如何避免修改现有代码来扩展创建过程,这更符合工厂方法或抽象工厂的特点。比如,引用[2]提到简单工厂违背开闭原则,而抽象工厂可以创建一组相关产品。结合MyBatis-Plus,可能需要根据不同的数据源或实体类型动态创建Mapper或Service实例。 接下来,我需要考虑MyBatis-Plus的组件,比如BaseMapper、ServiceImpl等。用户可能希望使用工厂来生成这些组件的实例,而不是直接new出来。例如,针对不同的UserDao或ProductDao,通过工厂来创建对应的Service实现,这样在新增类型时不需要修改工厂类,只需扩展。 然后,我需要构思一个具体的示例。例如,定义一个Service工厂接口,让不同的具体工厂实现该接口,生成对应的Service实例。比如UserServiceFactory和ProductServiceFactory分别创建UserServiceImpl和ProductServiceImpl。这样符合工厂方法模式,每个工厂负责一个产品。或者使用抽象工厂来生成一组相关的DAO和Service。 同时,要注意到MyBatis-Plus本身已经通过泛型和基类简化了DAO和Service的创建,比如BaseMapper和ServiceImpl。工厂模式可能需要在这些基础上进行封装。例如,通过工厂根据不同的实体类型动态创建对应的Service类,这样在业务层可以通过工厂获取所需的Service实例,而无需关心具体实现。 还要考虑如何集成Spring的依赖注入,因为MyBatis-Plus通常与Spring一起使用。可能需要将工厂类声明为Spring的Bean,利用Spring的容器来管理实例的创建和依赖关系。例如,使用@Configuration和@Bean来配置工厂,或者通过@Component注解让工厂类被自动扫描。 在代码示例部分,需要展示如何定义工厂接口、具体工厂实现,以及如何在Service层使用工厂获取实例。同时,要结合MyBatis-Plus的BaseMapper和ServiceImpl,展示如何将工厂模式应用于实际的数据访问层和服务层。 另外,需要验证是否符合开闭原则,即新增实体类型时是否只需添加新的工厂类而不修改已有代码。例如,当新增一个Product实体时,只需创建ProductServiceFactory和ProductServiceImpl,而不需要修改原有的User相关代码。这样可以确保系统的扩展性。 还要参考用户提供的引用内容,特别是引用[1]和[2]关于工厂模式与抽象工厂的区别,确保示例代码正确应用了相应的设计模式,避免误用简单工厂导致的问题。例如,避免在工厂类中使用条件判断来选择创建哪种实例,而是通过不同的工厂实现来分离创建逻辑。 最后,需要总结这种结合使用的优势,如提高代码的可维护性、扩展性,以及如何符合设计模式的原则。同时,指出可能的注意事项,比如工厂类的管理、与Spring框架的整合细节等,确保用户在实际应用中能够顺利实施。</think>### MyBatis-Plus与工厂模式结合的实现方法 #### 1. 工厂模式MyBatis-Plus中的应用场景 工厂模式可用于**动态创建Mapper或Service实例**,例如根据不同的实体类型生成对应的DAO或Service对象。结合MyBatis-Plus的`BaseMapper`和`ServiceImpl`,可通过工厂模式实现以下目标: - 统一管理Mapper/Service实例的创建过程[^2] - 支持多数据源或多租户场景下的对象动态生成 - 符合开闭原则,扩展时无需修改原有工厂逻辑[^1] --- #### 2. 实现示例:基于工厂模式的Service层封装 ##### 2.1 定义基础接口 ```java // 通用Service接口 public interface BaseService<T> { T getById(Long id); boolean saveEntity(T entity); } // 工厂接口 public interface ServiceFactory<T> { BaseService<T> createService(); } ``` ##### 2.2 实现MyBatis-Plus Service ```java // 具体Service实现 public class UserServiceImpl extends ServiceImpl<UserDao, User> implements BaseService<User> { // 继承默认CRUD操作 // 可添加自定义方法 } public class ProductServiceImpl extends ServiceImpl<ProductDao, Product> implements BaseService<Product> { // 产品相关服务实现 } ``` ##### 2.3 创建具体工厂类 ```java // 用户服务工厂 @Component public class UserServiceFactory implements ServiceFactory<User> { @Autowired private UserDao userDao; @Override public BaseService<User> createService() { return new UserServiceImpl() {{ setBaseMapper(userDao); }}; } } // 产品服务工厂 @Component public class ProductServiceFactory implements ServiceFactory<Product> { @Autowired private ProductDao productDao; @Override public BaseService<Product> createService() { return new ProductServiceImpl() {{ setBaseMapper(productDao); }}; } } ``` ##### 2.4 使用工厂客户端 ```java @Service public class BusinessService { private final Map<Class<?>, ServiceFactory<?>> factories; @Autowired public BusinessService(List<ServiceFactory<?>> factoryList) { factories = factoryList.stream() .collect(Collectors.toMap(f -> getGenericType(f.getClass()), f -> f)); } public <T> BaseService<T> getService(Class<T> entityType) { ServiceFactory<T> factory = (ServiceFactory<T>) factories.get(entityType); return factory != null ? factory.createService() : null; } private Class<?> getGenericType(Class<?> clazz) { // 通过反射获取泛型类型 return (Class<?>) ((ParameterizedType) clazz.getGenericInterfaces()[0]) .getActualTypeArguments()[0]; } } ``` --- #### 3. 集成Spring Boot配置 ```java @Configuration public class MybatisPlusFactoryConfig { @Bean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); return sessionFactory.getObject(); } } ``` --- #### 4. 使用示例 ```java @RestController public class UserController { @Autowired private BusinessService businessService; @GetMapping("/user/{id}") public User getUser(@PathVariable Long id) { BaseService<User> userService = businessService.getService(User.class); return userService.getById(id); } } ``` --- #### 5. 优势分析 1. **解耦创建逻辑**:对象创建与使用分离,符合单一职责原则 2. **扩展性强**:新增实体类型时只需添加新工厂类,无需修改现有代码[^2] 3. **统一管理**:集中控制MyBatis-Plus组件的初始化过程 4. **多态支持**:客户端通过统一接口访问不同实体服务 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值