org.springframework.beans及org.springframework.context这两个包是Spring IoC容器的基础,
其中重要的类有BeanFactory,BeanFactory是IoC容器的核心接口,其职责包括:实例化、定位、配置应用程序中的
对象及建立这些对象间的依赖关系。
ApplicationContext作为BeanFactory的子类,在Bean管理的功能上得到了很大的增强,也更易于与Spring AOP集成使用。
今天我们要讨论的并不是BeanFactory或者ApplicationContext的实现原理,而是对ApplicationContext的一种实际应用方式。
在实际工作中,我们经常会遇到一个接口及多个实现类的情况,并且在不同的条件下会使用不同的实现类。我们可以借助ApplicationContext的getBeansOfType来实现我们需要的结果
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
问题:执行sql语句,却会有多种数据库,选择相对应的数据库.通过多个数据库类型实现类。
一个接口类:
/**
* 操作数据库的接口类
* @author chenp
*/
public interface DbCaller {
/**
* 执行sql语句
* @param chkUpdateScript //sql语句内容类
* @param chkDatabase //数据库信息类
* @return AjaxResult
*/
AjaxResult executeSqlInvoke(ChkUpdateScript chkUpdateScript, ChkDatabase chkDatabase) throws Exception;
}
通过一个抽象类实现该接口:
/**
* 操作数据库抽象类
* @Date 2022-07-11
*/
public abstract class AbstractDbCaller implements DbCaller{
/**
* 执行sql语句
* @param chkUpdateScript
* @param chkDatabase
* @return AjaxResult
*/
@Override
public AjaxResult executeSqlInvoke(ChkUpdateScript chkUpdateScript, ChkDatabase chkDatabase) throws Exception {
return executeSql(chkUpdateScript, chkDatabase);
}
/**
* 执行sql语句
* @param chkUpdateScript
* @param chkDatabase
* @return AjaxResult
*/
protected abstract AjaxResult executeSql(ChkUpdateScript chkUpdateScript, ChkDatabase chkDatabase) throws Exception;
}
再由一个实现类继承该抽象类(mysql实现类):(其中调用了一个加密工具类和一个jdbc工具类用于执行sql语句)
/**
* mysql数据库执行sql语句
**/
@Component("MYSQL_CALLER")
public class MysqlCaller extends AbstractDbCaller{
/**
* 执行sql语句
* @param chkUpdateScript
* @param chkDatabase
* @return AjaxResult
*/
@Override
@Transactional(rollbackFor = Exception.class)
protected AjaxResult executeSql(ChkUpdateScript chkUpdateScript, ChkDatabase chkDatabase) throws Exception {
//获取用户名
String username =chkDatabase.getUsername();
//获取密码
String password = EncryptUtil.getInstance().DESdecode(chkDatabase.getPassword());
//数据库url地址
String dataSourceUrl = chkDatabase.getDataSourceUrl();
//获取驱动类
String databaseTypeDriver = chkDatabase.getDriver();
//获取sql语句
String sql = chkUpdateScript.getScriptContent();
//将sql脚本文件按分号分割开来
String[] sqlStatement = sql.split(";");
//获取数据库名称
String databaseName = chkDatabase.getDatabaseName();
//uuid
String uuid = "uuid";
//执行sql语句
for (int i = 0; i<sqlStatement.length; i++){
Boolean aBoolean = JDBCUtils.getInstance().executeSql(databaseTypeDriver, dataSourceUrl, username, password, sqlStatement[i], uuid);
if(!aBoolean == true){
String msg = sql + "SQL语句执行失败,执行数据库为" + databaseName;
return AjaxResult.error(msg);
}
}
String msg = sql + "SQL语句执行成功,执行数据库为" + databaseName;
return AjaxResult.success(msg);
}
}
实现类可多写,如再写也该Orcher数据库继承该抽象类
/**
* mysql数据库执行sql语句
**/
@Component("Orcher_CALLER")
public class OrcherCaller extends AbstractDbCaller{
/**
* 执行sql语句
* @param chkUpdateScript
* @param chkDatabase
* @return AjaxResult
*/
@Override
@Transactional(rollbackFor = Exception.class)
protected AjaxResult executeSql(ChkUpdateScript chkUpdateScript, ChkDatabase chkDatabase) throws Exception {
}
}
关键在于如何调用不同的实现类,
也就是通过这个注解@Component("MYSQL_CALLER")来识别不同的bean
调用方法:
//获取数据库类型信息 ===mysql
String databaseType = chkDatabase.getDatabaseType();
//数据库类型接口 ====MYSQL_CALLER
String invokeName = databaseType.toUpperCase() + CommonConstant.DATASOURCE_AUTOWIRED_NAME;
//获取相应的bean ====MYSQL_CALLER
DbCaller dbCaller = SpringUtils.getBean(invokeName);