工厂模式下的动态Mybatis-Plus

工厂模式下的动态Mybatis-Plus,第1张

   由于公司业务要求,项目要求同时支持区块链和传统关系型数据库,由于区块链的特殊特性,每次 *** 作的时候需要将表名作为参数进行接口调用,并且所有的方法都是抽出统一管理,所以在适配Mybatis-Plus的时候便遇到了不能将实现类和表名进行一一对应的情况,于是就有了下面的动态返回Mybatis-Plus的IService,返回的接口取决于传入的表名。
1、建立数据工厂选择器

建立DataBaseFactory类,该类用于根据配置文件中配置的数据存储方式来判断创建那种方式

public class DataBaseFactory {

    public static boolean isConnecting = false;

    public static IDataBaseCommon build() {
        IDataBaseCommon dataBaseCommon = null;
        // 这里是从配置文件中取出该应用需要使用那种数据存储模式
        String dataBaseType = (String) ProcessConfCom.getCommonYml("database.sqlImpl");
        // 区块链
        if (Constants.CONFIG_DATABASE_IMPL_CHAINSQL.equals(dataBaseType)) {
        	...
        }
        // 达梦数据库
        if (Constants.CONFIG_DATABASE_IMPL_DM.equals(dataBaseType)) {
            return new DmDbCommonImpl();
        }
        // mysql
        if (Constants.CONFIG_DATABASE_IMPL_MYSQL.equals(dataBaseType)) {
			// 同达梦数据库
        }
        return dataBaseCommon;
    }
}
2、达梦(mysql)数据库工厂

建立DmServerFactory类,该类管理所有需要处理的表对应的实现类,根据传入的表名进行选择返回那种IService的实现类

@Component
public class DmServerFactory {

    @Autowired
    ConfigCertOrgServer configCertOrgServer;

    @Autowired
    ConfigFisServer configFisServer;

    @Autowired
    ConfigSubServer configSubServer;

    @Autowired
    TransAttachServer transAttachServer;

    @Autowired
    TransInfoServer transInfoServer;

    @SuppressWarnings("rawtypes")
    public IService build(String tableName) {
        if (Constants.TABLE_CSJ_CONFIG_CERT_ORG.equals(tableName)) {
            return this.configCertOrgServer;
        }
        if (Constants.TABLE_CSJ_CONFIG_FIS.equals(tableName)) {
            return this.configFisServer;
        }
        if (Constants.TABLE_CSJ_CONFIG_SUB.equals(tableName)) {
            return this.configSubServer;
        }
        if (tableName.contains("trans_attach")) {
            return this.transAttachServer;
        }
        if (tableName.contains("trans_info")) {
            return this.transInfoServer;
        }
        return new ServiceImpl();
    }
}
3、具体实现类

这里就是通用的公共方法,只要传入表名,通过dmServerFactory.build();即可返回我们需要的接口,该接口调用的mybatis的方法就是我们需要 *** 作表的方法。

@Slf4j
@Service("DmDbCommonImpl")
public class DmDbCommonImpl implements IDataBaseCommon {
	
	@SuppressWarnings("rawtypes")
    @Override
    public void saveDataByTable(String tableName) {
    	// 由于工厂模式的原因,入口类的构造函数哪里不能进行自动注入交给spring进行管理,所以这里通过应用上下文返回
        DmServerFactory dmServerFactory = ApplicationContextProvider.getBean(DmServerFactory.class);
        JSONObject jsonObject = new JSONObject();
        IService iService = dmServerFactory.build(tableName);
        // 这里返回的IService就可以进行我们熟悉的 *** 作了,并且所 *** 作的就是传入的tableName
        boolean b = iService.saveBatch(saveList);
        ...
    }
}
4、ApplicationContextProvider类

通过应用上下文获取实例的方法,也分享一下吧

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * 普通类中无法注入service问题解决方案
 */
@Component
public class ApplicationContextProvider implements ApplicationContextAware {

    /**
     * 上下文对象实例
     */
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextProvider.applicationContext = applicationContext;
    }

    /**
     * 获取applicationContext
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param 
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param 
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

}
5、工厂模式入口

利用构造函数进行创建,因为build()方法会的实现类是不确定的,所以这里不能交给spring进行管理(或许是我没搞明白),启动的时候会报出注入的对象含有多个实现类,无法确定需要注入的是哪个。

@Slf4j
@SuppressWarnings("rawtypes")
public class UploadAttachAsyncJob {

    private IDataBaseCommon dataBaseCommon;
	
	// 构造函数,类加载时候会触发该函数,调用DataBaseFactory.build()
	 public UploadAttachAsyncJob(IOpFileUploadCommon opFileCommon) {
        this.dataBaseCommon = DataBaseFactory.build();
     }
	
	// 这里就可以根据传入的表名直接调用通用方法
	 public void save(String tableName){
		dataBaseCommon.saveDataByTable(tableName);
	}
}

不足之处,多多指教~

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/2991204.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-23
下一篇 2022-09-23

发表评论

登录后才能评论

评论列表(0条)

保存