SQLite數據庫-Unity操作
項目開發的時候,經常會遇到的一種需求,數據存儲
離線緩存的數據類型很多,大致分成兩類
- 字符串文本數據
- 多媒體數據
字符串數據的類型只有字符串,但是結構有很多:
- xml
- json
- md5
- base64
- 普通字符串
多媒體數據的類型:
- 圖片(jpg,png,gif...)
- 音頻(mp3,aif...)
- 視頻(mp4,mpv)
通常用數據庫來存儲字符串文本類型的數據,但是需要注意的是數據庫同時也能存儲多媒體類型的數據
關系數據庫
在一個給定的應用領域中,所有實體及實體之間聯系的集合構成一個關系數據庫。
目前主流的關系數據庫有oracle、db2、sqlserver、sybase、mysql等。
在Unity中打開數據庫函數
private string GetDBPath(string name)
{
return Application.persistentDataPath + "/" + name + ".sqlite";
}
/// <summary>
/// 就是用來存儲程序與數據庫鏈接的對象
/// </summary>
private SqliteConnection connection = null;
private void OpenDataBase()
{
//獲取一個數據庫文件的路徑
string path = GetDBPath ("xiaohao");
string c = "Data Source=" + path;
//需要通過數據庫文件磁盤路徑進行初始化
connection = new SqliteConnection (c);
//打開數據庫
connection.Open();
}
CRUD
創建表格SQL
create table lo_human(human_id integer,human_name text,human_age integer);
C#函數調用創建表格SQL
private void CreateObject()
{
//在一個數據庫鏈接對象上創建一個命令對象
SqliteCommand command = new SqliteCommand(connection);
//給命令對象添加SQL語句
command.CommandText = "create table if not exists lo_human(human_id integer,human_name text,human_age integer);";
//執行命令
command.ExecuteNonQuery();
}
添加數據
insert into lo_human(human_id,human_name,human_age) values(1,'xiaohao',36);
C#函數調用添加數據SQL
private void InsertObject()
{
//在一個數據庫鏈接對象上創建一個命令對象
SqliteCommand command = new SqliteCommand (connection);
//給命令對象添加SQL語句
command.CommandText = "insert into lo_human(human_id,human_name,human_age) values(1,'xiaohao',36);";
//執行命令
command.ExecuteNonQuery ();
}
更新數據
update lo_human set human_name='cuiyayun' where human_id=2;
C#函數調用更新數據SQL
private void UpdateObject()
{
//在一個數據庫鏈接對象上創建一個命令對象
SqliteCommand command = new SqliteCommand (connection);
//給命令對象添加SQL語句
command.CommandText = "update lo_human set human_name='cuiyayun' where human_id=3;";
//執行命令
command.ExecuteNonQuery ();
}
刪除數據
delete from lo_human where humanid=1;
C#函數調用刪除數據SQL
private void DeleteObject()
{
//在一個數據庫鏈接對象上創建一個命令對象
SqliteCommand command = new SqliteCommand (connection);
//給命令對象添加SQL語句
command.CommandText = "delete from lo_human where human_id=1;";
//執行命令
command.ExecuteNonQuery ();
}
查詢數據
select * from lo_human where human_id>15 order by human_id desc;
C#函數調用查詢數據SQL
private void SelectObject()
{
//在一個數據庫鏈接對象上創建一個命令對象
SqliteCommand command = new SqliteCommand (connection);
//給命令對象添加SQL語句
command.CommandText = "select * from lo_human where human_id>15 order by human_id desc;";
//數據讀取器
SqliteDataReader reader = command.ExecuteReader();
//判讀是否可以讀取下一行數據,如果可以的話就獲取數據
while (reader.Read())
{
//在循環體里,已經確定是哪行數據.
Debug.Log(reader ["human_name"]);
}
}
高級用法
通過使用C#語言的反射機制實現工具類SQLiteTools
[AttributeUsage(AttributeTargets.Property)]
public class SQLFieldAttribute:Attribute
{
public string Name{ set; get;}
public string Type{ set; get;}
public bool IsNotNull{ set; get;}
public bool AutoIncrement{set;get;}
public bool IsPrimaryKey{set;get;}
public string Default{ set; get;}
public bool IsUnique{set;get;}
}
[AttributeUsage(AttributeTargets.Class)]
public class SQLTableAttribute:Attribute
{
public string Name{set;get;}
}
/// <summary>
/// 測試功能用到的類
/// </summary>
//創建TestClass附件的特性對象SQLTable,並且將該特性對象的屬性Name賦值為"test_class"
[SQLTable(Name="test_class")]
public class TestClass
{
//創建test_id屬性附件的特性對象SQLField,並且將該特性對象的屬性Name、Type、AutoIncrement、IsNotNull、IsPrimaryKey進行賦值
[SQLField(Name="test_id",Type="integer",AutoIncrement=true,IsNotNull=true,IsPrimaryKey=true)]
public int test_id{set;get;}
[SQLField(Name="test_name",Type="text")]
public string test_name{set;get;}
[SQLField(Name="test_age",Type="integer")]
public int test_age{ set; get;}
public TestClass(){}
}
LOSQLiteTools.cs實現具體的功能
獲取表格名稱函數
/// <summary>
/// 獲取表格的名稱
/// </summary>
/// <returns>The table name.</returns>
private static string GetTableName(Type item)
{
//獲取到特性類型
Type att_type = typeof(SQLTableAttribute);
//獲取參數type對應的特性對象
Attribute a = Attribute.GetCustomAttribute(item,att_type);
if (a == null) {
return null;
}
//因為在Attribute.Get函數里的最后一個參數已經指定了
//特性的類型是SQLTableAttribute,所以可以顯式轉換
SQLTableAttribute sa = (SQLTableAttribute)a;
//將特性對象的Name屬性返回
return sa.Name;
}
獲取屬性姓名函數
/// <summary>
/// 獲取屬性在Field中的名字
/// </summary>
private static string GetFieldName(PropertyInfo item)
{
Type att_type = typeof(SQLFieldAttribute);
Attribute a = Attribute.GetCustomAttribute (item, att_type);
if (a == null) {
return null;
}
SQLFieldAttribute sfa = (SQLFieldAttribute)a;
return sfa.Name;
}
獲取屬性類型函數
/// <summary>
/// 獲取屬性在Field中的類型
/// </summary>
private static string GetFieldType(PropertyInfo item)
{
Type att_type = typeof(SQLFieldAttribute);
Attribute a = Attribute.GetCustomAttribute (item, att_type);
if (a == null) {
return null;
}
SQLFieldAttribute sfa = (SQLFieldAttribute)a;
return sfa.Type;
}
獲取屬性區域字符串函數
/// <summary>
/// 獲取創建表格時的Field字符串
/// </summary>
private static string GetFieldString(PropertyInfo item)
{
Type att_type = typeof(SQLFieldAttribute);
Attribute a = Attribute.GetCustomAttribute (item, att_type);
if (a == null) {
return null;
}
SQLFieldAttribute sfa = (SQLFieldAttribute)a;
string sql = "";
sql += sfa.Name + " ";
sql += sfa.Type + " ";
if (sfa.IsPrimaryKey) {
sql += "primary key" + " ";
}
if (sfa.AutoIncrement) {
sql += "autoincrement" + " ";
}
if (sfa.IsNotNull) {
sql += "not null" + " ";
}
if (sfa.IsUnique) {
sql += "unique" + " ";
}
if (sfa.Default != null) {
sql += "default " + sfa.Default;
}
return sql;
}
創建表格函數
/// <summary>
/// 通過實體類型創建數據庫表格
/// </summary>
public static void CreateTable(Type type)
{
//獲取一個類型的所有屬性
PropertyInfo[] p_list = type.GetProperties();
//獲取Table的名字
string table_name = GetTableName(type);
//獲取Table的列名字符串
string field_list = "(";
foreach (PropertyInfo item in p_list)
{
//對應的屬性區域
field_list += GetFieldString(item) + ",";
}
//刪除最后一個,
field_list = field_list.Substring (0, field_list.Length - 1);
field_list += ")";
//開始構造sql命令
string sql = "create table if not exists ";
sql += table_name + field_list + ";";
Debug.Log (sql);
SqliteCommand command = new SqliteCommand (connection);
command.CommandText = sql;
command.ExecuteNonQuery ();
}
}