实例化 Database
Database 是一个核心的实现,它实现了 IDatabase
接口定义的所有功能,它支持读写分离,所有的读操作都会使用从库,只有写操作才会使用主库,并自动开启事务。
1、Database 类
Database
类是 IDatabase
的默认实现,一般不建议直接使用 Database
类的构造函数来创建实例,但有必要介绍一下它的构造函数。如下所示:
[TestMethod]
public void TestDatabase()
{
var connStr = "Data Source=localhost;database=northwind;User Id=root;password=faib;";
using (var db = new Database(connStr, MySqlProvider.Instance))
{
}
}
Database
类的构造函数接收一个数据库连接字符串,以及 IProvider
实例,一般使用 MsSqlProvider.Instance、MySqlProvider.Instance 等单例形式。
Database
类除了接收一个数据库连接字符串,还可以接收一组数据库连接字符串,当数据库实例配置为集群模式时(见 数据库实例配置 -- 集群配置),使用的就是此构造函数。如下所示:
[TestMethod]
public void TestDistributedDatabase()
{
var conStrs = new List<DistributedConnectionString> {
new DistributedConnectionString("Data Source=192.168.1.100;database=northwind;User Id=root;password=faib;") { Mode = DistributedMode.Master },
new DistributedConnectionString("Data Source=192.168.1.101;database=northwind;User Id=root;password=faib;") { Mode = DistributedMode.Slave, Weight = 40 },
new DistributedConnectionString("Data Source=192.168.1.102;database=northwind;User Id=root;password=faib;") { Mode = DistributedMode.Slave, Weight = 60 }
};
using (var db = new Database(conStrs, MySqlProvider.Instance))
{
}
}
2、使用 DatabaseFactory 创建
DatabaseFactory
工厂类通过 数据库实例配置 来创建一个 IDatabase
实例。CreateDatabase 方法的 instanceName 参数和数据库实例配置中的 name 相对应,如果该参数,则使用默认的实例配置,即 default 项。如下所示:
[TestMethod]
public void TestCreateDatabase()
{
var db1 = DatabaseFactory.CreateDatabase();
var db2 = DatabaseFactory.CreateDatabase("mssql");
Assert.IsNotNull(db1); // sqlite db;
Assert.IsNotNull(db2); // sqlserver db;
}
使用 CreateDatabase 创建的 IDatabase
实例类型是可以配置为自己定义的实现的,之前在数据库实例配置章节并没有提及,只需在配置项中通过指定 databaseType 为一个实现类即可。如下所示:
- .Net Framework 下的 app.config 或 web.config 文件
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="fireasy">
<section name="dataInstances" type="Fireasy.Data.Configuration.InstanceConfigurationSectionHandler, Fireasy.Data"/>
</configSections>
<fireasy>
<dataInstances>
<instance name="mysql"
providerType="MySql"
databaseType="demo.Database, demo",
connectionString="Data Source=localhost;database=northwind;User Id=root;password=faib;pooling=true;charset=utf8"/>
</dataInstances>
</fireasy>
</configuration>
- .Net Core 下的 appsettings.json 文件
{
"fireasy": {
"dataInstances": {
"settings": {
"mysql": {
"providerType": "MySql",
"databaseType": "demo.Database, demo"
"connectionString": "Data Source=localhost;database=northwind;User Id=root;password=faib;pooling=true;charset=utf8"
}
}
}
}
}
3、从 Scope 里获取
使用 DatabaseScope
类可以在同一线程范围内使用相同的一个 IDatabase
实例,DatabaseFactory
工厂类的 GetDatabaseFromScope 方法可以检索当前线程内是否有存在 DatabaseScope
实例,如果存在的话则返回 DatabaseScope
实例的 IDatabase
实例。如下所示:
[TestMethod]
public void TestScopedDatabase()
{
using (var db = DatabaseFactory.CreateDatabase())
using (var scope = new DatabaseScope(db))
{
TestFromScope();
}
}
public void TestFromScope()
{
using (var db = DatabaseFactory.GetDatabaseFromScope())
{
Assert.IsNotNull(db);
}
}
从 DatabaseScope
实例获得的 IDatabase
实例是一个 NoDisposeDatabase
类型的对象,它的 Dispose 方法不会执行资源释放。
4、ScopedDatabase 类
ScopedDatabase
类继承自 Database
类,它在实例化时加入了一个 DatabaseScope
实例,因此如果使用此实例的话,是不需要在重新定义 DatabaseScope
实例的。如下所示:
[TestMethod]
public void TestScopedDatabase()
{
var connStr = "Data Source=localhost;database=northwind;User Id=root;password=faib;";
using (var db = new ScopedDatabase(connStr, MySqlProvider.Instance))
{
TestFromScope();
}
}
public void TestFromScope()
{
var db = DatabaseFactory.GetDatabaseFromScope();
Assert.IsNotNull(db);
}