SQLite总结

SQLite总结,第1张

概述SQLite Database SQLite is an embedded relational database engine. Its developers call it a self-contained, serverless, zero-configuration and transactional SQL database engine. 其实只需要记住SQLite不需要数据库服务器, sqlite Database sqlite is an embedded relational database engine. Its developers call it a self-contained,serverless,zero-configuration and transactional sql database engine. 其实只需要记住sqlite不需要数据库服务器,不需要额外配置,其数据库本身就是一个文件的一个小型数据库。 通常情况下在androID中创建数据库,系统会在"DATA/data/APP_name/databases".目录为我们创建数据库文件。 sqlite BasicdataTypes
sqlite支持的数据类型有很多,但他们总共可以分为以下几类:
desc <table> //查看表结构
select * from <table> //查询所有更
select,from table ;//查看指定列
select distinct,from table ;//非重复查询
insert into users(_ID,username,password) select * from users;//复制
select username from users where username like 'S%' ;//非重名字首字母为大写S的用户
select username from users where username like '__S%' ;//非重名字第三个字母为大写S的用户
select * from users where _ID in(001,220,230);
select * from user order by _ID;//以ID的顺序排列
select * from user order by _ID desc;//以ID反的顺序排 复制代码
常用Select语句
图形环境 很少有人直接在程序当中直接编写SQL语句,麻烦且容易出错。所以最好应该先在一个图形化的环境把SQL语句写好,测试好再加入到代码当中。 而且,sqlite数据库本身就是一个独立的文件,很容易从模拟器上抓取出来。可以使用图形化界面进行分析,和修改 etc.
sqlite expert 是个简单小巧的sqlite数据库管理软件,有免费版和,收费版两种,一般来讲免费版足以应付我们需求。
sqliteexpert官方网址
软件界面截图 使用sqlite expert 创建一张table,并让它为我们生成所需的SQL语句 下面的例子,我们创建一张表用来存储用户的用户名和密码;数据库名"users",表名"user_accounts",有三个列:row_ID INTEGER自增类型的主键,usernameTEXT类型 用来保存用户名,passwordTEXT类型,用来保存用户密码; 创建表格
为了创建一张table 首先要有一个数据库文件,点击"file"->""New Database然后选择文件的路径,点击OK便创建了一个数据库文件 创建完数据库之后创建表格,右击数据库文件名选择"New table"如下图所示:

这时我们便进入了"设计状态",填写表名(user_accounts),点击"Add",在name中填写"row_ID",Type选择Integer,如下图所示: 因为row_ID这个列比较特殊是我们的索引的主键,所以还要点击"Index",之后会看到下图: 左边的Available FIElds 中有我们刚刚创建的row_ID,点击"Add"把row_ID加入右边的Index FIElds当中。这时上面的Primary和autoIncrement会变成可先状态 ,勾选Primary和autoIncrement点击OK; 再回到FIEld当中创建其它两列,分别为username类型为TEXT,password类型也为TEXT,但不需要创建Index; 完成之后点击Apply,这样我们便使用sqlite expert创建一张表格,点击DDL,我们可以看到sqlite expert已经为我们生成好了生成这张表格所需的SQL语句: 在androID中需要代码生成表格时,只要把这段代码复制过去,就可以了。 增加用户
点击sql,执行以下SQL语句,为表格增加一个用户:

INSERT INTO user_accounts(row_ID,password) VALUES(001,'John','abcdef'); 复制代码 点击Data会发现数据库里边增加了一个用户名为John的用户。为了练习,我们不妨再增加两个用户,DavID和Sarah

复制代码 删除用户
执行下面的语句删除用户DavID:

DELETE FROM user_accounts WHERE username = 'DavID'; 修改密码
执行以下语句修改Sarah的密码:

update user_accounts SET password='666666' WHERE username = 'Sarah'; 复制代码 查看所用户信息可以使用如下语句查看表内所有用户的信息: SELECT * FROMM user_accounts; 一般来讲select * 的语句只在测试的时候时候,在正式代码中不推荐使用。 查看指定列的内容执行以下语句查看所有用户的用户名和密码: SELECT username,password FROM user_accounts; 这时个就发现row_ID列没有显示出来。 查询特定条件的信息
sql可以通过给定查询条件进行精确查找,比如我们只需要John的密码。就可以使用这样的语句

