我刚开始设计图案。我正在实现一个工具,它可以根据用户的需要连接到不同的数据库。这是我的代码结构。

在控制器中,我有API调用。下面我粘贴用于获取服务器中所有数据库的post APi调用
@PostMapping("/allDatabases")
public List<String> getDatabases(@RequestBody DatabaseModel db)
throws IOException, SQLException {
return migrationInterface.getAllDatabases(db);
}现在,我通过在服务包中调用接口中的方法来获得响应。但是,当数据库服务器发生变化时(例如: postgres、mysql),我必须使用不同的查询。
例如:
public class PostgresPreparedStatements {
public PreparedStatement getAllDbs(Connection con) throws SQLException {
return con.prepareStatement(
"SELECT datname FROM pg_database
WHERE datistemplate = false;");
}
}此查询在MySQL数据库中不起作用。因此,我将为不同的数据库保留不同的准备语句。我的想法是从控制器调用BaseAdapter并检查服务器类型,如下所示。
public class BaseAdapter {
public void checkServerType(String server) {
switch(server) {
case "postgres" :
// postgres functions
break;
case "mysql" :
// mysql functions
break;
default:
break;
}
}
}如果服务器是postgres,我想调用PostgresConnector.java。在Connector中,我想调用Facade来调用函数和相关查询。
知道怎么做吗?
请注意:目前我正在为postgres和MySQL实现这一功能,但是在将来,这将适用于任何数据库。
发布于 2022-11-08 17:08:14
当您想要添加新的行为(例如在您的情况下的新数据库)时,不使用适配器模式。适配器类的目标是允许其他类访问现有的功能。适配器将一个类的接口转换为另一个类可能使用的东西。
看起来,BaseAdapter有责任为不同的数据库选择SQL语句。我们可以解释这一责任,就像我们希望生成基于数据库的SQL查询一样。因此,看起来我们可以将这个switch语句替换为HashTable(Java)或Dictionary(C#)。而且这个HashTable(Java)或Dictionary(C#)可以是一个创建SQL查询的简单工厂。我们生成的SQL查询可以作为具体数据库的策略。
那么让我们开始研究代码吧。
看起来这是一个可以使用战略模式的地方:
策略模式是一种行为软件设计模式,允许在运行时选择算法。代码不是直接实现单一的算法,而是接收在一系列算法中使用的运行时指令。
让我通过C#展示一个例子。我很抱歉我不是Java人,但是我提供了关于代码在Java中的外观的评论。
我们需要有一些共同的行为,这些行为将在所有的战略中共享。在我们的例子中,它只是来自不同数据提供者的一个GetAllDbs()方法:
public interface IDatabaseStatement
{
IEnumerable<string> GetAllDbs();
}以及它的具体实现。这些是可交换的战略:
public class PostgresDatabaseStatement : IDatabaseStatement // implements in Java
{
public IEnumerable<string> GetAllDbs()
{
return new [] { "PostgresDatabaseStatement" };
}
}
public class MySQLDatabaseStatement : IDatabaseStatement // implements in Java
{
public IEnumerable<string> GetAllDbs()
{
return new[] { "MySQLDatabaseStatement" };
}
}
public class SqlServerDatabaseStatement : IDatabaseStatement // implements in Java
{
public IEnumerable<string> GetAllDbs()
{
return new[] { "SqlServerDatabaseStatement" };
}
}我们需要一个可以储存所有策略的地方。我们应该能从这家商店得到必要的策略。这是一个可以使用简单工厂的地方。简单的工厂不是工厂方法模式,也不是抽象工厂。
public enum DatabaseName
{
SqlServer, Postgres, MySql
}
public class DatabaseStatementFactory
{
private Dictionary<DatabaseName, IDatabaseStatement> _statementByDatabaseName
= new Dictionary<DatabaseName, IDatabaseStatement>()
{
{ DatabaseName.SqlServer, new SqlServerDatabaseStatement() },
{ DatabaseName.Postgres, new PostgresDatabaseStatement() },
{ DatabaseName.MySql, new MySQLDatabaseStatement() },
};
public IDatabaseStatement GetInstanceByType(DatabaseName databaseName) =>
_statementByDatabaseName[databaseName];
}然后,您可以更容易地获得所需存储的实例:
DatabaseStatementFactory databaseStatementFactory = new();
IDatabaseStatement databaseStatement = databaseStatementFactory
.GetInstanceByType(DatabaseName.MySql);
IEnumerable<string> allDatabases = databaseStatement.GetAllDbs(); // OUTPUT:
// MySQLDatabaseStatement 此设计与开放/封闭原则兼容。
https://stackoverflow.com/questions/74352647
复制相似问题