30

数据访问与多数据库支持

简介

本文档详细介绍了数据访问层的设计与实现,重点阐述了数据库适配机制、多数据库支持(SqlServer、MySql、Oracle、SQLite)及其配置方法。此外,还讲解了ORM、数据查询工具的用法和扩展方式。

项目结构

项目结构主要分为以下几个部分:

  1. Known:主项目,包含核心数据访问逻辑。
  2. Shared:共享库,包含数据库访问的基础实现和多数据库支持。
  3. Plugins:插件模块,扩展功能。
  4. Sample:示例项目,展示如何使用数据访问层。

核心目录

  • Known/:主项目目录。
  • Shared/Data/:数据库访问实现目录。
    • Database.cs:数据库访问基类。
    • DbProvider.*.cs:各数据库提供程序实现。
    • Database.Query.cs:查询工具实现。
    • DBUtils.cs:数据库工具类。

核心组件

1. 数据库访问基类 (Database.cs)

Database 类是数据访问层的核心,提供了数据库连接、事务管理、查询执行等功能。支持多数据库类型,并通过 DbProvider 实现适配。

关键功能

  • 多数据库支持:通过 DatabaseType 区分不同数据库类型。
  • 连接管理:支持连接字符串配置和动态切换。
  • 事务支持:提供事务管理功能。
public partial class Database : IDisposable
{
    public const string DefaultConnName = "Default";
    private DbConnection conn;
    private DbTransaction trans;
    private string TransId { get; set; }
}

2. 数据库提供程序 (DbProvider.*.cs)

每个数据库类型有独立的提供程序实现,例如:

  • SqlServerProvider:SQL Server 数据库支持。
  • MySqlProvider:MySQL 数据库支持。
  • OracleProvider:Oracle 数据库支持。
  • SQLiteProvider:SQLite 数据库支持。

示例:SQL Server 提供程序

class SqlServerProvider(Database db) : DbProvider(db)
{
    public override string FormatName(string name) => $"[{name}]";
    public override object FormatBoolean(bool value) => value ? 1 : 0;
}

3. 查询工具 (Database.Query.cs)

提供丰富的查询功能,支持异步操作和复杂查询表达式。

示例:查询单条数据

public virtual Task<T> QueryAsync<T>(string sql, object param = null)
{
    var info = new CommandInfo(Provider, typeof(T), sql, param);
    return QueryAsync<T>(info);
}

架构概述

数据访问层采用适配器模式,通过 DbProvider 实现多数据库支持。核心类 Database 负责统一管理数据库连接和操作,而具体的数据库实现由各提供程序完成。

classDiagram
    class Database {
        +DatabaseType DatabaseType
        +string ConnectionString
        +DbConnection conn
        +DbTransaction trans
        +OpenAsync()
        +CloseAsync()
    }
    class DbProvider {
        +FormatName(string name)
        +FormatBoolean(bool value)
    }
    Database --> DbProvider: uses
    DbProvider <|-- SqlServerProvider
    DbProvider <|-- MySqlProvider
    DbProvider <|-- OracleProvider
    DbProvider <|-- SQLiteProvider

详细组件分析

1. 数据库连接配置

通过 SetDatabase 方法动态配置数据库连接:

public virtual void SetDatabase(string connName)
{
    var info = DatabaseOption.Instance.GetDatabase(connName);
    SetDatabase(info);
}

2. 查询功能

支持多种查询方式:

  • 直接SQL查询:通过 QueryAsync 方法执行SQL语句。
  • 表达式查询:通过 Expression 构建查询条件。
public virtual Task<List<T>> QueryListAsync<T>(Expression<Func<T, bool>> expression)
{
    var info = Provider?.GetSelectCommand(expression);
    return QueryListAsync<T>(info);
}

依赖分析

数据访问层依赖以下组件:

  1. 数据库驱动:如 System.Data.SqlClientMySql.Data 等。
  2. 日志组件:通过 ILoggerFactory 记录操作日志。

性能考虑

  • 连接池:默认启用连接池,减少连接开销。
  • 异步操作:所有查询和操作均支持异步,提高并发性能。

故障排除指南

常见问题

  1. 连接失败:检查连接字符串是否正确。
  2. 事务异常:确保事务未提前提交或回滚。

结论

数据访问层通过适配器模式实现了多数据库支持,提供了灵活的查询工具和高效的性能优化。开发者可以通过简单的配置切换数据库类型,并通过丰富的API完成复杂的数据操作。