SELECT password FROM user_accounts WHERE username = 'John'; 以下流程图,来源于sqlite官方文档 Create table Statement column-def type-name
column-constraint
table-constraint
forIEgn-key-clause Insert Statement Delete Statement qualifIEd-table-name Update Statement Select Statement select-core result-column join-source single-source join-op join-constraint ordering-term compound-operator Dealing with large amount of data分页当数据库数据量很大时,分页显示是个很简单且符合人们习惯的一种处理方法。
获取数据行总数:

最简单的方法是:SELECT所有的行,再调用curosr.getCount() ;取得行数,但这样效率会很低。 sqlite为我们提供了一个函数很容易查出总共有多少行。有个名为cet6_table的表格,我们想知道总共有多少行的word;可以使用如下 语句来完成:

SELECT count(word) AS number FROM cet6_table;
count()函数为我们返回一个Int整形,代表有多少行数据。返回的列的名字叫count(word),为了方便阅读和处理用as number给这个列取个 别名number; SELECT [word],[explanation] FROM cet6_table ORDER BY word liMIT 100 OFFSET 200" 上语句,返回自第200行的最多100条数据。分页时我们只要修改offset 后面的数据即可取得对应页面的数据。
详情见示例程序!
多线程自带数据库
有些程序比如,字典,输入法等程序会在apk中带有数据库。思路很简单,把预先准备好的数据库放入asset或者raw目录当中 使用时复制到对应的手机目录上;再打开。以下代码会把raw目录中的名为cet6的数据库文件写入sd卡根目录并打开。 对于一些常用或者比较重要的数据建议放在程序的私有目录当中。

