1. 逻辑
- 封装各个数据库的访问方式;
- 以表为单位,定义 interface 接口,实现增删改查等操作,基于 Postgresql、Oracel 等数据库的具体实现类继承 interface;
- 封装 DataAccess 类,实现访问数据库的统一入口,通过反射的方式实现;
对 Postgresql、Oracel 等数据库的具体实现类的类名有要求。
如:PgStudent、OracleStudent,前缀固定为 Pg、Oracle,后缀保持一致。 - 封装对接业务层的 Model 层,通过 DataAccess 获取对应的数据库、数据表,返回给业务层。
2. 文件结构
3. 代码示例
3.1 interface 接口及具体实现类
public class Student {}
public interface IStudent
{
/// <summary>
/// 获取学生列表
/// </summary>
/// <returns></returns>
List<Student> GetStudentList(int page, int size);
}
/// <summary>
/// 从 Pg 表操作 学生 表
/// </summary>
public class PgStudent : AbstractPostgresql, IStudent
{
public List<Student> GetStudentList(int page, int size)
{
var list = new List<Student>();
try
{
string selectSql = string.Format("SELECT ...;");
var dt = this.ExecuteQuery(selectSql); //执行 sql 语句
list = DataTableToList<Student>(dt).ToList();//转成集合
}
catch (Exception ex) {}
return list;
}
}
/// <summary>
/// 从 Oracle 操作 学生 表
/// </summary>
public class OracleStudent : AbstractOracle, IStudent
{
public List<Student> GetStudentList(int page, int size)
{
var list = new List<Student>();
try
{
string selectSql = string.Format("SELECT ...;");
var dt = this.ExecuteQuery(selectSql);
list = DataTableToList<Student>(dt).ToList();
}
catch (Exception ex) {}
return list;
}
}
AbstractPostgresql 参考 https://www.cnblogs.com/MichaelLoveSna/p/14478846.html
AbstractOracle 参考 https://www.cnblogs.com/MichaelLoveSna/p/14478879.html
3.2 DataAccess
通过反射的方式,根据配置文件决定的
public class DataAccess
{
private static readonly string AssemblyName = "GoSun.VMapEngine.Vmap.YunXing";
private static readonly string db = ConfigurationManager.AppSettings["DBType"];
private static object _iStudentLockObj = new object();
private static IStudent _iStudent;
private static object _iTeacherLockObj = new object();
private static ITeacher _iTeacher;
...
/// <summary>
/// 获取学生操作类,使用单例模式(双锁)
/// </summary>
/// <returns></returns>
public static IStudent CreateStudent()
{
if (_iStudent == null)
{
lock (_iStudentLockObj)
{
if (_iStudent == null)
{
string className = AssemblyName + "." + db + "Student";
_iStudent = (IStudent)Assembly.Load(AssemblyName).CreateInstance(className);
}
}
}
return _iStudent;
}
}
3.3 GetStudent.cs
调用 DataAccess,根据配置文件制定的数据库类型获取对应的 Student 的数据库操作类,然后调用类的方法进行 sql 语句的操作。
public class GetStudentInfo
{
#region 获取学生列表
/// <summary>
/// 获取列表列表
/// </summary>
/// <returns></returns>
public static List<Student> GetStudentList(int page, int size)
{
List<Student> stuList = null;
IStudent iStu = DataAccess.CreateStudent();
stuList = iStu.GetStudentList(int page, int size);
return stuList;
}
/// <summary>
/// 异步获取学生列表
/// </summary>
/// <returns></returns>
public async static Task<List<Student>> AsyncGetStudentList(int page, int size)
{
List<Student> stuList = await Task.Run(() =>
{
IStudent iStu = DataAccess.CreateStudent();
return iStu.GetStudentList(int page, int size);
});
return stuList;
}
#endregion
}
3.4 业务调用
public class x
{
public async void InitStuList()
{
int page = 1;
int size = 10;
List<Student> stuList = await GetStudentInfo.AsyncGetStudentList(int page, int size);
// To do
// use stuList
}
public void InitStuList_2()
{
int page = 1;
int size = 10;
Task.Run(() =>
{
return GetStudentInfo.AsyncGetStudentList(int page, int size);
}).ContinueWith((r) =>
{
// To do
// use r.Result
});
}
}