请教java连接sqlite数据库与SQLServer两个数据库数据互导的问题

讨论SQLite数据库损坏与修复
您当前位置: &
[ 所属分类
作者 红领巾 ]
昨晚,朋友和我反馈SQLite数据库发生损坏有没有办法恢复。大致的情况是这样的,当数据库在使用时不小心用了新的文件覆盖数据库,导致了SQLite数据库出现了损坏,打开的时候出现要输入密码,而且不能把SQL语句dump下来。所以,文章这里整理SQLite数据库出现损坏的所有情况,以及如何修复损坏的SQLite数据库文件。SQLite算是非常稳定的数据库,不容易出现损坏,就算应用程序崩溃,或者操作系统崩溃,甚至是执行事务时出现断电,都能在下一次使用数据库时自动修复。但是,还是不能避免不出现损坏的情况。导致SQLite数据库损坏的情况导致SQLite数据库损坏的情况大致可归结为4类:文件覆盖问题、文件锁问题、数据同步问题、内存问题文件覆盖问题SQLite数据库文件被覆盖是可能的,毕竟是一个普通的磁盘文件,意味着所有的进程都可以打开和覆盖,所以不可能完全避免文件覆盖的情况。1. 多线程写数据库问题。 SQLite数据库是支持多进程并发读写,但是如果这时候关闭和重新打开数据库,就很可能出现一些线程还在写数据到数据库,出现部分数据被覆盖的情况。2. 执行事务时备份或恢复数据 事务都是一个过程性的操作,需要一定时间,而数据备份是原子操作,如果在事务执行过程时备份,可能导致复制的内容包含了部分新的内容和部分旧的内容,就出现数据库损坏。恢复也是一样。3. 删除日志文件 SQLite数据库通常都是存储所有内容到一个文件,但执行事务时,为了实现程序崩溃,断电时可以回滚日志,就伴随着一些附加的日志文件。如果日志被删除了,就会导致恢复出现异常。文件锁问题为了实现SQLite数据库并发读写,SQLite会使用文件锁来保证数据安全。1. 系统文件锁问题SQLite依赖于底层的文件系统对文件锁的实现,但是,一些文件系统存在锁逻辑错误,使得锁并不可靠,这在网络文件系统和NFS情况比较常见。2. POSIX协同锁(advisory lock)在 或者unix下,SQLite 默认锁是协同锁。当进程使用协同锁,如果其中有一个线程执行 close() 就可能导致锁被取消。如果已经有两个线程同时连接到同一个数据库,再来一个线程不以SQLite API的形式,就是以系统文件形式读取数据库( open(), read() , 然后close()),就会导致这个进程的数据库锁被取消,而两个线程同时操作数据库就会导致数据覆盖引起错乱。3. 不同的连接协议不同的连接协议锁也可能会不同,也就导致锁没有发挥错误引起错误。4.当数据库正在使用时删除或重命名数据库文件出现这种情况往往是在linux等类POSIX系统,下不会出现这个情况,而且同时有事务执行就会放大这个问题。数据同步问题为了保证数据一致性,SQLite有时候会请求操作系统将所有等待持久化的数据刷入磁盘,然后等待这个操作完成。1.磁盘驱动器的同步请求可能是不可靠的 现有普通消费级别的磁盘驱动器多数都会谎报数据同步结果,以期望得到更高的写入速度。当数据刚到达磁盘缓冲区,还没真正写入氧化物介质,磁盘驱动器就报告内容已经安全写入。但是这时候断电、硬件复位就会导致数据同步失败。这种情况主要出现在闪存介质。2.使用PRAGMAs会影响同步通过设置PRAGMA synchronous=OFF, SQLite所有的同步操作都会被忽略。这使得SQLite运行得更快,但如果出现电源故障或硬件复位就会前面保存的所有数据。如果单纯为了获得最大的数据可靠性和健壮性,SQLite可设置synchronous = FULL内存问题SQLite作为一个C运行库,和使用它的应用程序运行在同一个内存地址空间。这意味着,任何野指针,缓冲区溢出,堆损坏等都有可能损坏了SQLite的数据结构,并最终导致数据库文件损坏。另外,使用内存映射I/O模型(如mmap)的时候,内存问题会变得更加严重。当数据库文件的一部分或全部被映射到应用程序的地址空间,虽然减少了文件IO操作,但是野指针可能访问并修改到任何部分的映射空间数据。更多SQLite数据库损坏的原因可以看这里。修复损坏的SQLite数据库linux下:$ sqlite3 mydata.db ".dump" | sqlite3 new.dbwin下:d:\&sqlite3 mydata.db .dump & mydata.sqld:\&sqlite3 new.db & mydata.sqld:\&sqlite3 aa.db "pragma integrity_check"这里可以下载 sqlite3.exe当然,这些API只是在一定程序修复损坏的数据库,无法解决所有的问题。SQLite使用建议这里有4点建议:1. 减少多进程或多线程操作,尽可能单线程写。2. 减少事务操作,减小事务复杂度,减少检查点3. 减少数据库的大小4. 避免使用PRAGMA synchronous=OFF
本文数据库(mssql)相关术语:熊片数据库 mssql数据库 oracle数据库 pubmed数据库 access数据库 万方数据库
转载请注明本文标题:本站链接:
分享请点击:
1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
阅读(1548)
循路觅宗师,形影不相离,师知吾亦知,吾乃成宗师。
手机客户端
,专注代码审计及安全周边编程,转载请注明出处:http://www.codesec.net
转载文章如有侵权,请邮件 admin[at]codesec.net你的位置:
&& 详细内容
《SQLite权威指南(第二版)》电子书[PDF]
本资料所属分类:
更新时间:日
如不能下载,请查看
电子书http://www.minxue.net:&SQLite权威指南(第二版)原名:&The Definitive Guide to SQLite 作者:& Grant Allen译者:& 杨谦 刘义宣 谢志强图书分类:&网络资源格式:&PDF版本:&扫描版出版社:&电子工业出版社书号:&5地区:& 大陆语言:& 简体中文简介:&
译者序 iv推荐序1 vi推荐序2 viii推荐序3 ix关于作者 xx关于技术评审 xxi致谢 xxii简介 xxiii第1章 sqlite介绍 1嵌入式数据库 1开发者的数据库 2管理员的数据库 4sqlite历史 4谁在使用sqlite 5体系结构 6接口 6编译器 7虚拟机 7后端 9.工具和测试代码 9sqlite的特性和设计理念 10零配置 10移植性 10紧凑性 11简单性 11灵活性 12自由授权 12可靠性 12易用性 12性能和限制 13本书面向的读者 16本书的组织结构 17附加说明 18总结 19第2章 入门 21何处获取sqlite 21windows上的sqlite 22获得命令行程序 22获取sqlite动态链接库(dll) 25在windows上编译sqlite源代码 26使用微软visual c++构建sqlite dll 29用visual c++构建动态链接sqlite的客户端 31用mingw构建sqlite 32linux、苹果mac os x以及其他posix系统上的sqlite 34二进制和包 34从源代码编译 35命令行程序 37shell模式下的clp 37命令行模式的clp 39数据库管理 40创建数据库 40获得数据库的schema信息 42导出数据 43导入数据 44格式化 45导出带分隔符的数据 46执行无人值守维护 46备份数据库 47获得数据库文件的信息 48其他sqlite工具 50总结 51第3章 sqlite中的sql 53数据库示例 53安装 55运行示例 55语法 56命令 58常量 58关键字和标识符 59注释 59创建数据库 59创建表 60修改表 61数据库查询 62关系操作 62select命令与操作管道 63过滤 66限定和排序 71函数(function)和聚合(aggregate) 73分组(grouping) 74去掉重复 79多表连接 80名称和别名 85子查询 87复合查询 89条件结果 91处理sqlite中的null 93总结 95第4章 sqlite中的高级sql 97修改数据 97插入记录 97更新记录 101删除记录 102数据完整性 102实体完整性 103域完整性 108存储类 113视图 116索引 118触发器 120事务 124事务的范围 124冲突解决 125数据库锁 128死锁 129事务的类型 130数据库管理 131附加数据库 131数据库清理 133数据库配置 133系统目录 137查看查询计划 137总结 138第5章 sqlite设计与概念 139api 140主要数据结构 140连接和语句 141核心api 142可操作的控制 150使用线程 151扩展api 151创建用户自定义函数 151创建用户自定义聚合 152创建用户自定义排序 153事务 153事务生命周期 154锁状态 154读事务 156写事务 157调整页面缓存 160过渡到独占状态 161调整页面缓存 161等待锁 162繁忙处理 162使用恰当的事务 164代码 165使用多个连接 165finalize()函数的重要性 167共享缓存模式 168总结 168第6章 核心c api 171查询封装 171连接与断开连接 172执行查询 174获取表查询 178查询准备 179编译 180执行 181完成与重置 182获取记录 184获取字段信息 184获取字段值 186一个实例 187查询参数化 189参数编号 192参数命名 192tcl参数 193错误与异常 194错误处理 194繁忙情况处理 196模式改变处理 197操作控制 198提交钩子 198回滚钩子 199更新钩子 199授权函数 200线程 210共享缓存模型 210线程与内存管理 213总结 214第7章 扩展c api 215api 216注册函数 217步骤函数 218返回值 219函数 220返回值 222数组与内存清理器 223错误处理 224返回输入值 224聚合 225注册函数 226实例 226排序规则 230排序法定义 231简单例子 234按需排序 237总结 238第8章 语言扩展 239选择一种扩展语言 240perl 242安装 242连接 243查询处理 243参数绑定 245用户自定义函数 246聚合 247python 248安装 248连接 249查询处理 249参数绑定 251用户自定义函数 253聚合 253apsw(另一种python接口) 254ruby 255安装 255连接 256查询处理 256参数绑定 257用户自定义函数 259java 260安装 260连接 261查询处理 262自定义函数和聚合 264jdbc 266tcl 268安装 268连接 268查询处理 269用户自定义函数 272php 272安装 273连接 273查询 274用户自定义函数和聚合 276总结 278第9章 ios开发中的sqlite 279sqlite ios开发的先决条件 279注册成为apple软件开发者 280下载并安装xcode和ios sdk 280其他开发环境 283建立iseinfeld ios sqlite应用 284第一步:创建一个新的xcode工程 285第二步:将sqlite框架添加到工程 285第三步:准备foods数据库 287第四步:为食品数据创建类 289第五步:访问和查询sqlite数据库 293第六步:最后包装和配置iseinfeld应用程序 297运行iseinfeld 297ios中处理大型sqlite数据库 299总结 300第10章 android开发中的sqlite 301sqlite android开发的先决条件 301检查先决条件和jdk 302下载和安装android sdk starter包 302下载和安装android开发工具 303添加android平台和组件 304android sqlite类和接口 306使用基础帮助类:sqliteopenhelper 307sqlitedatabase类 308在实际中应用sqliteopenhelper和sqlitedatabase 312使用sqlitequerybuilder类查询sqlite数据库 315搭建seinfeld android sqlite应用程序 317创建新的android工程 318将seinfeld sqlite数据库添加到工程 319查询food数据库表 319定义用户接口 320连接数据和用户接口 321查看完成的seinfeld应用程序 322sqlite android应用程序的注意事项 322android数据库的备份 323android系统处理大型sqlite数据库 324总结 324第11章 sqlite内部机制及新特性 325b-tree和pager模块 325数据库文件格式 325b-tree api 330显示类型、存储类以及亲缘性介绍 332显示类型 333类型亲缘性 335亲缘性和存储 336执行中的亲缘性 336预写日志 340wal工作原理 341激活和配置wal 342wal的优缺点 343启用wal时sqlite数据库的操作问题 343总结 345索引 347
电子书www.minxue.net链接内容介绍:  这是一本关于sqlite 起源、特性、简介、使用、深度解析的书。   《sqlite权威指南(第二版)》首先从 sqlite 最初起源、特性、设计理念、实际应用讲解开始,逐步深入、全面地介绍了在各个平台如何使用sqlite。接着,介绍sqlite 的一般sql 和高级功能的sql,采取举例说明,使得本书内容生动有趣。然后,全面介绍了各种语言如何与sqlite 进行编程交互,重点介绍sqlite 原生语言c 语言中的api,使得使用者可以不管扩展sqlite 的功能。本书还介绍了目前火热的ios 和android 开发中如何使用sqlite,并给出实际例子。最后,介绍了sqlite 内部架构设计,使得读者可以深入理解sqlite,高级开发者可以进一步参与sqlite 开发或者开发自己的sqlite。   不管您是 sqlite 的初学者,还是sqlite 资深用户或者是对sql 语言和程序设计感兴趣的技术爱好者,都可以从本书汲取营养。 内容截图:
自带站内搜索End-->
相关学习资料您的位置: >>
嵌入式数据库无需安装,体积小巧,速度又很快,在很多场合可以替代目前流行的MySQL, SQLServer等大中型数据库。本文介绍两种嵌入式数据库产品:Berkeley DB和SQLite,并着重讨论它们与Java之间的接口。
  嵌入式数据库无需安装,体积小巧,速度又快,在很多场合可以替代目前流行的MySQL,SQL Server等大中型数据库。本文介绍两种嵌入式数据库产品:Berkeley DB和SQLite,并着重讨论它们与Java之间的接口。
  通常我们采用各种数据库产品来实现对数据的存储、检索等功能,例如,Oracle,SQL Server,MySQL等。这些产品除提供基本的查询,删除,添加等功能外,也提供了很多高级特性,如触发器,存储过程,数据备份恢复,全文检索功能 等。但实际上,很多的应用,仅仅利用到了这些数据库产品的基本特性而已。而且在一些小型应用上,或者某些特殊场合的应用,比如桌面程序,这些数据库产品就 明显有一些臃肿。在这些情况下,嵌入式数据库的优势就特别明显了。
  嵌入式数据库无须独立运行的数据库引擎,它是由程序直接调用相应的 API去实现对数据的存取操作。更直白的讲,嵌入式数据库是一种具备了基本数据库特性的数据文件。嵌入式数据库与其它数据库产品的区别是,前者是程序驱动 式, 而后者是引擎响应式。嵌入式数据库的一个很重要的特点是它们的体积非常小,编译后的产品也不过几十K。这不但对桌面程序的数据存储方案是一个很好的选择, 也使得它们可以应用到一些移动设备上。同时,很多嵌入式数据库在性能上也优于其它数据库,所以在高性能的应用上也常见嵌入式数据库的身影。
  下面介绍的是两个开放源代码的嵌入式数据库,Berkeley DB和SQLite。同时侧重介绍如何应用Java连接这两种嵌入式数据库。
  一. Berkeley DB
  1. 简介
  Berkeley DB是一款健壮的,高速的工业级嵌入式数据库产品,你可以在它的官方主页(见参考链接一)上发现很多知名的公司都采用了这款嵌入式数据库。 Berkeley DB的一个很重要的特点是就是高速存储。在高流量,高并发的情况下,Berkeley DB要比非嵌入式的数据库表现得更加出色。所以在一些技术实现上,Berkeley DB被作为大型关系数据库的中间数据缓冲层,用来快速的保存数据,可能会在适当的时刻再导入到大型数据库中,进而应用大型数据库所提供的更为高级的特性。
  Berkeley DB虽然是开源的产品,但对某些条件下的商业性应用,却不是免费的,而且价格颇为昂贵。这些商业条件排除了开源的情况,不发放分布版本的情况,等等。比 如,如果你的程序是开放源代码的或者仅仅应用到单一的网站上,在这种情况下,Berkeley DB是免费的。
  2. 获得Java与Berkeley DB的接口
  Berkeley DB目前的版本是4.1.25,自带了Java接口。下载的压缩包中包含C和Java语言的源代码和编译配置文件。在Windows平台,可以用MS Visual C++ 6.0或MS VC.Net编译。用VC6编译的操作如下介绍:在源代码的build_win32路径下打开VC的工程文件,之后在Build菜单中的Set Active Configuration选择db_java win32 release编译选项。在VC的Tools菜单Options选项中指定JNI.H等Java本地化接口编译时所需要头文件的位置。
  你会在JDK的 include路径下找到这些头文件, 例如加入的路径可能会是这样的:C:\jdk1.4\include和C:\jdk1.4\include\ win32。最后在Tools菜单中Options选项还要设置Javac.exe和Jar.exe的执行路径,这个设置会使VC开发环境也能调用 Java编译器,从而在VC环境下直接完成对Java接口类的编译和打包。在编译后,在release路径下的文件中找到db.jar, libdb41.dll, libdb_java41.dll,这三个文件组成了Berkeley DB的Java接口程序包。
  3. 应用Java与Berkeley DB的接口
  Berkeley DB并不是一个关系型的数据库。不能应用标准的SQL语句对数据库操作,对它的操作要调用专用的API实现。这些API提供了查询、插入、删除等功能。比 如com.sleepycat.db.Db类代表数据库对象。Db类的put()方法完成的是插入功能,get()方法完成的是读出数据的功能。 com.sleepycat.db.Dbc是Berkeley DB的游标类,提供了遍历数据库记录的功能。
  Berkeley DB每一个记录都有一个键值和对应的数据值,而键值和数据必须是类com.sleepycat.db.Dbt的对象或其子类的对象。Dbt提供了一些方法 可以将byte数组或Object对象保存到Dbt的对象中去。比如,Dbt类中的set_data(byte[])或set_object (Object)方法。注意到目前Berkeley DB中的Java API命名方法并不符合Java的命名规范,比如set_data()方法应该命名为setData()方法。Berkeley DB许诺在下一个版本中会提供符合命名规范的Java API。
  Berkeley DB对任何存入的数据都是直接原样存储到数据文件中去,无论其是二进制数据还是ASCII或Unicode等编码的文本。通常可以利用这一特性和Java串行化的概念方便的进行数据的存取。例如声明一个类
