Android中使用Sqlite存储和管理数据,如前面的联系人、短信等,都是通过Sqlite来进行存储和管理,在启动模拟机之后,通过File Explorer窗体可以查看模拟机中的数据库(如果没有File Explorer,则通过Eclipse的“Window——Show View——Other…”菜单,然后在Android下选择File Explorer),如下图所示:
通过File Explorer上的按钮可以将模拟机上的数据文件导入到本地磁盘,同样,通过按钮也可以将本地磁盘的数据导入到模拟机上的指定目录下。data文件夹中包含了Android系统包括安装程序所操作和使用的数据,Sqlite数据库文件后缀为db,如data文件下data\com.android.providers.telephony\databases\mmssms.db文件即为系统的短信数据库,如下图所示:
通过按钮将这个mmssms.db文件导出到本地磁盘,然后通过Sqlite查看工具即可查看db数据库,如SQLiteSpy软件,如下图所示:
打开sms表即可看到表中的具体内容,即短信数据在Android中的存储格式。前面提到的query()查询中需要的一些字段以及字段类型都可以在此通过Sqlite软件进行查询。
现在新建一个名为Sample123的Android项目。
1、创建数据库
Android中Sqlite数据库采用SQLiteDatabase类,打开或创建一个数据库采用openOrCreateDatabase()方法。openOrCreateDatabase()方法有三个参数,其中第一个参数为数据库名称,如"test.db",如果该数据库文件已经存在则是打开这个已经存在的数据库,如果没有该数据库则会创建一个该名称的数据库,这个数据库会存储在程序安装的数据文件加中,如data\data\com.xzy\databases\test.db;第二个参数为数据库操作模式,默认为0或者MODE_PRIVATE,采用MODE_WORLD_READABLE 或 MODE_WORLD_WRITEABLE参数值可以控制许可权限。
现在在main.xml中添加一个按钮用于创建新的数据库,如下图所示:
然后在Sample123.java的onCreate()重载函数中添加按钮的点击事件,点击该按钮就创建或打开名为test.db的数据库,如下:
publicclass Sample23Activity extends Activity {
//定义数据库对象
private SQLiteDatabase myDatabase;
/** Calledwhen the activity is first created. */
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//创建或打开数据库
ButtonmyButton01=(Button)findViewById(R.id.button1);
myButton01.setOnClickListener(newOnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//打开或创建test.db数据库
myDatabase= openOrCreateDatabase("test.db",
Context.MODE_PRIVATE,null);
Toast.makeText(Sample23Activity.this,
"打开了数据库test.db", Toast.LENGTH_SHORT).show();
}});
}
}
运行程序,当点击“创建数据库”按钮之后,在Eclipse的File Explorer中查看路径data\data\com.xzy\databases即多了一个test.db文件,这个就是刚才创建的数据库文件,如下图所示:2、创建数据表
在打开一个数据库的基础之上,创建数据表时需要指定主键、表中各字段的数据类型,Sqlite支持的常见数据类型有VARCHAR、NVARCHAR、TEXT、INTEGER、FLOAT、BOOLEAN、BLOB等。创建数据表的SQL语法为“CreateTable 表格名称 (字段1 数据类型, 字段2 数据类型, … )”,如果要指定某个字段为主键,则在数据类型后还添加关键词primary key autoincrement表示主键并自增长。建议创建表时都创建一个名为_id的主键,如_id Integer primary key autoincrement。执行SQL语句采用SQLiteDatabase的execSQL()方法来实现,现在在main.xml中添加一个创建数据表的按钮,然后在Sample123.java的onCreate()重载函数中添加按钮的点击事件,点击该按钮就创建一个名为myPhoneBook的表,如下:
//创建数据表
ButtonmyButton02=(Button)findViewById(R.id.button2);
myButton02.setOnClickListener(new OnClickListener(){
@Override
publicvoid onClick(View v) {
// TODO Auto-generatedmethod stub
if(myDatabase==null){//如果数据库没有打开
myDatabase = openOrCreateDatabase("test.db",
Context.MODE_PRIVATE, null);
}
//创建数据表
String sql="CreateTable myPhoneBook ("
+"_id Integerprimary key autoincrement,"
+"namevarchar(10),number varchar(20),"
+"ageInterger, brithday Long, remark Text)";
myDatabase.execSQL(sql);
}});
运行程序,点击“创建数据表”按钮,然后在File Explorer中将data\data\com.xzy\databases\test.db文件导出到本地,通过Sqlite数据库软件查看,如下图所示:
如果该数据表已经存在,再点击“创建数据表”按钮就会出错,所以有时候如果需要在创建该表之前删除已经存在的表,可以通过Drop语句来删除之前存在的数据表,具体代码如下:
//如果数据表myPhoneBook已经存在,则删除
myDatabase.execSQL("DROP TABLE IF EXISTS myPhoneBook");那么下次在创建表myPhoneBook之前,如果该表已经存在,则会删除该表,然后再创建这个表。但是有时候我们并不需要删除这个表,即如果这个表不存在就创建,这只需要在Create Table语句中加上IF Not EXISTS即可。如下:
//创建数据表
String sql="Create Table IF Not EXISTS myPhoneBook ("
+"_id Integerprimary key autoincrement,"
+"namevarchar(10),number varchar(20),"
+"ageInterger, brithday Long, remark Text)";
myDatabase.execSQL(sql);
那么在创建表myPhoneBook的时候如果这个表已经存在就不再重新创建了。
3、插入数据
其实到目前为止,我们发现Sqlite的基本语法与其他数据库操作的语法几乎大同小异,同样,插入数据也是采用Insert Into,具体用法如下:
Insert Into [数据库名称.]表名称 (列组) Values (值组)
现在在main.xml中添加一个插入数据的按钮,然后在Sample123.java的onCreate()重载函数中添加按钮的点击事件,点击该按钮就向myPhoneBook表中添加一条记录,如下: //添加了一条记录
ButtonmyButton03=(Button)findViewById(R.id.button3);
myButton03.setOnClickListener(new OnClickListener(){
@Override
publicvoid onClick(View v) {
// TODO Auto-generatedmethod stub
if(myDatabase==null){//如果数据库没有打开
myDatabase = openOrCreateDatabase("test.db",
Context.MODE_PRIVATE, null);
}
//日期格式
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
long brithDay = 0;
try {
brithDay = format.parse("19870507").getTime();
} catch (ParseException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
//添加一条数据记录到表中
String sql="InsertInto myPhoneBook (name,number,age, brithday,remark)"
+"Values('肖泽云','18986781282',25,"+brithDay+",'武汉大学水利水电学院博士研究生')";
myDatabase.execSQL(sql);
Toast.makeText(Sample23Activity.this,
"添加了一条新的记录", Toast.LENGTH_SHORT).show();
}});
运行程序,点击“添加记录”按钮,然后将test.db数据库导出到本地查询,其结果如下图所示:4、修改数据
修改数据的SQL语句格式为:
Update [数据库名称.]表名称 Set 字段1=值1 [,字段2=值2…] [Where 条件语句]
如要修改myPhoneBook表中name字段名称为“肖泽云”的所有记录中age字段值为26,则相应SQL语句为:UpdatemyPhoneBook Set age=26 Where name='肖泽云'
现在在main.xml中添加一个修改数据的按钮,然后在Sample123.java的onCreate()重载函数中添加按钮的点击事件,点击该按钮就向myPhoneBook表中更新name为“肖泽云”的age值为26,如下:
//修改数据
ButtonmyButton04=(Button)findViewById(R.id.button4);
myButton04.setOnClickListener(new OnClickListener(){
@Override
publicvoid onClick(View v) {
// TODO Auto-generatedmethod stub
if(myDatabase==null){//如果数据库没有打开
myDatabase = openOrCreateDatabase("test.db",
Context.MODE_PRIVATE, null);
}
//修改数据
String sql="UpdatemyPhoneBook Set age=26 Where name='肖泽云'";
myDatabase.execSQL(sql);
Toast.makeText(Sample23Activity.this,
"更新了数据", Toast.LENGTH_SHORT).show();
}});
运行程序,点击“修改数据”按钮,然后将test.db数据库导出查看,其结果如下图所示:
5、删除数据记录
删除数据的SQL语句格式如下:
Delete From [数据库名称.]表名称 [Where 条件语句]
如果没有Where条件语句,则表示删除所有的数据,如果有则只删除符合条件的数据。
现在在main.xml中添加一个删除数据的按钮,然后在Sample123.java的onCreate()重载函数中添加按钮的点击事件,点击该按钮就将myPhoneBook表中age为25的数据删除,如下:
//删除数据
ButtonmyButton05=(Button)findViewById(R.id.button5);
myButton05.setOnClickListener(new OnClickListener(){
@Override
publicvoid onClick(View v) {
// TODO Auto-generated methodstub
if(myDatabase==null){//如果数据库没有打开
myDatabase = openOrCreateDatabase("test.db",
Context.MODE_PRIVATE, null);
}
//删除数据
String sql="DeleteFrom myPhoneBook Where age=25";
myDatabase.execSQL(sql);
Toast.makeText(Sample23Activity.this,
"删除了age=25的数据", Toast.LENGTH_SHORT).show();
}});
运行程序,对比test.db数据库myPhoneBook表中点击按钮“删除数据”之前的数据和点击该按钮之后的数据,如下图所示:
6、查询数据
查询数据是常见和常用的功能,之前的一些例子中也有些涉及,如query()方法等。SQLiteDatabase的query()方法有多个重载函数,其中常见的如下:
public Cursorquery (Stringtable, String[] columns, String selection, String[] selectionArgs, StringgroupBy, String having, String orderBy)
以上参数中table为表名,columns为列名称数组(如果是null则返回所有的列),selection为选择条件(如果是null则返回所有的数据),selectionArgs为选择条件标记数据(当选择条件selection中包含问号?时,这些问号对应的值就是selectionArgs数组中的值,所以selectionArgs数组的长度与选择条件selection中问号?的数目相同),groupBy表示分组声明(如果为null表示不分组),having为返回游标cursor的一个过滤声明(如果为null表示所有都包含),orderBy为返回数据的排序方式(如果为null则表示不排序)。
现在在main.xml中添加一个查询数据的按钮,然后在Sample123.java的onCreate()重载函数中添加按钮的点击事件,点击该按钮就将myPhoneBook表中所有的数据返回,如下:
//查询数据
ButtonmyButton06=(Button)findViewById(R.id.button6);
myButton06.setOnClickListener(new OnClickListener(){
@Override
publicvoid onClick(View v) {
// TODO Auto-generatedmethod stub
if(myDatabase==null){//如果数据库没有打开
myDatabase = openOrCreateDatabase("test.db",
Context.MODE_PRIVATE, null);
}
String totalMsg="";
//查询数据
Cursor pCursor = myDatabase.query("myPhoneBook",
new String[]{"name","number","age","remark"},
null, null, null, null, null);
if(pCursor!=null){
while(pCursor.moveToNext()){
totalMsg+="姓名:"+ pCursor.getString(0)
+",号码:"+pCursor.getString(1)
+",年龄:"+pCursor.getLong(2)
+",备注:"+pCursor.getString(3)+"\n";
}
}
Toast.makeText(Sample23Activity.this,
"查询结果为:\n"+totalMsg, Toast.LENGTH_LONG).show();
}});
其结果如下图所示:如果指定selection参数,即可返回指定条件的数据,如_id=8的数据,如下:
//查询数据
Cursor pCursor = myDatabase.query("myPhoneBook",
new String[]{"name","number","age","remark"},
"_id=8", null, null, null, null);
其结果如下图所示:
除了上面介绍的这些之外,还有其他的query()方法,如:
public Cursorquery (Stringtable, String[] columns, String selection, String[] selectionArgs, StringgroupBy, String having, String orderBy, String limit)
其中参数limit为返回数据的限制数目,如只返回数目为10,如果为null则表示不限制。
public Cursorquery (booleandistinct, String table, String[] columns, String selection, String[]selectionArgs, String groupBy, String having, String orderBy, String limit)
其中参数distinct表示查询的字段值是否限制唯一,如果为true则表示只查询唯一值的数据,如果表中该字段的值相同,则只返回一条记录。如果为false就不管唯一值问题。这点和SQL语句中Distinct关键字的含义是一样的。
7、二进制数据操作
二进制数据是经常需要使用的一种数据类型,如保存图片、视频文件到Sqlite数据库中,二进制数据类型在Sqlite为BLOB,下面以三个例子来说明创建带二进制类型字段的数据表、插入二进制数据、读取二进制数据,在main.xml中添加三个按钮,分别表示这三个功能,如下图所示:
创建一个二进制表的代码如下:
//创建一个二进制数据表
ButtonmyButton07=(Button)findViewById(R.id.button7);
myButton07.setOnClickListener(new OnClickListener(){
@Override
publicvoid onClick(View v) {
// TODO Auto-generatedmethod stub
if(myDatabase==null){//如果数据库没有打开
myDatabase = openOrCreateDatabase("test.db",
Context.MODE_PRIVATE, null);
}
//创建数据表
String sql="CreateTable IF Not EXISTS myBinary ("
+"_id Integerprimary key autoincrement,"
+"namevarchar(10),file BLOB)";
myDatabase.execSQL(sql);
Toast.makeText(Sample23Activity.this,
"创建了数据表myBinary", Toast.LENGTH_SHORT).show();
}});
在File Explorer中导入一个名为online.png的文件到data\data\com.xzy\files文件夹中,如下图所示:添加一个二进制数据的代码如下:
//添加了一条二进制数据
ButtonmyButton08=(Button)findViewById(R.id.button8);
myButton08.setOnClickListener(new OnClickListener(){
@Override
publicvoid onClick(View v) {
// TODO Auto-generatedmethod stub
if(myDatabase==null){//如果数据库没有打开
myDatabase = openOrCreateDatabase("test.db",
Context.MODE_PRIVATE, null);
}
ContentValues tempValues=new ContentValues();
//添加name字段值
tempValues.put("name", "肖泽云");
File tempFile=new File("data\\data\\com.xzy\\files\\online.png");
if(tempFile.exists())
{
Toast.makeText(Sample23Activity.this,
"文件存在", Toast.LENGTH_SHORT).show();
FileInputStream fi=null;
try {
fi=new FileInputStream(tempFile);
int size=fi.available();
byte[] tempbytes=newbyte[size];
fi.read(tempbytes);//读取为二进制数据
//添加参数
tempValues.put("file", tempbytes);
myDatabase.insert("myBinary", null, tempValues);
Toast.makeText(Sample23Activity.this,
"插入二进制数据成功:"+size, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
Toast.makeText(Sample23Activity.this,
"错误:"+e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
else
Toast.makeText(Sample23Activity.this,
"文件不存在", Toast.LENGTH_SHORT).show();
}});
最后是下载二进制数据,将数据表myBinary中的数据下载到“data\\data\\com.xzy\\files\\”文件夹中,具体代码如下:
//下载二进制数据
ButtonmyButton09=(Button)findViewById(R.id.button9);
myButton09.setOnClickListener(new OnClickListener(){
@Override
publicvoid onClick(View v) {
// TODO Auto-generatedmethod stub
if(myDatabase==null){//如果数据库没有打开
myDatabase = openOrCreateDatabase("test.db",
Context.MODE_PRIVATE, null);
}
//查询数据
Cursor pCursor = myDatabase.query("myBinary",
new String[]{"name","file"},
null, null, null, null, null);
int count=0;
if(pCursor!=null){
while(pCursor.moveToNext()){
count++;
byte[] tempBytes = pCursor.getBlob(1);
try {
File tempFile=new File("data\\data\\com.xzy\\files\\"+"file"+count+".png");
FileOutputStream fos=newFileOutputStream(tempFile);
fos.write(tempBytes);
fos.close();
Toast.makeText(Sample23Activity.this,
"下载文件成功:"+tempFile.getName(),Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}
}
}
}});
运行程序,分别点击这三个按钮,其结果如下图所示: