1. android开发 sqlite作用
SQLite简介
Google为Andriod的较大的数据处理提供了SQLite,他在数据存储、管理、维护等各方面都相当出色,功能也非常的强大。SQLite具备下列特点:
1.轻量级
使用 SQLite 只需要带一个动态库,就可以享受它的全部功能,而且那个动态库的尺寸想当小。
2.独立性
SQLite 数据库的核心引擎不需要依赖第三方软件,也不需要所谓的“安装”。
3.隔离性
SQLite 数据库中所有的信息(比如表、视图、触发器等)都包含在一个文件夹内,方便管理和维护。
4.跨平台
SQLite 目前支持大部分操作系统,不至电脑操作系统更在众多的手机系统也是能够运行,比如:Android。
5.多语言接口
SQLite 数据库支持多语言编程接口。
6.安全性
SQLite 数据库通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只能有一个可以写入数据。
Android中的SQLite使用
首先创建数据库类
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "mydata.db"; //数据库名称
private static final int version = 1; //数据库版本
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, version);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table user(username varchar(20) not null , password varchar(60) not null );";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
SQLiteOpenHelper类介绍
SQLiteOpenHelper是SQLiteDatabase的一个帮助类,用来管理数据库的创建和版本的更新。一般是建立一个类继承它,并实现它的onCreate和onUpgrade方法。
方法名
方法描述
SQLiteOpenHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version) 构造方法,一般是传递一个要创建的数据库名称那么参数
onCreate(SQLiteDatabase db) 创建数据库时调用
onUpgrade(SQLiteDatabase db,int oldVersion , int newVersion) 版本更新时调用
getReadableDatabase() 创建或打开一个只读数据库
getWritableDatabase() 创建或打开一个读写数据库
下面来介绍调用的方法
创建数据库
这里特别的地方是通过调用了SQLiteOpenHelper类的getReadableDatabase()方法来实现创建一个数据库的
1
2
3
DatabaseHelper database = new DatabaseHelper(this);//这段代码放到Activity类中才用this
SQLiteDatabase db = null;
db = database.getReadalbeDatabase();
SQLiteDatabase类为我们提供了很多种方法,而较常用的方法如下
(返回值)方法名
方法描述
(int) delete(String table,String whereClause,String[] whereArgs) 删除数据行的便捷方法
(long) insert(String table,String nullColumnHack,ContentValues values) 添加数据行的便捷方法
(int) update(String table, ContentValues values, String whereClause, String[] whereArgs) 更新数据行的便捷方法
(void) execSQL(String sql) 执行一个SQL语句,可以是一个select或其他的sql语句
(void) close() 关闭数据库
(Cursor) query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) 查询指定的数据表返回一个带游标的数据集
(Cursor) rawQuery(String sql, String[] selectionArgs) 运行一个预置的SQL语句,返回带游标的数据集(与上面的语句最大的区别就是防止SQL注入)
数据的添删改查分别可以通过2种途径来实现
数据的添加
1.使用insert方法
1
2
3
ContentValues cv = new ContentValues();//实例化一个ContentValues用来装载待插入的数据cv.put("username","Jack Johnson");//添加用户名
cv.put("password","iLovePopMusic"); //添加密码
db.insert("user",null,cv);//执行插入操作
2.使用execSQL方式来实现
1
2
String sql = "insert into user(username,password) values ('Jack Johnson','iLovePopMuisc');//插入操作的SQL语句
db.execSQL(sql);//执行SQL语句
数据的删除
同样有2种方式可以实现
1
2
3
String whereClause = "username=?";//删除的条件
String[] whereArgs = {"Jack Johnson"};//删除的条件参数
db.delete("user",whereClause,whereArgs);//执行删除
使用execSQL方式的实现
1
2
String sql = "delete from user where username='Jack Johnson'";//删除操作的SQL语句
db.execSQL(sql);//执行删除操作
数据修改
同上,仍是2种方式
1
2
3
4
5
ContentValues cv = new ContentValues();//实例化ContentValues
cv.put("password","iHatePopMusic");//添加要更改的字段及内容
String whereClause = "username=?";//修改条件
String[] whereArgs = {"Jack Johnson"};//修改条件的参数
db.update("user",cv,whereClause,whereArgs);//执行修改
使用execSQL方式的实现
1
2
String sql = "update [user] set password = 'iHatePopMusic' where username='Jack Johnson'";//修改的SQL语句
db.execSQL(sql);//执行修改
数据查询
数据查询相对前面几种方法就复杂一些了,因为查询会带有很多条件
通过query实现查询的
public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
各参数说明:
table:表名称
colums:列名称数组
selection:条件子句,相当于where
selectionArgs:条件语句的参数数组
groupBy:分组
having:分组条件
orderBy:排序类
limit:分页查询的限制
Cursor:返回值,相当于结果集ResultSet
针对游标(Cursor)也提供了不少方法
方法名称
方法描述
getCount() 总记录条数
isFirst() 判断是否第一条记录
isLast() 判断是否最后一条记录
moveToFirst() 移动到第一条记录
moveToLast() 移动到最后一条记录
move(int offset) 移动到指定的记录
moveToNext() 移动到吓一条记录
moveToPrevious() 移动到上一条记录
getColumnIndex(String columnName) 获得指定列索引的int类型值
实现代码
1
2
3
4
5
6
7
8
Cursor c = db.query("user",null,null,null,null,null,null);//查询并获得游标
if(c.moveToFirst()){//判断游标是否为空
for(int i=0;i<c.getCount();i++){
c.move(i);//移动到指定记录
String username = c.getString(c.getColumnIndex("username");
String password = c.getString(c.getColumnIndex("password"));
}
}
通过rawQuery实现的带参数查询
1
2
3
4
Cursor c = db.rawQuery("select * from user where username=?",new Stirng[]{"Jack Johnson"});
if(cursor.moveToFirst()) {
String password = c.getString(c.getColumnIndex("password"));
}
2. android sqlite怎么实现
数据库的创建
创建文件
1.声明文件对象,文件是不会被创建出来的。
File file = new File("文件名称");
2.写文件(文件才会被创建出来)
FileOutputStream fos = new FileOutputStream(file);
fos.write("hdahfdsaklfh".getbytes());
创建数据库
1.实现SQLiteOpenHelper的子类PersonSQLiteOpenHelper
java">{
publicPersonSQLiteOpenHelper(Contextcontext,Stringname,
CursorFactoryfactory,intversion){
super(context,name,factory,version);
//TODOAuto-generatedconstructorstub
}
@Override
publicvoidonCreate(SQLiteDatabasearg0){
//TODOAuto-generatedmethodstub
}
@Override
publicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){
//TODOAuto-generatedmethodstub
}
}
2.getWritableDatabase/getReadableDatabase()
新建TestPersonDB.java
//.
//在数据库第一次创建的时候执行的方法
//如果数据库已经创建完毕,就不会再去执行了。
//适合做数据库表结构的初始化操作
//db代表的就是当前的数据库
@Override
publicvoidonCreate(SQLiteDatabasedb){
//初始化数据库的表结构
db.execSQL("createtableperson(,namevarchar(20),numbervarchar(20))");
}
3. android sqlite数据库的更新
一、使用嵌入式关系型SQLite数据库存储数据
在Android平台上,集成了一个嵌入式关系型数据库——SQLite,SQLite3支持NULL、INTEGER、REAL(浮点数字)、 TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上sqlite3也接受varchar(n)、 char(n)、decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型。 SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么。例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段保存除整数以外的数据时,将会产生错误。 另外,在编写CREATE TABLE 语句时,你可以省略跟在字段名称后面的数据类型信息,如下面语句你可以省略name字段的类型信息:
CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))
SQLite可以解析大部分标准SQL语句,如:
复制代码 代码如下:
查询语句:select * from 表名 where 条件子句 group by 分组字句 having ... order by 排序子句
如: select * from person
select * from person order by id desc
select name from person group by name having count(*)>1
分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录
select * from Account limit 5 offset 3 或者 select * from Account limit 3,5
插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person(name, age) values(‘传智',3)
更新语句:update 表名 set 字段名=值 where 条件子句。如:update person set name=‘传智‘ where id=10
删除语句:delete from 表名 where 条件子句。如:delete from person where id=10
二、使用SQLiteOpenHelper对数据库进行版本管理
我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软件时创建出应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数据表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手机上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工方式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在Android系统,为我们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库版本进行管理来实现前面提出的需求。
为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如果你愿意,设置为100也行),并且在 onUpgrade()方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后作出相应的表结构及数据更新。
getWritableDatabase()和 getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。但 getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。
注意:getWritableDatabase(),getReadableDatabase的区别是当数据库写满时,调用前者会报错,调用后者不会,所以如果不是更新数据库的话,最好调用后者来获得数据库连接。
代码:
复制代码 代码如下:
public class DatabaseHelper extends SQLiteOpenHelper {
//类没有实例化,是不能用作父类构造器的参数,必须声明为静态
private static final String name = "ljqdb"; //数据库名称
private static final int version = 1; //数据库版本
public DatabaseHelper(Context context) {
//第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类
super(context, name, null, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS person (
personid integer primary key autoincrement, name varchar(20), age INTEGER)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(" ALTER TABLE person ADD phone VARCHAR(12) NULL "); //往表中增加一列
// DROP TABLE IF EXISTS person 删除表
}
}
在实际项目开发中,当数据库表结构发生更新时,应该避免用户存放于数据库中的数据丢失。
三、使用SQLiteDatabase操作SQLite数据库
Android提供了一个名为SQLiteDatabase的类,该类封装了一些操作数据库的API,使用该类可以完成对数据进行添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)操作(这些操作简称为CRUD)。对SQLiteDatabase的学习,我们应该重点掌握execSQL()和rawQuery()方法。execSQL()方法可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句; rawQuery()方法用于执行select语句。
execSQL()方法的使用例子:
复制代码 代码如下:
SQLiteDatabase db = ....;
db.execSQL("insert into person(name, age) values('林计钦', 24)");
db.close();
执行上面SQL语句会往person表中添加进一条记录,在实际应用中, 语句中的“林计钦”这些参数值会由用户输入界面提供,如果把用户输入的内容原样组拼到上面的insert语句, 当用户输入的内容含有单引号时,组拼出来的SQL语句就会存在语法错误。要解决这个问题需要对单引号进行转义,也就是把单引号转换成两个单引号。有些时候用户往往还会输入像“ & ”这些特殊SQL符号,为保证组拼好的SQL语句语法正确,必须对SQL语句中的这些特殊SQL符号都进行转义,显然,对每条SQL语句都做这样的处理工作是比较烦琐的。 SQLiteDatabase类提供了一个重载后的execSQL(String sql, Object[] bindArgs)方法,使用这个方法可以解决前面提到的问题,因为这个方法支持使用占位符参数(?)。使用例子如下:
复制代码 代码如下:
SQLiteDatabase db = ....;
db.execSQL("insert into person(name, age) values(?,?)", new Object[]{"传智播客", 4});
db.close();
execSQL(String sql, Object[] bindArgs)方法的第一个参数为SQL语句,第二个参数为SQL语句中占位符参数的值,参数值在数组中的顺序要和占位符的位置对应。
SQLiteDatabase的rawQuery()用于执行select语句,使用例子如下:
复制代码 代码如下:
SQLiteDatabase db = ....;
Cursor cursor = db.rawQuery("select * from person", null);
while (cursor.moveToNext()) {
int personid = cursor.getInt(0); //获取第一列的值,第一列的索引从0开始
String name = cursor.getString(1);//获取第二列的值
int age = cursor.getInt(2);//获取第三列的值
}
cursor.close();
db.close();
rawQuery()方法的第一个参数为select语句;第二个参数为select语句中占位符参数的值,如果select语句没有使用占位符,该参数可以设置为null。带占位符参数的select语句使用例子如下:
复制代码 代码如下:
Cursor cursor = db.rawQuery("select * from person where name like ? and age=?", new String[]{"%林计钦%", "4"});
Cursor是结果集游标,用于对结果集进行随机访问,如果大家熟悉jdbc, 其实Cursor与JDBC中的ResultSet作用很相似。使用moveToNext()方法可以将游标从当前行移动到下一行,如果已经移过了结果集的最后一行,返回结果为false,否则为true。另外Cursor 还有常用的moveToPrevious()方法(用于将游标从当前行移动到上一行,如果已经移过了结果集的第一行,返回值为false,否则为true )、moveToFirst()方法(用于将游标移动到结果集的第一行,如果结果集为空,返回值为false,否则为true )和moveToLast()方法(用于将游标移动到结果集的最后一行,如果结果集为空,返回值为false,否则为true ) 。
除了前面给大家介绍的execSQL()和rawQuery()方法, SQLiteDatabase还专门提供了对应于添加、删除、更新、查询的操作方法: insert()、delete()、update()和query() 。这些方法实际上是给那些不太了解SQL语法的菜鸟使用的,对于熟悉SQL语法的程序员而言,直接使用execSQL()和rawQuery()方法执行SQL语句就能完成数据的添加、删除、更新、查询操作。
4. 有熟悉Sqlite的吗请教个Android Sqlite安全性方面的问题
1.这个基本会发生的2.3 你要知道,一个APP仅仅只能访问自己的数据,你知道数据库文件放在哪儿吗? 在这个下面/data/data/报名/database/,所以就保证了,每一个APP的数据库是不影响的,每一个APP相互调用自己的数据库文件,所以你说的2、3问题基本可以忽略了。如果你想看的/data/data/报名/database/的话,记得把你的手机root后就可以看到了,4.不敏感,SQL都貌似是不敏感的 查看原帖>>
5. 如何使用SQLite,Android上SQLite的最佳实践
SQLite3是目前最新的SQLite版本。可以从网站上下载SQLite3的源代码(本书使用的版本是sqlite-3.6.12.tar.gz)。
解压缩后进入sqlite-3.6.12的根目录,首先命令“./configure”生成Makefile文件,接着运行命令“make”对源代码进行编译,最后运行命令“make install”安装SQLite3。安装完毕后,可以运行命令sqlite3查看SQLite3是否能正常运行,如下所示:
[root@localhost ~]# sqlite3
SQLite version 3.6.12
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>
可以看到,SQLite3启动后会停留在提示符sqlite>处,等待用户输入SQL语句。
在使用SQLite3前需要先了解下SQLite3支持的数据类型。SQLite3支持的基本数据类型主要有以下几类:
NULL
NUMERIC
INTEGER
REAL
TEXT
SQLite3会自动把其他数据类型转换成以上5类基本数据类型,转换规则如下所示:
char、clob、test、varchar—> TEXT
integer—>INTEGER
real、double、float—> REAL
blob—>NULL
其余数据类型都转变成NUMERIC
下面通过一个实例来演示SQLite3的使用方法。
新建一个数据库
新建数据库test.db(使用.db后缀是为了标识数据库文件)。在test.db中新建一个表test_table,该表具有name,、sex、age三列。SQLite3的具体操作如下所示:
[root@localhost home]# sqlite3 test.db
SQLite version 3.6.12
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> create table test_table(name, sex, age);
如果数据库test.db已经存在,则命令“sqlite3 test.db”会在当前目录下打开test.db。如果数据库test.db不存在,则命令“sqlite3 test.db”会在当前目录下新建数据库test.db。为了提高效率,SQLite3并不会马上创建test.db,而是等到第一个表创建完成后才会在物理上创建数据库。
由于SQLite3能根据插入数据的实际类型动态改变列的类型,所以在create语句中并不要求给出列的类型。
创建索引
为了加快表的查询速度,往往在主键上添加索引。如下所示的是在name列上添加索引的过程。
sqlite> create index test_index on test_table(name);
操作数据
如下所示的是在test_table中进行数据的插入、更新、删除操作:
sqlite> insert into test_table values ('xiaoming', 'male', 20);
sqlite> insert into test_table values ('xiaohong', 'female', 18);
sqlite> select * from test_table;
xiaoming|male|20
xiaohong|female|18
sqlite> update test_table set age=19 where name = 'xiaohong';
sqlite> select * from test_table;
xiaoming|male|20
xiaohong|female|19
sqlite> delete from test_table where name = 'xiaoming';
sqlite> select * from test_table;
xiaohong|female|19
批量操作数据库
如下所示的是在test_table中连续插入两条记录:
sqlite> begin;
sqlite> insert into test_table values ('xiaoxue', 'female', 18);
sqlite> insert into test_table values ('xiaoliu', 'male', 20);
sqlite> commit;
sqlite> select * from test_table;
xiaohong|female|19
xiaoxue|male|18
xiaoliu|male|20
运行命令commit后,才会把插入的数据写入数据库中。
数据库的导入导出
如下所示的是把test.db导出到sql文件中:
[root@localhost home]# sqlite3 test.db ".mp" > test.sql;
test.sql文件的内容如下所示:
BEGIN TRANSACTION;
CREATE TABLE test_table(name, sex, age);
INSERT INTO "test_table" VALUES('xiaohong','female',19);
CREATE INDEX test_index on test_table(name);
COMMIT;
如下所示的是导入test.sql文件(导入前删除原有的test.db):
[root@localhost home]# sqlite3 test.db < test.sql;
通过对test.sql文件的导入导出,可以实现数据库文件的备份。
11.2.2 SQLite3的C接口
以上介绍的是SQLite3数据库的命令操作方式。在实际使用中,一般都是应用程序需要对数据库进行访问。为此,SQLite3提供了各种编程语言的使用接口(本书介绍C语言接口)。SQLite3具有几十个C接口,下面介绍一些常用的C接口。
sqlite_open
作用:打开SQLite3数据库
原型:int sqlite3_open(const char *dbname, sqlite3 **db)
参数:
dbname:数据库的名称;
db:数据库的句柄;
sqlite_colse
作用:关闭SQLite3数据库
原型:int sqlite_close(sqlite3 *db)
例如:
test.c:
#include <stdio.h>
#include <sqlite3.h>
static sqlite3 *db=NULL;
int main()
{
int rc;
rc= sqlite3_open("test.db", &db);
if(rc)
{
printf("can't open database!\n");
}
else
{
printf("open database success!\n");
}
sqlite3_close(db);
return 0;
}
运行命令“gcc –o test test.c –lsqlite3”进行编译,运行test的结果如下所示:
[root@localhost home]# open database success!
sqlite_exec
作用:执行SQL语句
原型:int sqlite3_exec(sqlite3 *db, const char *sql, int (*callback)(void*,int,char**,char**), void *, char **errmsg)
参数:
db:数据库;
sql:SQL语句;
callback:回滚;
errmsg:错误信息
例如:
test.c:
#include <stdio.h>
#include <sqlite3.h>
static sqlite3 *db=NULL;
static char *errmsg=NULL;
int main()
{
int rc;
rc = sqlite3_open("test.db", &db);
rc = sqlite3_exec(db,"insert into test_table values('bao', 'male', 24)", 0, 0, &errmsg);
if(rc)
{
printf("exec fail!\n");
}
else
{
printf("exec success!\n");
}
sqlite3_close(db);
return 0;
}
编译完成后,运行test的结果如下所示:
[root@localhost home]# ./test
exec success!
[root@localhost home]# sqlite3 test.db
SQLite version 3.6.11
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from test_table;
bao|male|24
sqlite3_get_table
作用:执行SQL查询
原型:int sqlite3_get_table(sqlite3 *db, const char *zSql, char ***pazResult, int *pnRow, int *pnColumn, char **pzErrmsg)
参数:
db:数据库;
zSql:SQL语句;
pazResult:查询结果集;
pnRow:结果集的行数;
pnColumn:结果集的列数;
errmsg:错误信息;
sqlite3_free_table
作用:注销结果集
原型:void sqlite3_free_table(char **result)
参数:
result:结果集;
例如:
test.c:
#include <stdio.h>
#include <sqlite3.h>
static sqlite3 *db=NULL;
static char **Result=NULL;
static char *errmsg=NULL;
int main()
{
int rc, i, j;
int nrow;
int ncolumn;
rc= sqlite3_open("test.db", &db);
rc= sqlite3_get_table(db, "select * from test_table", &Result, &nrow, &ncolumn,
&errmsg);
if(rc)
{
printf("query fail!\n");
}
else
{
printf("query success!\n");
for(i = 1; i <= nrow; i++)
{
for(j = 0; j < ncolumn; j++)
{
printf("%s | ", Result[i * ncolumn + j]);
}
printf("\n");
}
}
sqlite3_free_table(Result);
sqlite3_close(db);
return 0;
}
编译完成后,运行test的结果如下所示:
[root@localhost home]# ./test
query success!
xiaohong | female | 19 |
xiaoxue | female | 18 |
xiaoliu | male | 20 |
bao | male | 24 |
sqlite3_prepare
作用:把SQL语句编译成字节码,由后面的执行函数去执行
原型:int sqlite3_prepare(sqlite3 *db, const char *zSql, int nByte, sqlite3_stmt **stmt, const char **pTail)
参数:
db:数据库;
zSql:SQL语句;
nByte:SQL语句的最大字节数;
stmt:Statement句柄;
pTail:SQL语句无用部分的指针;
sqlite3_step
作用:步步执行SQL语句字节码
原型:int sqlite3_step (sqlite3_stmt *)
例如:
test.c:
#include <stdio.h>
#include <sqlite3.h>
static sqlite3 *db=NULL;
static sqlite3_stmt *stmt=NULL;
int main()
{
int rc, i, j;
int ncolumn;
rc= sqlite3_open("test.db", &db);
rc=sqlite3_prepare(db,"select * from test_table",-1,&stmt,0);
if(rc)
{
printf("query fail!\n");
}
else
{
printf("query success!\n");
rc=sqlite3_step(stmt);
ncolumn=sqlite3_column_count(stmt);
while(rc==SQLITE_ROW)
{
for(i=0; i<2; i++)
{
printf("%s | ", sqlite3_column_text(stmt,i));
}
printf("\n");
rc=sqlite3_step(stmt);
}
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
编译完成后,运行test的结果如下所示:
[root@localhost home]# ./test
query success!
xiaohong | female | 19 |
xiaoxue | female | 18 |
xiaoliu | male | 20 |
bao | male | 24 |
在程序中访问SQLite3数据库时,要注意C API的接口定义和数据类型是否正确,否则会得到错误的访问结果。
6. 如何在android自带的sqlite3中创建一个数据库文件,请大虾门详细指导
Android中提供4种数据存储的方法:(1)SharedPreferences,用键值对的方式来存储数据,是一种轻量级的存储机制,可以存储一些属性等。(2)Files:文件输入输出流的方式存储数据,FileInputStream和FileOutputStream。在Android中,文件是一个应用程序私有的,一个应用程序无法读写其他应用程序的文件。写入SD卡除外。(3)SQLite(4)网络(这个不算吧~~~--!)。
SQLite:
(1)创建和打开数据库可以使用方法openOrCreateDatabase,它会自动去检测是否存在数据库,如果存在则打开,如果不存在则创建一个数据库;成功返回一个SQliteDatabase对象。(2)创建一张表通过SQL语句实现,调用sqliteDatabase对象的execSQL方法,执行创建表的SQL语句。
(3)向数据表中添加一条记录可以直接通过SQL语句实现,也可以使用ContentValue对象,ContentValue对象是一个Map,Key是字段名,Value是值。Cv.put(key,value);然后调用sqliteDatabase对象的
insert(tableName,null,cv)方法插入数据。
(4)删除数据可以直接执行SQL,也可以执行sqliteDatabase的delete方法。
(5)同理修改数据也是执行SQL或调用update方法,需要传入ContenValue的对象表示修改的内容。
(6)关闭数据库sqliteDatabase.close();
(7)删除指定表调用SQL语句即可。
(8)查询:在Android中查询数据是通过Cursor类来实现的,当我们使用SQLiteDatabase.query()方法时,会得到一个Cursor对象,Cursor对象指向的是每条数据。例如cur.moveToFirst();cur.moveToNext();等。在实际开发中,为了能够更好地管理和维护数据库,我们会封装一个继承自SQLiteOpenHelper类的数据库操作类。SQLiteOpenHelper的构造方法中分别需要传入Context、数据库名称、CursorFactory(一般默认null)、数据库版本号。在SQLiteOpenHelper中首先执行的是onCreate方法(当数据库第一次被创建时)。在构造函数中并没有真正创建数据库,而是调用getWriteableDatabase或者getReadableDatabase方法时才真正去创建数据库,并且返回一个SQLiteDatabase对象。
7. android sqlite数据库怎么使用
其主要思路是:
1. 把数据库分解成几个asset文件。
2. 当需要打开数据库时,如果数据库不存在,就把那几个asset文件重新合并成一个数据库文件。
3. 如果数据库的版本改变了,就在onUpgrade()方法中把数据库文件删除掉。
下面是代码:
//数据库的缺省路径
private static finalString DB_PATH = "/data/data/com.mypackage.myapp/databases/";
private static finalString DB_NAME = "mydb.db";
private static finalint DB_VERSION = 2;
private static finalString DB_SPLIT_NAME = "mydb.db.00";
private static finalint DB_SPLIT_COUNT = 3;
private SQLiteDatabasem_database;
private final Contextm_context;
/**
* Constructor
*保存传进来的context参数以用来访问应用的asset和资源文件。
* @param context
*/
public MyDB(Contextcontext) {
super(context, DB_NAME, null, DB_VERSION);
this.m_context = context;
}
public static MyDBopenDatabaseReadOnly(Context context) {
MyDB db = new MyDB(context);
try {
db.createDataBase();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
db.openDataBase(SQLiteDatabase.OPEN_READONLY);
return db;
}
public static MyDBopenDatabaseReadWrite(Context context) {
MyDB db = new MyDB(context);
try {
db.createDataBase();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
db.openDataBase(SQLiteDatabase.OPEN_READWRITE);
return db;
}
/**
*创建一个空数据库,用来存储你已有的数据库。
*/
public voidcreateDataBase() throws IOException{
boolean dbExist =checkDataBase();
if (dbExist) {
/*
**如果你的数据库的版本改变了,调用这个方法确保在onUpgrade()被调用时
**传进去的是可写的数据库。
*/
SQLiteDatabase db =this.getWritableDatabase();
if (db != null) {
db.close();
}
}
dbExist = checkDataBase();
if (!dbExist) {
try {
/*
** 调用这个方法以确保在缺省路径内产生一个空数据库,以便在其基础上复制我们已有的数据库。
*/
SQLiteDatabase db =this.getReadableDatabase();
if (db != null) {
db.close();
}
DataBase();
}
catch (IOException e) {
Log.e("DB", e.getMessage());
throw new Error("Error ingdatabase");
}
}
}
/**
* 检查数据库是否已存在,以避免重复复制。
* @return true if it exists, false if itdoesn't
*/
private static booleancheckDataBase(){
SQLiteDatabase checkDB = null;
try {
String path = DB_PATH + DB_NAME;
checkDB =SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
}
catch (SQLiteException e){
//database does't exist yet.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* 把存在asset文件中的数据库复制的刚创建的空数据库中。
* */
private voidDataBase() throws IOException {
// 刚创建的空数据库的路径
String outFileName = DB_PATH + DB_NAME;
// 打开空数据库
OutputStream output = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024*8];
AssetManager assetMgr =m_context.getAssets();
for (int i = 1; i <= DB_SPLIT_COUNT; i++){
// 打开分解的asset文件
String fn = DB_SPLIT_NAME +String.valueOf(i);
InputStream input = assetMgr.open(fn);
//Log.i("DB", "opened" + fn);
int length;
while ((length = input.read(buffer)) >0) {
//Log.i("DB", "read" + String.valueOf(length));
output.write(buffer, 0, length);
//Log.i("DB", "write" + String.valueOf(length));
}
input.close();
}
//Close the streams
output.flush();
output.close();
}
/**
* 打开数据库。
* */
private voidopenDataBase(int flags) throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
m_database =SQLiteDatabase.openDatabase(myPath, null, flags);
}
/**
* 关闭数据库。
* */
@Override
public synchronizedvoid close() {
if (m_database != null)
m_database.close();
super.close();
}
}
@Override
public voidonCreate(SQLiteDatabase db) {
// 不需做任何事
}
/**
* 在数据库版本提高时,删除原有数据库。
* */
@Override
public voidonUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion) {
m_context.deleteDatabase(DB_NAME);
}
}