1. public class AccountInfo implements Serializable{
2. //帐户信息
3. public String loginN
4. public S
5. public boolean auotL
  在 这个 AccountInfo类中仅仅包含了数据项的定义。我们完全可以将这个类看作数据库的表中字段定义。可以用Berkeley DB保存AccountInfo对象的串行化二进制数据,以此来保存这个对象中的变量值。在操作中,先对Dbt的对象调用set_object (AccountInfo)方法,而后把这个Dbt对象作为一条纪录保存到表中。当然,我们也可以应用继承Dbt类的方法来完成对数据的保存。
  下面这段简单代码演示如何将数据存入到数据库中,然后再用游标对象浏览全部数据。
1. //注意,下面的程序的忽略了对异常处理,写入数据初始化等等一些代码,请在适当修改后再编
2. //译运行它
3. Db dbFile = null;
4. //生成Db对象
5. dbFile = new Db(null, 0);
6. //用BTree方式打开数据库,库文件是在c:/temp下的mydata.db文件,表名是employee
7. //如果数据库不存在,则自动生成一个新的数据库。
8. dbFile.open(null,"c:\\temp\\mydata.db","employee",Db.DB_BTREE,
9. Db.DB_CREATE,0);
10. Dbt key = new Dbt();
11. Dbt data = new Dbt();
12. //向库文件中插入一条数据,如果已经存在,打印出错信息
13. if (dbFile.put(null,key, data, Db.DB_APPEND) == Db.DB_KEYEXIST) {
14. System.out.println("Key already exists.");
16. //关闭数据文件
17. dbFile.close(0);
18. //重新打开数据文件
19. dbFile = new Db(null, 0);
20. dbFile.open(null, "c:\\temp\\mydata.db", "employee", Db.DB_UNKNOWN,
21. 0, 0644);
22. // 声明一个数据库游标Dbc对象iterator
23. Dbc iterator = dbFile.cursor(null, 0);
24. // 遍历整个表
25. Dbt key = new Dbt();
26. while (iterator.get(key, data, Db.DB_NEXT) == 0)
28. System.out.println("reading");
30. //关闭游标和数据文件
31. iterator.close();
32. dbFile.close(0);
  在运行Berkeley DB的程序时勿必在系统环境变量PATH中设置libdb41.dll和 libdb_java41.dll所在的路径。
  4. Berkeley DB的存储模式
  Berkeley DB提供了四种存储数据的模式:Btree,Hash,Queue和Recno。在打开数据库的时候要指定一种存储模式,比如上例中open()方法中的参数Db.DB_BTREE就是指定以Btree模式打开数据库。
  Btree 模式是以排序的二叉树的方式存储,Hash是以线性哈希表的方式存储。Queue用逻辑记录号做为键值,以定长的数据为记录值。Recno方式也以逻辑记 录号做为键值,但可以保存定长或变长的记录值。这里提到的逻辑记录号有两种,可变的和固定的。可变逻辑记录号会根据数据记录的增加与删除做相应的变化。比 如在数据库中共有100条记录,如果删除第80条记录,那么第81条记录的逻辑记录号会自动变成80,以此类推,第100条记录逻辑记录号会变成99。固 定的逻辑记录号则无论数据库如何操作都不会有变化。Queue模式下,逻辑记录号只能是固定方式。 Recno模式则可通过配置来选择是采用那种类型的记录号作为键值。Btree模式也可以通过设置,将可变的逻辑记录号做为键值。
  这几种 存储模式各有优缺点,要根据具体的需求来选择。当键值不想用逻辑记录号时Btree或Hash是必须的选择。 Btree方式比较适合连续的顺序读取,比如,当键值是时间值,如果经常有从某一时间点开始连续读取后继的记录的操作,Btree是一种很好的选择。对随 机的跳跃式读取,Hash模式则更为恰当。Queue和Recno都以记录号为键值,但前者适合先进先出的读取方式。Recno则通常是存取变长文本记录 的理想存储模式。
  5. Berkeley DB Environment的概念
  Berkeley DB Environment为一组数据库同时提供参数设置。更为重要的是,如果要应用更高级的特性,必须要使用Environment功能,比如在想要对保存的数据进行加密存储时。
  6. 更多特点
  除了最基本的插入、查询、删除功能以外,Berkeley DB还提供了一些特性,比如Transaction,数据加密,同步加锁控制,错误日志等功能。下面的图片是Berkeley DB功能示意图。
  二. SQLite
  1. 简介
  相信PHP的开发人员一定不会对SQLite感到陌生,因为在PHP5中已经集成了这个轻巧的内嵌式数据库产品。SQLite与Berkeley DB相比,在操作语句上更类似关系型数据库的产品。绝大多数标准的SQL92语句SQLite都能支持。
  SQLite 的版权允许无任何限制的应用,包括商业性的产品。在参考链接二上提供的SQLite官方主站上可以下载到编译后的SQLite程序。但推荐应用CVS工具 下载最新版本的SQLite源代码。如果在*nux平台下,可直接用make编译。如果在Windows 平台,常用的有两种方法,一是应用在Windows平台下的Linux仿真程序,如MingW或Cygwin提供的make来编译。
  二是应用MS VC平台编译。后者设置略有麻烦,但可仿照参考链接五上提供的MS VC6工程文件的样例。应用到这个样例的时候,要注意的是由于SQLite源代码在不断更新,如果直接应用样例所提供的VC6工程文件编译会出现一些问 题,读者要根据具体的情况稍微调整一下编译的设置。
  2. 编译第三方Java接口
  SQLite 源代码是C,而且官方网站上只提供了C和Tcl语言的接口。为了应用Java接口,要采用第三方的接口驱程,可在参考链接三中找到这个Java接口程序。 这个接口提供了两种连接SQLite的方式:一是直接用JNI技术调用SQLite的C语言接口,这种方式要求开发人员要对SQLite本身的API也有 一定的了解。在第二种方式中,接口程序实现了Java标准规范的JDBC接口,这样开发人员只要对JDBC有了解就可以了。
  下面介绍在Windows系统MS VC6环境中编译SQLite Java接口(同时包括JNI和JDBC两个接口)的过程。如果你对C语言编译的设置很熟悉,可以跳这这段介绍。
  第 一步先把SQLite源代码编译成Lib静态库文件。具体的步骤可以直接应用下面参考链接中提供的MS VC6工作区文件,其中有一个编译SQLite到静态库的设置。编译成功后得到SQLite.lib文件。
  第二步要建立一个新的VC DLL项目,然后和上面介绍的Berkeley DB在编译Java本地化接口的设置一样,在VC的Tools菜单Options选项中指定JNI.H等JNI编译所要的头文件位置。同时还要指定 sqlite.h头文件位置,这个文件是在生成SQLite静态库的时候自动生成的,可以在SQLite.lib文件所在的工作区目录下面找到它,例如加 入的路径为C:\sqlite\msvc6。然后在Project菜单的setting选项设置Link到SQLite.lib库文件,并再次在 Tools菜单中Options指定SQLite.lib的查找路径。注意有些情况下可能要设置予编译选项HAVE_SQLITE_COMPILE以便使 用SQLite中VM的一些功能。编译成功后可得到Sqlite_jni.dll文件。
  第三方接口库中的Java代码包含JNI接口和多个版本的JDBC接口程序,可根据你的JRE的版本选择相应的JDBC程序。编译这些Java代码的过程这里就不做叙述了。
  编译后的Java类包加上前面得到的Sqlite_jni.dll文件,组成了SQLite的Java接口库,在应用Java语言调用JDBC或JNI接口时,都是通过应用Java的本地化技术调用Sqlite_jni.dll文件,完成对SQLite数据库的操作。
  3. 应用JNI直接调用SQLite功能
  下面这段代码演示如何应用JNI接口操作SQLite。可以看到Database类的exec()方法是执行SQL语句的关键:
1. Database db = new Database();
3. //打开数据库
4. db.open("c:\\temp\\mydata.slt", 0666);
5. db.interrupt();
6. db.busy_timeout(1000);
7. db.busy_handler(null);
8. db.exec("create table account (name varchar(10),gale boolean)"
9. ,result);
10. db.exec("insert into account values('steve','m')", result);
11. db.exec("select * from account",result);
12. //关闭数据库
13. db.close();
14. } catch (Exception e) {
15. e.printStackTrace();
  4. 应用JDBC连接SQLite
  用"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的例程:
1. //声明JDBC驱动程序
2. Class clz = Class.forName("SQLite.JDBCDriver");
3. //连接数据库
4. Connection conn = DriverManager.getConnection("jdbc:sqlite:/c:/temp/e2.db");
5. Statement stmt = conn.createStatement();
6. //生成person表,包含名子和年龄字段
7. stmt.execute("create table person (name varchar(100),age int)");
8. //插入数据
9. stmt.execute("insert into person values('steve',25)");
10. //用SQL语句读出数据
11. result = stmt.executeQuery("select * from person");
12. while(result.next()){
13. System.out.println(result.getString(1));
14. System.out.println(result.getInt(2));
  运行程序时要在 Java.exe命令行加入选项java.library.path指定到Sqlite_jni.dll所在的路径。例如,如果 Sqlite_jni.dll放在c:\sqliteNative 路径下面,运行类com.e2one.MyClass 的命令行将会是这样:java -Djava.library.path=c:\sqliteNative com.e2one.MyClass。
  5. SQLite的特点
  SQLite 是无数据类型的数据库。虽然在生成表结构的时候,要声明每个域的数据类型,但SQLite并不做任何检查。开发人员要靠自己的程序控制输入与读出数据的类 型是正确的。这里有一个例外,就是当主键为整型值时,如果要插入一个非整型值时会产生异常。另外,虽然在插入或读出数据的时候是不区分类型的,但在比较的 时候,不同数据类型是有区别的。比如:
1. CREATE TABLE MyTable(a INTEGER, b TEXT);
2. INSERT INTO MyTable VALUES(0,0);
  当执行下面的查询:
1. SELECT count(*) FROM MyTable WHERE a=='00';
  会返回一条记录,因为字段a的类型是整型,而数字00与0是相等的。
  而执行下面的查询则不会返回记录:
1. SELECT count(*) FROM MyTable WHERE b=='00';
  因为字段b是字符类型,字符"00"与"0"是不相等的。
  SQLite提供了对Transaction的支持。应用Transaction即保证了数据的完整性,也会提高运行速度,因为多条语句一起提交给数据库的速度会比一条一条的提交方式更快。
  对 二进制数据,SQLite不能直接保存。但可以先将二进制的数据转换成ASCII编码,然后再保存。Base64编码机制是最常见的把二进制数据转换成 ASCII编码的手段。在SQLite的C语言代码encode.c中提供了Base64编码的功能。对Java而言,在参考链接六中提供的Apache 的XML RPC项目中可以找到一个Base64编码的例子。
  上面介绍了两个比较常见的嵌入式数据库,Berkeley DB速度极快,可靠性高,但学习起来有一定难度。SQLite则简单易用,速度也很快,又可以应用标准的JDBC连接,但它功能却照Berkeley略有逊色,比如二进制数据的处理等。
数据库热门文章
数据库最新文章

我要回帖

更多关于 安卓sqlite数据库 的文章

 

随机推荐