SQLite
SQLite作为一个开源的嵌入式数据库产品,具有系统开销小,检索效率高的特性,适用于手机、PDA、机顶盒设备等电器,并且作为嵌入式数据库在可下载的消费类应用程序中运行的很好。这篇文章介绍嵌入式数据库产品SQLite的技术特点,并着重讨论研究与Java语言之间的接口,并以实例说明如何使用JAVA开发基于SQLite的应用程序。
通常我们采用各种数据库产品来实现对数据的存储、检索等功能,例如,Oracle,SQL Server,MySQL等等。这些产品除提供基本的查询,删除,添加等功能外,也提供了很多高级特性,如触发器,存储过程,数据备份恢复,全文检索功能等。但实际上,很多的应用,仅仅利用到了这些数据库产品的基本特性而已。而且在一些小型应用上,或者某些特殊场合的应用,比如桌面程序,这些数据库产品就明显有一些臃肿。在这些情况下,嵌入式数据库的优势就特别明显了。
嵌入式数据库无须独立运行的数据库引擎,它是由程序直接调用相应的API去实现对数据的存取操作。更直白的讲,嵌入式数据库是一种具备了基本数据库特性的数据文件。嵌入式数据库与其它数据库产品的区别是,前者是程序驱动式, 而后者是引擎响应式。嵌入式数据库的一个很重要的特点是它们的体积非常小,编译后的产品也不过几十K。这不但对桌面程序的数据存储方案是一个很好的选择,也使得它们可以应用到一些移动设备上。同时,很多嵌入式数据库在性能上也优于其它数据库,所以在高性能的应用上也常见嵌入式数据库的身影。
下面介绍的是开放源代码的嵌入式数据库,SQLite。同时侧重研究如何应用Java连接SQLite数据库,并开发基于SQLite的应用程序。
SQLite 是D ·理查德·希普开发出来的用一个小型C 库实现的一种强有力的嵌入式关系数据库管理体制。它提供了对SQL92 的大多数支持: 支持多表和索引、事务、视图、触发和一系列的用户接口及驱动
SQLite 实现了完备的、可嵌入的、零配置的SQL数据库引擎。它的特点包括:
1、事务处理是原子的、一致的、独立的和持久的(ACID),即使在系统崩溃和掉电以后。
2、零配置,即不需要设置和管理。
3、实现了绝大部分的SQL92标准。
4、一个单独的磁盘文件存储一个完整的数据库。
5、数据库文件在机器之间可自由共享。
6、支持数据库文件大小至2TB。
7、字符串和BLOG的大小只受限于可用存储器容量。
8、代码量小,即小于30K的C代码行和小于250K的代码空间(gcc 在i486上)
9、对于绝大多数普通操作来说,比流行的C/S 模式的数据库引擎运行速度快。
10、API 简单、易用。
可以看出,基于以上特点,SQLite非常适合应用于嵌入式移动数据库。SQLite的版权允许无任何限制的应用,包括商业性的产品。SQLite官方主站上可以下载到编译后的SQLite程序。
SQLite是无数据类型的数据库。虽然在生成表结构的时候,要声明每个域的数据类型,但SQLite并不做任何检查。开发人员要靠自己的程序控制输入与读出数据的类型是正确的。这里有一个例外,就是当主键为整型值时,如果要插入一个非整型值时会产生异常。另外,虽然在插入或读出数据的时候是不区分类型的,但在比较的时候,不同数据类型是有区别的。比如:
CREATE TABLE MyTable(a INTEGER, b TEXT); INSERT INTO MyTable VALUES(0,0);
当执行下面的查询:
SELECT count(*) FROM MyTable WHERE a=='00';
会返回一条记录,因为字段a的类型是整型,而数字00与0是相等的。而执行下面的查询则不会返
回记录:
SELECT count(*) FROM MyTable WHERE b=='00';
因为字段b是字符类型,字符"00"与"0"是不相等的。
SQLite提供了对Transaction的支持。应用Transaction即保证了数据的完整性,也会提高运行速度,因为多条语句一起提交给数据库的速度会比一条一条的提交方式更快。
SQLite库包括一个简单的命令行工具,该工具名称对应SQLite-3_2_2版本叫做sqlite3,用户使用这个工具可以对一个SQLite数据库手工输入和执行SQL命令。例如建立一个名叫wgy的SQLite数据库,并建立一个名叫user的表的步骤如下:
Sqlite3 wgy
SQLite version
Enter ".help" for instructions
sqlite> create table user(usernamevarchar(10), password varchar(10));
sqlite> insert into user values('Marry','111111');
sqlite> insert into tbl1 values('Helen','222222');
sqlite> select * from user;
Marry|111111
Helen|222222
Sqlite>
用户结束操作只需按CTRL+C组合键。注意每条SQL命令后要加分号。
用户可能对命令行方式的操作感到不直观,不太容易使用。那么用户可以使用SQLite Database Browser 软件,这是一个免费的、公用域的、开源的可视化工具,可以用来建立、编辑SQLite数据库文件。这就意味着用户可以不必学习复杂的SQL命令,而直接使用熟悉的可视化图形界面设计、编辑SQLite数据库。用户可从http://sqlitebrowser.sourceforge.net/下载该工具软件。
SQLite源代码是C,而且官方网站上只提供了C和Tcl语言的接口。为了应用Java接口,要采用第三方的接口驱动程序,可在http://www.ch-werner.de/javasqlite 中找到这个Java接口程序。这个接口提供了两种连接SQLite的方式:一是直接用JNI技术调用SQLite的C语言接口,这种方式要求开发人员要对SQLite本身的API也有一定的了解。在第二种方式中,接口程序实现了Java标准规范的JDBC接口,这样开发人员只要对JDBC有了解就可以了。
第三方接口库中的Java代码包含JNI接口和多个版本的JDBC接口程序,可根据你的JRE的版本选择相应的JDBC程序。Java类包加上Sqlite_jni.dll文件,组成了SQLite的Java接口库,在应用Java语言调用JDBC或JNI接口时,都是通过应用Java的本地化技术调用Sqlite_jni.dll文件,完成对SQLite数据库的操作。
下面这段代码演示如何应用JNI接口操作SQLite。可以看到Database类的exec()方法是执行SQL语句的关键:
Database db = new Database(); try { //打开数据库 db.open("c:\\temp\\mydata.slt",0666); db.interrupt(); db.busy_timeout(1000); db.busy_handler(null); db.exec("create table account (namevarchar(10),gale boolean)",result); db.exec("insert into accountvalues('steve','m')", result); db.exec("select * fromaccount",result); Author:YiYun QQ:33252040 / 99593311 //关闭数据库 db.close(); } catch (Exception e) { e.printStackTrace(); }
用户一定要保证在类路径class_path中有“sqlite.jar”,并且保证在你的JAVA库路径JAVAlibrary path 中有本地库nativelibrary。用"SQLite.JDBCDriver"作为JDBC的驱动程序类名。连接JDBC的URL格式为jdbc:sqlite:/path。这里的path为指定到SQLite数据库文件的路径,例如:
jdbc:sqlite://dirA/dirB/dbfile
jdbc:sqlite://DRIVE:/dirA/dirB/dbfile
jdbc:sqlite://COMPUTERNAME/shareA/dirB/dbfile
参考下面的应用JDBC连接SQLite的例程:
//声明JDBC驱动程序
Class clz =Class.forName("SQLite.JDBCDriver");
//连接数据库
Connection conn =DriverManager.getConnection("jdbc:sqlite:/c:/temp/e2.db");
Statement stmt = conn.createStatement();
//生成person表,包含名子和年龄字段
stmt.execute("create table person(name varchar(100),age int)");
//插入数据
stmt.execute("insert into personvalues('steve',25)");
//用SQL语句读出数据
result = stmt.executeQuery("select *from person");
while(result.next()){
System.out.println(result.getString(1));
System.out.println(result.getInt(2));
}
运行程序时要在Java.exe命令行加入选项java.library.path指定到Sqlite_jni.dll所在的路径。例如,如果Sqlite_jni.dll放在c:\sqliteNative 路径下面,运行类com.YiYun.MyClass 的命令行将会是这样:java-Djava.library.path=c:\sqliteNative com.YiYun.MyClass。
SQLite已于
import java.sql.*;
public class Test {
public static void main(String[] args) throws Exception {
Class.forName("org.sqlite.JDBC");
Connection conn =
DriverManager.getConnection("jdbc:sqlite:test.db");
Statement stat = conn.createStatement();
stat.executeUpdate("drop table if exists people;");
stat.executeUpdate("create table people (name, occupation);");
PreparedStatement prep = conn.prepareStatement(
"insert into people values (?, ?);");
prep.setString(1, "Gandhi");
prep.setString(2, "politics");
prep.addBatch();
prep.setString(1, "Turing");
prep.setString(2, "computers");
prep.addBatch();
prep.setString(1, "Wittgenstein");
prep.setString(2, "smartypants");
prep.addBatch();
conn.setAutoCommit(false);
prep.executeBatch();
conn.setAutoCommit(true);
ResultSet rs = stat.executeQuery("select * from people;");
while (rs.next()) {
System.out.println("name = " + rs.getString("name"));
System.out.println("job = " + rs.getString("occupation"));
}
rs.close();
conn.close();
}
}