一般情况下,我们的SQL语句都写在代码里,虽然耦合度高了,但是方便。然而,如果突然有一天,需求变了,换数据库,然后我们用新的数据库,一调试,发现有些SQL语句不执行,傻眼了,只能一条一条的改,而且,如果有一天数据库又要换回来,又要改回去,非常不方便。这里我提供一个方法。
Aceess数据库 System.Data.OleDb
SQLite数据库 System.Data.SQLite
Oracle 数据库 System.Data.OracleClient 或 Oracle.DataAccess.Client
MySql数据库 MySql.Data.MySqlClient
我原本使用Sqlite数据库的代码
public static IDbConnection GetDBConnection()
{
System.Data.SQLite.SQLiteConnectionStringBuilder SQLiteSB = new System.Data.SQLite.SQLiteConnectionStringBuilder();
SQLiteSB.DataSource = System.Configuration.ConfigurationManager.ConnectionStrings["dbPath"].ConnectionString;
return new System.Data.SQLite.SQLiteConnection(SQLiteSB.ToString());
}
使用Access数据库的代码
public static IDbConnection GetDBConnection()
{
System.Data.OleDb.OleDbConnectionStringBuilder AccessSB = new System.Data.OleDb.OleDbConnectionStringBuilder();
AccessSB.Provider = "Microsoft.ACE.OLEDB.12.0";
AccessSB.DataSource = System.Configuration.ConfigurationManager.ConnectionStrings["dbPath"].ConnectionString;
return new System.Data.OleDb.OleDbConnection(AccessSB.ToString());
}
修改为一个抽象类MyDb
public abstract class MyDb
{
private static MyDb _myDb;
public abstract IDbConnection GetDbConnection();
public abstract string InsertTest();
public string SelectMyProject_All()
{
return "select * from MyProject where Name = @Name";
}
public string InsertMyProject()
{
return "insert into MyProject(ProjectID,Name,SharpType) Values(@ProjectID,@Name,@SharpType)";
}
public string InsertMySharp()
{
return "insert into MySharp(ProjectID,Name,SharpID) Values(@ProjectID,@Name,@SharpID)";
}
public string InsertProperty()
{
return "insert into Property(Standard,PositiveTolerance,NegativeTolerance,Compensation,PropertyID,Name,SharpID,IsSelected) Values(@Standard,@PositiveTolerance,@NegativeTolerance,@Compensation,@PropertyID,@Name,@SharpID,@IsSelected)";
}
public string SelectMyProject_ProjectForm()
{
return "select t1.projectID as ProjectIDString,t1.Name,t1.Selection,t2.Name as SharpName from MyProject t1 left join MySharp t2 on t1.ProjectID=t2.ProjectID"; ;
}
public string SelectProperty()
{
return "select t1.Standard,t1.NegativeTolerance,t1.PositiveTolerance,t1.Compensation,t1.PropertyID as PropertyIDString,t1.IsSelected,t1.Name,t1.SharpID as SharpIDString from Property t1 left join MySharp t2 on t1.SharpID=t2.SharpID where t2.ProjectID=@ProjectID";
}
public string DelectMyProject()
{
return "delete from MyProject where Name =@Name";
}
public static MyDb CreateMyDbFactory()
{
switch (System.Configuration.ConfigurationManager.ConnectionStrings["dbPath"].ProviderName)
{
//Aceess数据库
case "System.Data.OleDb":
_myDb = new AccessDb();
return _myDb;
//SQLite数据库
case "System.Data.SQLite":
default:
_myDb = new SqliteDb();
return _myDb;
Oracle 数据库
//case "System.Data.OracleClient":
//case "Oracle.DataAccess.Client":
// break;
MySql数据库
//case "MySql.Data.MySqlClient":
// break;
}
}
}
一个Access的类继承MyDb
public class AccessDb : MyDb
{
public override IDbConnection GetDbConnection()
{
System.Data.OleDb.OleDbConnectionStringBuilder AccessSB = new System.Data.OleDb.OleDbConnectionStringBuilder();
AccessSB.Provider = "Microsoft.ACE.OLEDB.12.0";
AccessSB.DataSource = System.Configuration.ConfigurationManager.ConnectionStrings["dbPath"].ConnectionString;
return new System.Data.OleDb.OleDbConnection(AccessSB.ToString());
}
public override string InsertTest()
{
return "insert into Test([ID],[TestID],[PropertyID],[Name],[Value],[IsMore],[IsLess]) Values(@ID,@TestID,@PropertyID,@Name,@Value,@IsMore,@IsLess)";
}
}
一个Sqlite的类继承MyDb
public class SqliteDb : MyDb
{
public override IDbConnection GetDbConnection()
{
System.Data.SQLite.SQLiteConnectionStringBuilder SQLiteSB = new System.Data.SQLite.SQLiteConnectionStringBuilder();
SQLiteSB.DataSource = System.Configuration.ConfigurationManager.ConnectionStrings["dbPath"].ConnectionString;
return new System.Data.SQLite.SQLiteConnection(SQLiteSB.ToString());
}
public override string InsertTest()
{
return "insert into Test(ID,TestID,PropertyID,Name,Value,IsMore,IsLess) Values(@ID,@TestID,@PropertyID,@Name,@Value,@IsMore,@IsLess)";
}
}
之前的SQL语句代码
using (System.Data.IDbConnection con = db.GetDbConnection())
{
string sqlStr = "insert into Test([ID],[TestID],[PropertyID],[Name],[Value],[IsMore],[IsLess]) Values(@ID,@TestID,@PropertyID,@Name,@Value,@IsMore,@IsLess)";
con.Execute(sqlStr, new
{
ID = test.ID.ToString("N"),
TestID = test.TestID.ToString("N"),
PropertyID = test.PropertyID.ToString("N"),
Name = test.Name,
Value = values,
IsMore = test.IsMore,
IsLess = test.IsLess,
Time = test.Time
});
}
改了之后
var db = MyDb.CreateMyDbFactory();
using (System.Data.IDbConnection con = db.GetDbConnection())
{
string sqlStr = db.InsertTest();
con.Execute(sqlStr, new
{
ID = test.ID.ToString("N"),
TestID = test.TestID.ToString("N"),
PropertyID = test.PropertyID.ToString("N"),
Name = test.Name,
Value = values,
IsMore = test.IsMore,
IsLess = test.IsLess,
Time = test.Time
});
}
改成MyDb抽象类之后便于测试,把SQL语句统一放在一个类里方便管理,而且耦合度低,还符合单一职责。
后来,我看了三层架构,发现业务代码里,虽然SQL语句被隐藏了,但是还是有对数据进行操作,应该隐藏起来,如果要改,还是在数据访问层操作比较好。于是把MyDb类改成如下所示,将之前的得到SQL语句的方法变为protected。
public abstract class MyDb
{
private static MyDb _myDb;
protected abstract IDbConnection GetDbConnection();
protected abstract string CreateTest();
protected abstract string RetrieveTest();
protected string RetrieveMyProject_All()
{
return "select * from MyProject where Name = @Name";
}
protected string CreateMyProject()
{
return "insert into MyProject(ProjectID,Name,SharpType) Values(@ProjectID,@Name,@SharpType)";
}
protected string CreateMySharp()
{
return "insert into MySharp(ProjectID,Name,SharpID) Values(@ProjectID,@Name,@SharpID)";
}
protected string CreateProperty()
{
return "insert into Property(Standard,PositiveTolerance,NegativeTolerance,Compensation,PropertyID,Name,SharpID,IsSelected) Values(@Standard,@PositiveTolerance,@NegativeTolerance,@Compensation,@PropertyID,@Name,@SharpID,@IsSelected)";
}
protected string RetrieveMyProject_ProjectForm()
{
return "select t1.projectID as ProjectIDString,t1.Name,t1.Selection,t2.Name as SharpName from MyProject t1 left join MySharp t2 on t1.ProjectID=t2.ProjectID"; ;
}
protected string RetrieveProperty()
{
return "select t1.Standard,t1.NegativeTolerance,t1.PositiveTolerance,t1.Compensation,t1.PropertyID as PropertyIDString,t1.IsSelected,t1.Name,t1.SharpID as SharpIDString from Property t1 left join MySharp t2 on t1.SharpID=t2.SharpID where t2.ProjectID=@ProjectID";
}
protected string DelectMyProject()
{
return "delete from MyProject where Name =@Name";
}
#region 公有方法
public virtual int CreateTest(ITest test)
{
string values = string.Empty;
foreach (double dd in test.Value)
{
values += dd + ",";
}
values = values.Remove(values.Length - 1);
using (System.Data.IDbConnection con = GetDbConnection())
{
//string sqlStr = "insert into Test([ID],[TestID],[PropertyID],[Name],[Value],[IsMore],[IsLess]) Values(@ID,@TestID,@PropertyID,@Name,@Value,@IsMore,@IsLess)";
string sqlStr = CreateTest();
return con.Execute(sqlStr, new
{
ID = test.ID.ToString("N"),
TestID = test.TestID.ToString("N"),
PropertyID = test.PropertyID.ToString("N"),
Name = test.Name,
Value = values,
IsMore = test.IsMore,
IsLess = test.IsLess,
Time = test.Time
});
}
}
public int CreateMyProject(MyProject myProject)
{
using (IDbConnection con = GetDbConnection())
{
//string sqlStr = "insert into MyProject(ProjectID,Name,SharpType) Values(@ProjectID,@Name,@SharpType)";
string sqlStr = CreateMyProject();
return con.Execute(sqlStr, new { ProjectID = myProject.ProjectID.ToString("N"), Name = myProject.Name, SharpType = myProject.SharpType });
}
}
public int RetrieveMyProject_All(string name)
{
using (IDbConnection con = GetDbConnection())
{
//string sqlStr = "select * from MyProject where Name = @Name";
string sqlStr = RetrieveMyProject_All();
return con.Query(sqlStr, new { Name = name }).Count();
}
}
public int CreateMySharp(MyProject myProject)
{
using (IDbConnection con = GetDbConnection())
{
//sqlStr = "insert into MySharp(ProjectID,Name,SharpID) Values(@ProjectID,@Name,@SharpID)";
string sqlStr = CreateMySharp();
return con.Execute(sqlStr, new { ProjectID = myProject.MySharp.ProjectID.ToString("N"), Name = myProject.MySharp.Name, SharpID = myProject.MySharp.SharpID.ToString("N") });
}
}
public int CreateProperty(Property property)
{
using (IDbConnection con = GetDbConnection())
{
//sqlStr = "insert into Property(Standard,PositiveTolerance,NegativeTolerance,Compensation,PropertyID,Name,SharpID,IsSelected) Values(@Standard,@PositiveTolerance,@NegativeTolerance,@Compensation,@PropertyID,@Name,@SharpID,@IsSelected)";
string sqlStr = CreateProperty();
return con.Execute(sqlStr, new
{
Standard = property.Standard,
PositiveTolerance = property.PositiveTolerance,
NegativeTolerance = property.NegativeTolerance,
Compensation = property.Compensation,
PropertyID = property.PropertyID.ToString("N"),
Name = property.Name,
SharpID = property.SharpID.ToString("N"),
IsSelected = property.IsSelected
});
}
}
public List RetrieveMyProject_ProjectForm(object param = null)
{
using (IDbConnection con = GetDbConnection())
{
//string sqlStr = "select t1.projectID as ProjectIDString,t1.Name,t1.Selection,t2.Name as SharpName from MyProject t1 left join MySharp t2 on t1.ProjectID=t2.ProjectID";
string sqlStr = RetrieveMyProject_ProjectForm();
return con.Query(sqlStr).ToList();
}
}
public List RetrieveProperty(MyProject myProject)
{
using (IDbConnection con = GetDbConnection())
{
string sqlStr = RetrieveProperty();
//string sqlStr = "select t1.Standard,t1.NegativeTolerance,t1.PositiveTolerance,t1.Compensation,t1.PropertyID as PropertyIDString,t1.IsSelected,t1.Name,t1.SharpID as SharpIDString from Property t1 left join MySharp t2 on t1.SharpID=t2.SharpID where t2.ProjectID=@ProjectID";
return con.Query(sqlStr, new { ProjectID = myProject.ProjectID.ToString("N") }).Select(PropertyHelper.ConvertToProperty).ToList();
}
}
public int DelectMyProject(MyProject myProject)
{
using (IDbConnection con = GetDbConnection())
{
//string sqlStr = "delete from MyProject where Name =@Name";
string sqlStr = DelectMyProject();
return con.Execute(sqlStr, myProject);
}
}
public DataTable RetrieveTest(object param = null)
{
using (IDbConnection con = GetDbConnection())
{
return DBHelper.ToDataTable(con.Query(RetrieveTest()));
}
}
public static MyDb CreateMyDbFactory()
{
switch (System.Configuration.ConfigurationManager.ConnectionStrings["dbPath"].ProviderName)
{
//Aceess数据库
case "System.Data.OleDb":
_myDb = new AccessDb();
return _myDb;
//SQLite数据库
case "System.Data.SQLite":
default:
_myDb = new SqliteDb();
return _myDb;
Oracle 数据库
//case "System.Data.OracleClient":
//case "Oracle.DataAccess.Client":
// break;
MySql数据库
//case "MySql.Data.MySqlClient":
// break;
}
}
#endregion
}
public class TestFactory : ITestFactory
{
private readonly MyDb _myDb;
private ITest test;
public Guid TestID { get; set; }
public TestFactory() : this(MyDb.CreateMyDbFactory()) { }
internal TestFactory(MyDb myDb)
{
this._myDb = myDb;
}
public ITest CreateTest()
{
//test的相关操作
_myDb.CreateTest(test);
return test;
}
}
如果有什么其他方法或者觉得我不对的地方,请不吝指出。