代码之家  ›  专栏  ›  技术社区  ›  Bartosz

为什么Xamarin文档建议使用singleton进行数据库连接?

  •  5
  • Bartosz  · 技术社区  · 8 年前

    酒店雇员和饭馆雇员 https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/dependency-service/introduction/

    这种方法创建一个保持打开的数据库连接 在应用程序运行时,因此避免了打开的费用 以及在每次执行数据库操作时关闭数据库文件 已执行。

    public static TodoItemDatabase Database
    {
      get
      {
        if (database == null)
        {
          database = new TodoItemDatabase(DependencyService.Get<IFileHelper>().GetLocalFilePath("TodoSQLite.db3"));
        }
        return database;
      }
    }
    

    https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/part_2_-_architecture/

    单例模式提供了一种只需要 特定对象的单个实例可能永远存在。例如 在移动应用程序中使用SQLite时,您只需要一个 数据库的实例。使用单例模式是一种简单的方法

    在这里 https://developer.xamarin.com/guides/cross-platform/application_fundamentals/building_cross_platform_applications/case_study-tasky/

    TaskItemDatabase是一个单例,确保对同一实例进行所有访问。锁用于防止并发 从多个线程访问。

    public T GetItem<T> (int id) where T : BL.Contracts.IBusinessEntity, new ()
    {
        lock (locker) {
            return Table<T>().FirstOrDefault(x => x.ID == id);
        }
    }
    

    getting db connection through singleton class Is singleton approach right for accessing/maintaining database and internet connection

    那么,知道Xamarin团队为什么要推广这种方法吗?是因为他们框架的某些特殊性而有所不同吗? 更重要的是,如果不是这样,那么正确的方法是什么?

    2 回复  |  直到 8 年前
        1
  •  4
  •   Stephen Rauch Afsar Ali    7 年前

    SQLite数据库结构是内存中的单个文件(您将其路径设置为“TodoSQLite.db3”)。可以将其视为从代码的多个位置访问特定的.txt文件。

        2
  •  4
  •   Brandon Minnick    6 年前

    Xamarin最流行的SQLite ORM, SQLite-net ,是线程安全的,并为您处理数据库连接。

    我更喜欢使用类似的方法构造数据库 BaseDatabase 检索连接的类。

    基本数据库

    笔记 基本数据库 Xamarin.Essentials NuGet Package 定位应用程序的数据目录。确保首先添加Xamarin。Essentials NuGet软件包并遵循 Getting Started Instructions

    using System.Threading.Tasks;
    
    using SQLite;
    
    using Xamarin.Essentials;
    using Xamarin.Forms;
    
    namespace MyNamespace
    {
        public abstract class BaseDatabase
        {
            static readonly string _databasePath = Path.Combine(FileSystem.AppDataDirectory, "SqliteDatabase.db3");
            static readonly Lazy<SQLiteAsyncConnection> _databaseConnectionHolder = new Lazy<SQLiteAsyncConnection>(() => new SQLiteAsyncConnection(_databasePath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create | SQLiteOpenFlags.SharedCache));
    
            SQLiteAsyncConnection DatabaseConnection => _databaseConnectionHolder.Value;
    
            protected static async Task<SQLiteAsyncConnection> GetDatabaseConnection<T>()
            {
                if (!DatabaseConnection.TableMappings.Any(x => x.MappedType.Name == typeof(T).Name))
                {
                    // On sqlite-net v1.6.0+, enabling write-ahead logging allows for faster database execution
                    // await DatabaseConnection.EnableWriteAheadLoggingAsync().ConfigureAwait(false);
                    await DatabaseConnection.CreateTablesAsync(CreateFlags.None, typeof(T)).ConfigureAwait(false);
                }
    
                return DatabaseConnection;
            }    
        }
    }
    

    数据库

    namespace MyNamespace
    {
        public class OpportunityModelDatabase : BaseDatabase
        {
            public async Task<List<OpportunityModel>> GetAllOpportunityDataAsync()
            {
                var databaseConnection = await GetDatabaseConnection<OpportunityModel>().ConfigureAwait(false);
    
                return await databaseConnection.Table<OpportunityModel>().ToListAsync().ConfigureAwait(false);
            }
        }
    }
    
    推荐文章