SQLite 是一種嵌入式數(shù)據(jù)庫(kù)定拟,它的數(shù)據(jù)庫(kù)就是一個(gè)文件。由于SQLite本身是C寫(xiě)的蹋嵌,而且體積很小,所以葫隙,經(jīng)常被集成到各種應(yīng)用程序中栽烂,甚至在iOS和Android的App中都可以集成。SQLite是一個(gè)進(jìn)程內(nèi)的庫(kù)恋脚,實(shí)現(xiàn)了自給自足的腺办、無(wú)服務(wù)器的、零配置的糟描、事務(wù)性的 SQL 數(shù)據(jù)庫(kù)引擎怀喉。它是一個(gè)零配置的數(shù)據(jù)庫(kù),這意味著您不需要在系統(tǒng)中配置船响,就可以使用躬拢。
特點(diǎn)
不需要一個(gè)單獨(dú)的服務(wù)器進(jìn)程或操作的系統(tǒng)(無(wú)服務(wù)器的)。
SQLite 不需要配置见间,這意味著不需要安裝或管理聊闯。
一個(gè)完整的 SQLite 數(shù)據(jù)庫(kù)是存儲(chǔ)在一個(gè)單一的跨平臺(tái)的磁盤(pán)文件。
SQLite 是非常小的米诉,是輕量級(jí)的菱蔬,完全配置時(shí)小于 400KiB,省略可選功能配置時(shí)小于250KiB史侣。
SQLite 是自給自足的拴泌,這意味著不需要任何外部的依賴(lài)。
SQLite 事務(wù)是完全兼容 ACID 的惊橱,允許從多個(gè)進(jìn)程或線程安全訪問(wèn)蚪腐。
SQLite 支持 SQL92(SQL2)標(biāo)準(zhǔn)的大多數(shù)查詢(xún)語(yǔ)言的功能。
Unity中使用
using System;
using System.Collections.Generic;
using UnityEngine;
using Mono.Data.Sqlite;
/// <summary>
/// 數(shù)據(jù)庫(kù)管理器
/// </summary>
public class DBManager :MonoBehaviour{
private static DBManager _instance;
public static DBManager Instance
{
get
{
if (_instance == null)
{
GameObject go = new GameObject("DBManger");
_instance = go.AddComponent<DBManager>();
}
return _instance;
}
}
//用于建立數(shù)據(jù)庫(kù)連接税朴,保證數(shù)據(jù)流
SqliteConnection connection;
//數(shù)據(jù)庫(kù)命令
SqliteCommand command;
//數(shù)據(jù)庫(kù)閱讀器
SqliteDataReader reader;
private const string dbName = "data";
void Awake()
{
InitDB();
OpenDB();
}
void OnDestroy()
{
CloseDB();
}
//拷貝數(shù)據(jù)庫(kù)到沙盒目錄
void InitDB()
{
Debug.Log("*-> DBManager->Init");
//判斷是移動(dòng)端
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
{
string systemDBPath = Application.persistentDataPath + "/data.db";
// copy data.db from steamingAssetsPath to persistentDataPath
if (!System.IO.File.Exists(systemDBPath))
{
CopyFileFromStreamingAssetsToPersistentDataPath("/data.db");
}
}
}
void CopyFileFromStreamingAssetsToPersistentDataPath(string relativePath)
{
string fileInStreamingAssets = Application.streamingAssetsPath + relativePath;
string fileInPersistentDataPath = Application.persistentDataPath + relativePath;
Debug.Log(fileInStreamingAssets + "->"+ fileInPersistentDataPath);
if (Application.platform == RuntimePlatform.Android)
{
WWW fileReader = new WWW(fileInStreamingAssets);
while (!fileReader.isDone) { }
//把www加載的數(shù)據(jù)庫(kù)的bytes寫(xiě)入到沙盒的data.db
FileUtil.WriteFile(fileInPersistentDataPath, fileReader.bytes);
}
else
{
byte[] content = FileUtil.ReadFile(fileInStreamingAssets);
FileUtil.WriteFile(fileInPersistentDataPath, content);
}
}
public void OpenDB()
{
try
{
//指定數(shù)據(jù)庫(kù)路徑削茁,一般放置到StreamingAsset下
string path = Application.streamingAssetsPath + "/" + dbName + ".db";
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
{
path = Application.persistentDataPath + "/" + dbName + ".db";
}
Debug.Log("dbPath:" + path);
//新建數(shù)據(jù)庫(kù)連接
connection = new SqliteConnection(@"Data Source = " + path);
//打開(kāi)數(shù)據(jù)庫(kù)
connection.Open();
Debug.Log("打開(kāi)數(shù)據(jù)庫(kù)");
}
catch (Exception ex)
{
Debug.Log(ex.ToString());
}
}
public void CloseDB()
{
if(connection!=null)
connection.Close();
if (command != null)
command.Dispose();//Dispose用于釋放宙枷,和Close功能一樣
if (reader != null)
reader.Close();
Debug.Log("關(guān)閉數(shù)據(jù)庫(kù)");
}
//創(chuàng)建表
//Activator.CreateInstance(type);//根據(jù)System.Type類(lèi)型去實(shí)例化一個(gè)類(lèi)
//var fields = type.GetFields();//根據(jù)System.Type類(lèi)型拿到類(lèi)中的字段
//fields[i].Name//得到單個(gè)字段的名字
//fields[i].Name//T t: type.GetField(fields[i].Name).GetValue(t);//得到T類(lèi)型的t中field的值
//fields[i].Name//T t: type.GetField(fields[i].Name).SetValue(t,"新的值");//設(shè)置T類(lèi)型的t中field的值
public void CreateTable<T>()
{
var type = typeof(T);
string sql = "create Table "+type.Name+"(";
var fields = type.GetFields();
for (int i = 0; i < fields.Length; i++)
{
sql += "[" + fields[i].Name + "] " + CS2DB(fields[i].FieldType)+",";
}
sql = sql.TrimEnd(',') + ")";
Excute(sql);
}
public void Insert<T>(T t)
{
var type = typeof(T);
string sql = "insert into " + type.Name + " values (";
var fields = type.GetFields();
foreach (var field in fields)
{
//通過(guò)反射得到對(duì)象中的值
sql += "'" + type.GetField(field.Name).GetValue(t) + "',";
}
sql = sql.TrimEnd(',') + ");";
Excute(sql);
}
//插入語(yǔ)句
//--insert into users values("小新",28,'男','371452646566256456',1235123123);
public void InsertInto(string tbName,params object[] objs)
{
string sql = "insert into " + tbName + " values (";
foreach (var item in objs)
{
sql += "'"+ item + "',";
}
//sql=sql.Substring(0, sql.Length - 1);
sql=sql.TrimEnd(',')+ ");";
Excute(sql);
}
//刪除語(yǔ)句
public void DeleteAnd(string tbName,params object[] objs)
{
string sql = "delete from " + tbName + " where (";
for (int i = 0; i < objs.Length-1; i+=2)
{
sql += objs[i] + "='" + objs[i + 1] +"' and ";
}
sql=sql.Substring(0, sql.Length - 4)+ ");";
Excute(sql);
}
//修改語(yǔ)句
//--update users set age = 18 where name = '小史'and cardid isnull;
public void UpdateAnd(string tbName, object[] colums,params object[] conditions)
{
string sql = "update "+tbName+" set ";
for (int i = 0; i < colums.Length-1; i+=2)
{
sql += colums[i] + "='" + colums[i + 1] + "',";
}
sql = sql.TrimEnd(',') + " where (";
for (int i = 0; i < conditions.Length-1; i+=2)
{
sql += conditions[i] + "='" + conditions[i + 1]+"' and ";
}
sql = sql.Substring(0, sql.Length - 4) + ");";
Excute(sql);
}
//查詢(xún)>字典
public List<Dictionary<string, string>> Select(string tbName)
{
string sql = "select * from " + tbName;
Excute(sql);
List<Dictionary<string, string>> result = new List<Dictionary<string, string>>();
while(reader.Read())
{
var dic = new Dictionary<string, string>();
for (int i = 0; i < reader.FieldCount; i++)
{
dic.Add(reader.GetName(i), reader.GetValue(i).ToString());
}
result.Add(dic);
}
return result;
}
/// <summary>
/// 泛型約束
/// class :引用類(lèi)型
/// struct:值類(lèi)型
/// 接口和抽象類(lèi)
/// 普通類(lèi)
/// new():無(wú)參構(gòu)造,(必須是最后一個(gè)約束)
/// </summary>
//查詢(xún):泛型實(shí)體類(lèi)(復(fù)用性高,靈活)
public List<T> Select<T>() where T: new()
{
var type = typeof(T);
string sql = "select * from " + type.Name;
Excute(sql);
List<T> result = new List<T>();
var fields = type.GetFields();
while (reader.Read())//讀取下一行數(shù)據(jù)
{
T t = new T();//使用new() 實(shí)例化T
for (int i = 0; i < reader.FieldCount; i++)
{
string key = reader.GetName(i);//獲取數(shù)據(jù)庫(kù)指定列的key
object value = reader.GetValue(i);//獲取數(shù)據(jù)庫(kù)指定列的值
Debug.Log(key + ":" + value);
type.GetField(key).SetValue(t, value);//使用反射給T類(lèi)型t賦值
}
result.Add(t);
}
return result;
}
/// <summary>
/// 通過(guò)Id查詢(xún)數(shù)據(jù)
/// </summary>
public T SelectById<T>(string id) where T:new()
{
Type type = typeof(T);
string sql = "select * from " + type.Name + " where id='" + id+"'";
Excute(sql);
T t = new T();
reader.Read();
var count = reader.FieldCount;
for (int i = 0; i < count; i++)
{
string key = reader.GetName(i);
object value = reader.GetValue(i);
type.GetField(key).SetValue(t, value);
}
return t;
}
void Excute(string sql)
{
Debug.LogWarning(sql);
//創(chuàng)建數(shù)據(jù)庫(kù)連接命令
command = connection.CreateCommand();
//設(shè)置命令語(yǔ)句
command.CommandText = sql;
//執(zhí)行命令
reader = command.ExecuteReader();
}
string CS2DB(Type type)
{
string result = "Text";
if(type==typeof(Int32))
{
result = "Int";
}
else if (type == typeof(String))
{
result = "Text";
}
else if (type == typeof(Single))
{
result = "FLOAT";
}
else if (type == typeof(Boolean))
{
result = "Bool";
}
return result;
}
}