Xamarin.Forms學習系列之SQLite


在App中我們通常不會實時獲取服務器數據,會在用戶手機中保存歷史數據,這個時候就需要用到數據庫SQLite,由於微軟的封裝,在Xamarin中操作SQLite非常簡單,類似EF的操作。

1、我們需要在共享項目的nuget中引用 sqlite-net-pcl 和 SQLitePCLRaw.core  

2、由於Android和IOS的SQLite數據庫存放位置不一樣,所以我們需要在共享項目中抽象一個接口ISQLite,然后分別在Android和IOS項目中實現接口,初始化數據庫連接

共享項目代碼如下:

public interface ISQLite
    {
        SQLiteAsyncConnection GetAsyncConnection();
    }

Android項目代碼如下:

[assembly: Xamarin.Forms.Dependency(typeof(SQLiteAndroid))]//注入SQLiteAndroid
namespace Mobile.Droid.Helpers
{
    public class SQLiteAndroid : ISQLite
    {
        private static string path;

        private static SQLiteAsyncConnection connectionAsync;

        private static readonly object locker = new object();
        private static readonly object pathLocker = new object();

        private static string GetDatabasePath()
        {
            lock (pathLocker)
            {
                if (path == null)
                { 
                    string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); // Documents folder
                    path = Path.Combine(documentsPath, GlobalSetting.SqliteFilename);
                }
            }
            return path;
        }

        public SQLiteAsyncConnection GetAsyncConnection()
        {
            lock (locker)
            {
                if (connectionAsync == null)
                {
                    var dbPath = GetDatabasePath();
                    connectionAsync = new SQLiteAsyncConnection(dbPath);
                }
            }
            return connectionAsync;
        }
    }
}

IOS項目代碼如下:

[assembly: Xamarin.Forms.Dependency(typeof(SQLiteIOS))]
namespace Mobile.iOS.Helpers
{
    public class SQLiteIOS : ISQLite
    {
        private static string path;

        private static SQLiteAsyncConnection connectionAsync;

        private static readonly object locker = new object();
        private static readonly object pathLocker = new object();

        private static string GetDatabasePath()
        {
            lock (pathLocker)
            {
                if (path == null)
                { 
                    var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // Documents folder
                    var libraryPath = Path.Combine(documentsPath, "..", "Library"); // Library folder
                    path = Path.Combine(libraryPath, GlobalSetting.SqliteFilename);
                }
            }
            return path;
        }

        public SQLiteAsyncConnection GetAsyncConnection()
        {
            lock (locker)
            {
                if (connectionAsync == null)
                {
                    var dbPath = GetDatabasePath();
                    connectionAsync = new SQLiteAsyncConnection(dbPath);
                }
            }
            return connectionAsync;
        }
    }
}

3、在共享項目中創建SqliteHelper 

using Microsoft.AppCenter.Crashes;
using Mobile.Interfaces;
using SQLite;
using System;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace Mobile.Helpers
{
    public class SqliteHelper
    {
        static SqliteHelper baseSqlite;
        public static SqliteHelper Current
        {
            get { return baseSqlite ?? (baseSqlite = new SqliteHelper()); }
        }
        public SQLiteAsyncConnection db;
        public SqliteHelper()
        {
            if (db == null)
                db = DependencyService.Get<ISQLite>().GetAsyncConnection();
        }

        /// <summary>
        /// 創建或者更新Sqlite數據庫表
        /// 在App啟動的時候執行該方法,sqlite-net-pcl會根據實體類創建對應的表,如果實體類有更新,表結構也會更新,如果表結構沒變,則不進行操作,sqlite-net-pcl會自動判斷
        /// </summary>
        public async void CreateOrUpdateAllTablesAsync()
        {
            await db.CreateTablesAsync<TestTable, UserInfo>();
        }

    }
}

4、Sqlite的增刪改查操作

public async Task<Model.News> QueryNew(int id)
        {
            return await db.Table<Model.News>().Where(a => a.Id == id).FirstOrDefaultAsync();
        }
        public async Task<List<Model.News>> QueryNews(int pageSize)
        {
            return await db.Table<Model.News>().OrderByDescending(a => a.DateAdded).Skip(0).Take(pageSize).ToListAsync();
        }
        public async Task<List<Model.News>> QueryNewsByRecommend(int pageSize)
        {
            return await db.Table<Model.News>().Where(a => a.IsRecommend).OrderByDescending(a => a.DateAdded).Skip(0).Take(pageSize).ToListAsync();
        }
        public async Task<List<Model.News>> QueryNewsByWorkHot(int pageSize, DateTime startdate)
        {
            return await db.Table<Model.News>().Where(a => a.IsHot && a.DateAdded > startdate).OrderByDescending(a => a.DateAdded).Skip(0).Take(pageSize).ToListAsync();
        }
        public async Task UpdateNews(List<Model.News> lists)
        {
            foreach (var item in lists)
            {
                await QueryNew(item.Id).ContinueWith(async (results) =>
                {
                    if (results.Result == null)
                    {
                        try
                        {
                            await db.InsertAsync(item);
                        }
                        catch (Exception ex)
                        {
                            Crashes.TrackError(ex);
                        }
                    }
                    else
                    {
                        await UpdateNew(item);
                    }
                });
            }
        }
        public async Task UpdateNew(Model.News model)
        {
            try
            {
                await db.UpdateAsync(model);
            }
            catch (Exception ex)
            {
                Crashes.TrackError(ex);
            }
        }

參考代碼: https://github.com/JoesWeek/XamCnblogs 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM