一、 SQLite简介
SQLite是遵守ACID的关联式数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。
不像常见的客户-服务器范例,SQLite引擎不是个程序与之通信的独立进程,而是连接到程序中成为它的一个主要部分。所以主要的通信协议是在编程语言内的直接API调用。这在消耗总量、延迟时间和整体简单性上有积极的作用。整个数据库(定义、表、索引和数据本身)都在宿主主机上存储在一个单一的文件中。它的简单的设计是通过在开始一个事务的时候锁定整个数据文件而完成的。
这个介绍就不说了,反正它就是个小型的SQL数据库,有点类似于ACCESS。先来试试它的功能吧。
二、创建sqlite数据库
1、创建空的sqlite数据库。
//方法一:创建一个空sqlite数据库,用IO的方式
FileStream fs = File.Create(“c:\\test.db“);
//方法二:用SQLiteConnection
SQLiteConnection.CreateFile(“c:\\test.db“);
创建的数据库是个0字节的文件。
2、创建加密的空sqlite数据库
SQLiteConnection.CreateFile(“c:\\test2.db“);
SQLiteConnection cnn = new SQLiteConnection(“Data Source=c:\\test2.db“);
SQLiteConnection cnn = new SQLiteConnection(“Data Source=D:\\test2.db“);
cnn.Open();
cnn.ChangePassword(“password“);
3、给未加密的数据库加密
cnn.Open();
cnn.ChangePassword(“password“);
4、打开加密sqlite数据库
//方法一
SQLiteConnection cnn = new SQLiteConnection(“Data Source=c:\\test2.db“);
cnn.SetPassword(“password“);
cnn.Open();
//方法二
SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.DataSource = @”c:\test.db“;
builder.Password = @”password“;
SQLiteConnection cnn = new SQLiteConnection(builder.ConnectionString);
cnn .Open();
分页
select * from messages limit 10,100;
表示跳过10行,取100行的返回结果。
三、 初步试探
经过多方搜索,我找到了SQLite在.NET平台的支持库,点击 这里 下载。我按照默认安装,路径为:”c://program files/sqlite.net”,安装后进入这个文件夹,里面有好多文件,我们只需要”System.Data.SQLite.DLL”,很小,只有605K。打开VS,新建一个控制台程序sqlitetest。引用刚才提到的DLL文件。然后引用”System.Data.SQLite”命名空间。现在就可以试试了。
从网上查询到了一些资料,现在运用一下,看看行不行。
第一步,创建数据库文件。
我声明了一个全局字符串变量”dbName”,方面以后使用。
新建数据库文件的相关代码为:
SQLiteConnection.CreateFile(dbName);
是不是超级简单。接下来就是连接了。同样是SQLiteConnection这个类。这个类有3个构造函数,一个是空参数,另一个是SQLiteConnection类型,就是复制一个连接了,最后一个是字符串类型(连接字符串),这个连接字符串包含数据库信息已经密码(这个轻量级的数据库也支持密码哦,好厉害),我现在还不懂格式是什么,先试试默认构造函数。网上给的是使用SQLiteConnectionStringBuilder这个类构造连接字符串。它有很多属性,现在要用的是DataSource属性,把dbName赋给它。还有Password属性,没有密码吧,赋给它””吧。然后就是打开数据库了。所有代码如下:
SQLiteConnection conn = new SQLiteConnection();
SQLiteConnectionStringBuilder connsb = new SQLiteConnectionStringBuilder();
connsb.DataSource = dbName;
connsb.Password = "";
conn.ConnectionString = connsb.ToString();
conn.Open();
接下来理所当然地要插入张表试试。
SQLite有个跟SQLCommand类似的SQLiteCommand,用法也差不多,这就不多说了,直接给出代码吧:
SQLiteCommand cmd = new SQLiteCommand(conn);
string cmdText = "CREATE TABLE TEST(ID int,name varchar(20))";
cmd.CommandText = cmdText;
cmd.ExecuteNonQuery();
一起把插入数据的代码也贴了,都一样的东西:
cmd.CommandText = "INSERT INTO [TEST] (ID,name) VALUES (1,'acen')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO [TEST] (ID,name) VALUES (2,'unique')";
cmd.ExecuteNonQuery();
接下来就要查询数据了,看看结果如何。网上教程用的是SQLiteReader,是不是和SQLReader很像?对啊,其实用法也是一样的,看来这东西做得还是很方便的,代码如下:
cmd.CommandText = "SELECT * FROM [TEST]";
SQLiteDataReader dr = cmd.ExecuteReader();
StringBuilder sb = new StringBuilder();
while (dr.Read())
{
sb.Append(dr.GetInt32(0)).Append(""n").Append(dr.GetString(1));
}
Console.WriteLine(sb);
只要用过ADO.NET的看懂上面的代码都没问题吧,行,我们运行一下吧!
等啊等,哦,出错了:Invalid ConnectionString format for parameter "Password".原来这句有问题,那好吧,删掉试试。行了,呵呵,成功了!再看看网上的文章,注释为“设置密码”,意思这一步是设置密码?试试。真行了,与此相关的东西接下来再测试。
好吧,首战告捷,现在我们进一步对其进行测试!进行之前把完整代码贴出来吧。
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;
namespace sqlitetest
{
class Program
{
private const string dbName="sqlitetest.db";
static void Main(string[] args)
{
//创建数据库文件
SQLiteConnection.CreateFile(dbName);
//建立数据库连接并打开数据库
SQLiteConnection conn = new SQLiteConnection();
SQLiteConnectionStringBuilder connsb = new SQLiteConnectionStringBuilder();
connsb.DataSource = dbName;
connsb.Password = "acen";
conn.ConnectionString = connsb.ToString();
conn.Open();
//添加表
SQLiteCommand cmd = new SQLiteCommand(conn);
string cmdText = "CREATE TABLE TEST(ID int,name varchar(20))";
cmd.CommandText = cmdText;
cmd.ExecuteNonQuery();
//插入测试数据
cmd.CommandText = "INSERT INTO [TEST] (ID,name) VALUES (1,'acen')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO [TEST] (ID,name) VALUES (2,'unique')";
cmd.ExecuteNonQuery();
//查询结果
cmd.CommandText = "SELECT * FROM [TEST]";
SQLiteDataReader dr = cmd.ExecuteReader();
StringBuilder sb = new StringBuilder();
while (dr.Read())
{
sb.Append(dr.GetInt32(0)).Append(""n").Append(dr.GetString(1));
}
Console.WriteLine(sb);
Console.ReadKey();
}
}
}
三、连接部分深入测试
第二部分基本是照着网上的一篇文章弄的,现在来点自己的测试。这次就不能再创建数据库了吧,别把刚才的给盖了。好的,开始,把创建数据库文件和添加表那一部分删除。先直接运行,有四条记录了。说明文件连接正常,已经起到存储的作用了。
研究一下SQLiteConnection的相关内容。
首先是它那几个构造函数。复制连接那个就不管了,看它剩下的那个构造函数吧,看看是什么格式。狂试自然不行,单步调试吧,不是有一步是把connsb(SQLiteConnectionStringBuilder)的值转换为string后赋值给conn(SQLiteConnection)吗,看看connsb的值,发现了,是”Data Source=sqlitetest.db;Password=acen”,应该就是这个了,试试。测试通过,那么把密码去掉试试。”File opened that is not a database file .file is encrypted or is not a database”,不出所料,出错了。刚才查看SQLiteConnection属性的时候,看到有DataSource项,莫非不用借助SQLiteConnectionStringBuilder直接赋值也行?嘿嘿,不用得意得太早,这是只读的,行不通。我要修改密码怎么办呢?再认真看看,从连接字符串一定是不可能的了,那就从SQLiteConnection这个类看看吧,有个SetPassword方法,这个方法有两种参数,一种是字节数组,另一种是字符串形式,用第二种吧,改为”imacen”,能运行,问题是能多次运行,不对吧,密码没改到?把新密码加到连接字符串,果真出错了。我刚才是放在打开数据库之前,莫非不能这样?那放在后面吧,还是错了,提示设置密码应当在数据库开始之前,莫非这只是设置连接时的密码?嗨,我错了,我没认真看,它还有个changePassword的方法,这个才是啊,而且要放在数据库打开后。那我就纳闷了,为什么有setPassword方法却没有setDataSource方法呢?把连接字符串的密码部分删了,再试试setPassword方法。成功,它真的是设置连接密码的,我想它为什么要加入这个方法呢,可能考虑到安全新问题吧,其它都是使用明文,只是猜测罢了。行,这部分就这样了,能连了就得。
总结一下:
1. 可以使用SQLiteConnectionStringBuilder类构建链接字符串,然后转换为string赋给SQLiteConnection的ConnectionString属性,密码没有就别写成””了。
2. 在构造SQLiteConnection时直接用连接字符串,格式为”Data Source=xxx;Password=xxx”;其中密码部分可以在setPassword方法中设置。
3. 修改密码使用SQLiteConnection的changePassword方法,需在数据库打开之后。
四、 插入数据测试
SQLite不支持存储过程,虽然它的类SQLiteCommand有一个CommandType属性,但其明确写着目前仅支持CommandType.Text.那我要测试什么呢?参数功能。开始啦!
记得在前面给出的代码中有插入数据部分,现在把插入语句换成” INSERT INTO [TEST] (ID,name) VALUES (@ID,@name)";有Parameters这个属性吧,真的有,不好意思了,连Add,AddWithValue都有,好啊,先用AddWithValue这种最简单的试试。
cmd.CommandText = "INSERT INTO [TEST] (ID,name) VALUES (@ID,@name)";
cmd.Parameters.AddWithValue("@ID", 5);
cmd.Parameters.AddWithValue("@name","testtest");
cmd.ExecuteNonQuery();
运行,显然行。那我们就和SQLCommand对比一下吧。粗略看了一下,SQLCommand有的SQLiteCommand都有,莫非SQLiteCommand就是继承自SQLCommand?或者两者是继承自同一个接口,从”System.Data.SQLite”,”System.Data.SQLClient”来看,这两者应该是继承自同一个接口了。看看能不能找着证据。
很明显,他们确实是继承自同一个类或接口,那就没什么好说的啦,这个测试也差不多就这样啦,其它读取,更新那些也应该就一样了。
后来我还分析了一下,这个SQLite应该就是把各个类重写了一下,再把SQL Server的功能精简后编译成DLL文件。我没用过ACCESS,但我觉得SQLite跟ACCESS应该就是同类的东西了吧。这个我不敢下断言。
用SQLite的好处在于,它能执行大部分SQL语句,而且网上评论认为它的性能是相当高的,另外一个最重要的原因是,它很小,1M不到的体积对于小型数据运用是非常方便的了。