public voID init(Context context) {
try {
String databasePath = Environment.getExternalStorageDirectory().getabsolutePath();
String databasefilename = databasePath + "/" + DATABASE_filename;
file dir = new file(databasePath);
if (!dir.exists()){
dir.mkdir();
}
if (!(new file(databasefilename)).exists()) {
inputStream is = context.getResources().openRawResource(
R.raw.cet6);
fileOutputStream fos = new fileOutputStream(databasefilename);
byte[] buffer = new byte[1024];
int count = 0;
while ((count = is.read(buffer)) > 0) {
fos.write(buffer,count);
}
fos.flush();
fos.close();
is.close();
mCet6Db = sqliteDatabase.openorCreateDatabase(databasefilename,
null);
} catch (Exception e) {
e.printstacktrace();
} 单词提示,IME使用autoCompleteText + sqlite很容易实现类似于baIDu ,Google等搜索时出现的提示文字。 输入法也是同样的原理,以拼音或五笔等作为索引,非常容易实现。可以加一个列标明一个字被选择的次数, 在select的时候可以按照这个列来排序,这样可以保存用户的习惯;作出来的输入法将更人性化。因为输入法的查询量比较大 可以考虑把数据库文件放入内存当中,sqlite本身是支持内存数据库的。但androID中封装上没有提供这一功能,而且sqliteDataBase类 很多核心功能都是通过JNI实现的,所以要把数据库搬入内存还需编写c/c++的代码。也可以考虑使用Lucene的全文搜索功能来实现。Date
sqlite有很多函数支持日期的方便处理。

%d day of month: 00
%f fractional seconds: SS.SSS
%H hour: 00-24
%j day of year: 001-366
%J Julian day number
%m month: 01-12
%M minute: 00-59
%s seconds since 1970-01-01
%s seconds: 00-59
%w day of week 0-6 with Sunday==0
%W week of year: 00-53
%Y year: 0000-9999
%% % sqlite支持以下格式的日期: YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM //T 就是字母T,用于分开日期和时间
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM
HH:MM:SS
HH:MM:SS.SSS
Now
ddddddddDD //is the Julian day number expressed as a floating point value. strftime('%Y-%m-%d',column_name)方法可以很方便的对日期进行格式化,而不用Java对String进行再处理。
ContentValues 不支持直接把datetime('Now')之类函数作为值插入数据库。 比如想把当前系统时间插件数据库使用ContentValues:
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
ContentValues initialValues = new ContentValues();
initialValues.put("date_created",dateFormat.format(date));
long rowID = mDb.insert(DATABASE_table,null,initialValues); 或者如附带程序记事本程序一样使用exesql(sql); sqliteOpenHelper 上流程图来自O'REILLY 视频公开课"DeveloPing AndroID Applications with Java"中的视频截图
sqliteOpenHelper是androID框架为我们提供的一个数据库助手类。对于数据库的 *** 作一般都是从这个类继承。它主要负责数据库的创建,打开,更新 等一些 *** 作。
Singleton DAO
很多有j2ee背景的开发者都喜欢建立一个单例模式的数据库 *** 作类,专门处理数据库之间的交流。也有很多人把这个习惯带到的AndroID的开发当中。 而且我们也经常需要在几个Activity,Service同时访问一个数据库文件,所以经常能看到类似于这样的代码:

public class dbaccess {
class DbHelper extends sqliteOpenHelper {
//此处代码被省略
private static DB_name = "users";
private mDbHelper = null;
private static mdbaccess;//to make sure there is only one instance exist;

private dbaccess(Context context){
//private constructer;
if(mDbHelper == null){
mDbHelper = new DbHelper(context,DB_name);
public dbaccess getInstance(Context context){
if(mdbaccess == null){
mdbaccess = new dbaccess(context);
return mdbaccess;
//部分代码被省略
//insert
//delete
//update
//query
}
public class ActivityA extends Activity{
@OverrIDe
protected voID onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dao = dbaccess.getInstance(this);
////部分代码被省略
程序的流程应该是这样的: 假设ActivityA创建了Dao的对象,又开启了ServiceA,A使用了一段时间再跳转到了ActivityB与B再接着使用同一个Dao对象。ActivityA创建Dao对象的时候 把自己的引用向上转型成一个Context对象,Dao又用这个context创建了sqliteOpenHelper,所以sqliteOpenHelper就持有了ActivityA的引用。当ActivityA被销毁 之后因为单例的Dao保留有ActivityA的引用,所以ActivityA不能被GC所回收,造成整个Acitivity内存的泄漏。 解决方案
1,最简单的,不使用单例模式,因为sqliteOpenHelper保证了数据库的单例,所以实际上我们只是创建了多个sqliteOpenHelper的对象,数据库 对象本身还是单例的。缺点:会有一些重复的代码,并生成多个sqliteOpenHelper的子类对象。

2,把Dao对象放入Application当中,在Application的onCreate()中使用Application的Context进行初始化。优点,Application对象的创建在Activity和Service之前 所以保证了,Activity和Service等等使用时数据库已经准备好了。缺点:Application的生命周期是最长的,并且AndroID会尽量不让程序关闭,也就是尽量不 去销毁Application对象,所以数据库一直保持打开状态,依靠Application的onDestroy()关闭数据库,不确定的因素比较大,并且因为打开数据库的时候直接 影响程序启动时间。

3,先看一个问题,为什么sqliteOpenHelper需要一个Context对象?查看sqliteOpenHelper的源码发现如下代码:

sqliteDatabase db = null;
try {
mIsInitializing = true;
String path = mContext.getDatabasePath(mname).getPath();
db = sqliteDatabase.openDatabase(path,mFactory,sqliteDatabase.OPEN_Readonly);
if (db.getVersion() != mNewVersion) {
throw new sqliteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + path);
onopen(db);
Log.w(TAG,"Opened " + mname + " in read-only mode");
mDatabase = db; 所以我们可以自己仿照sqliteOpenHelper写一个不需要Context的助手类,大constructer当中把路径传进行,而不是一个context对象。缺点:需要考虑多线程同步等 很多因素,有一定的复杂度。 4,在创建Dao对象时,不使用Activity的引用作为Context,而是把Application作为Context传入Dao的构造函数中进行创建。优点,不会影响程序的启动时间。 缺点:对于数据库的关闭还是不确定。 5,在第四种方案的基础上加入计数器。第调用getInstance计数器自增,再加入一个release()方法,计数器自减,当计数器为0时,关闭数据库(或者当计数器为零且 过一段时间没有连接时关闭)。 总结

以上是内存溢出为你收集整理的SQLite总结全部内容,希望文章能够帮你解决SQLite总结所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1181126.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存