热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android数据存储之SQLite数据库存储,Android中SQLite数据库的查看

—————————————-SQLite数据库———————

—————————————-SQLite数据库———————————————-

SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百K的内存就足够了,因此特别适合在移动设备上使用。

SQLite不仅支持标准的SQL语法,还遵守了数据库的 ACID 事务,只要你以前使用过其他的关系型数据库,就可以很快的上手SQLite。

而SQLite又比一般的数据库要简单的多,它甚至不用设置用户名和密码就可以使用。

Android 正是把这个功能极为强大的数据库嵌入到了系统当中,使得本地持久化的功能有了一次质的飞跃。

——————————————-创建数据库———————————————–

Android 提供了一个SQLiteOpenHelper 帮助类,借助这个类就可以非常简单的对数据库进行创建和升级。

SQLiteOpenHelper 是一个抽象类,如果需要使用它的话,就需要创建一个帮助类去继承它。

SQLiteOpenHelper 中有两个抽象方法,分别是 onCreate() 和 onUpdate(),需要在帮助类里重写这两个方法,然后分别在这两个方法中去实现创建和升级数据库的逻辑。

SQLiteOpenHelper 中还有两个非常重要的实例方法getReadableDatabase() 和 getWritableDatabase()。这两种方法都可以创建或打开一个现有的数据库(如果数据库已存在则直接打开,否则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象。不同的是,当数据库不可写入的时候(如磁盘空间已满)getReadableDatabase() 方法返回的对象将以只读的方式去打开数据库,而getWritableDatabase() 方法将抛出异常。

SQLiteOpenHelper 的构造方法接收四个参数,第一个参数是 Context,必须要有Context对象才能对数据库进行操作。第二个参数是数据库名,创建数据库时使用的就是这里指定的名称。第三个参数允许在查询数据库的时候返回一个自定义的 Cursor,一般传入null。第四个参数表示当前数据库的版本号,可用于对数据库进行升级操作。

构建出 SQLiteOpenHelper 的实例之后,再调用它的 getReadableDatabase() 或 getWritableDatabase() 方法就能够创建数据库了,数据库文件会存放在 /data/data/<包名>/database/ 目录下。

新建 MyDatabaseHelper 类继承自 SQLiteOpenHelper:

public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = "CREATE TABLE book ("
+ "id integer PRIMARY KEY Autoincrement ,"
+ "author text ,"
+ "price real ,"
+ "pages integer,"
+ "name text )";
/**
* integer:整形
* real:浮点型
* text:文本类型
* blob:二进制类型
* PRIMARY KEY将id列设置为主键
* AutoIncrement关键字表示id列是自动增长的
*/
private Context myContent;
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
myContent
= context;
}
@Override
public void onCreate(SQLiteDatabase db) {
//创建数据库的同时创建Book表
db.execSQL(CREATE_BOOK);
//提示数据库创建成功
Toast.makeText(myContent, "数据库创建成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}

在 MainActivity 中进行测试:

public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//构建一个 MyDatabaseHelper 对象,通过构造函数将数据库名指定为 BookStore.db
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1);
Button createDatabase
= (Button)findViewById(R.id.create_database);
createDatabase.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
*调用getWritableDatabase() 方法
* 自动检测当前程序中 BookStore.db 这个数据库
* 如果不存在则创建该数据库并调用 onCreate() 方法
* 同时Book表也会被创建
*/
dbHelper.getWritableDatabase();
}
});
}
}

点击按钮 BookStore.db 数据库和 Book 表就已经创建成功了,再次点击不会再有Toast弹出。

关于如何查看SQLite数据库,请参考:Android 中 SQLite 数据库的查看

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-升级数据库&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;

onUpdate() 方法是用于对数据库进行升级的,它在整个数据库的管理工作中担当着非常重要的作用。

目前 BookStore.db 中已经有一张 Book 表用于存放书的各种详细数据,接下来再添加一张 Category 表用于记录书籍的分类。

将建表语句添加到 MyDatabaseHelper 中,代码如下:

public static final String CREATE_CATEGORY = "CREATE TABLE category ("
+ "id integer PRIMARY KEY Autoincrement , "
+ "category_name text , "
+ "category_code integer )";

并在 onCreate()方法中添加:db.execSQL( CREATE_CATEGORY); 这条语句,运行程序,并不会弹出创建成功的提示。因为此时 BookStore.db 数据库已经存在了,之后不论怎样点击创建按钮,MyDatabaseHelper 中的 onCreate() 方法都不会再次执行,因此新添加的表也就无法得到创建了。

只需要巧妙的运用 SQLiteOpenHelper 的升级功能就可以很轻松的解决这个问题。

修改 MyDatabaseHelper 中的代码,如下所示:

@Override
public void onCreate(SQLiteDatabase db) {
//创建Book表和Category表
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
//提示数据库创建成功
Toast.makeText(myContent, "数据库创建成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/**
* 如果发现数据库中已经存在 Book 表或 Category 表
* 就将这两张表删除掉,然后调用 onCreate() 方法重新创建
* 如果在创建表时发现表已经存在,就会直接报错
*/
db.execSQL(
"DROP TABLE IF EXISTS Book");
db.execSQL(
"DROP TABLE IF EXISTS Category");
onCreate(db);
}

接下来的问题就是如何让 onUpgrade() 方法能够得到执行了,还记得 SQLiteOpenHelper 的构造方法里接受的第四个参数吗?它表示当前数据库的版本号,之前我们传入的是1,现在只要传入一个比1大的数,就可以让 onUpgrade() 方法得到执行了,修改MainActivity 中的代码:

dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,3);

这里将数据库版本号指定为3,表示我们对数据库进行升级了。重新运行程序,并点击创建数据库按钮,这时就会再次弹出创建成功的提示。

升级数据库的最佳方式:

  粗暴的删除当前所有的表来达到更新的效果,对于用户来说是非常糟糕的,因为以前程序中存储的本地数据全部丢失了。其实只需进行一些合理的控制,就可以保证升级数据库的时候数据并不会丢失了。

  每一个数据库版本都会对应一个版本号,当指定的数据库版本号大于当前数据库版本号的时候,就会进入到 onUpgrade()方法中去执行更新操作。这里需要为每一个版本号赋予它各自改变的内容,然后在 onUpgrade()方法中对当前数据库的版本进行判断,再执行相应的改变就可以了。

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
db.execSQL(CREATE_CATEGORY);
default:
}
}

注意,switch 中每一个 case 的最后都是没有使用 break 的,这是为了保证跨版本升级的时候,每一次的数据库修改都能被全部执行。

使用这种方式来维护数据库的升级,不管版本怎样更新,都可以保证数据库的表结构是最新的,而且表中的数据也完全不会丢失。

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;使用SQL操作数据库&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-

现在你已经掌握了创建和升级数据库的方法,接下来就该学习一下如何对表中的数据进行操作了。

其实我们可以对数据库进行的操作也就无非四种,添加(Create)、查询(Rectrieve)、更新(Update),删除(Delete)

每一种操作又各自对应了一种SQL命令,添加数据时使用 insert,查询数据时使用 select,更新数据时使用 update,删除数据时使用 delete。

而作为一个开发者熟练使用SQL语句是非常有必要的,Android 提供了一系列方法,使得可以直接通过SQL来操作数据库。

下面简略演示一下,如何直接使用SQL来完成增删改查的操作。

添加数据的方法如下:

/**
* SQL插入语句:
* INSERT INTO Book(name,author,pages,price) VALUES
* ("The Da Vinci Code" ,"Dan Brown",454,16.96);
*/
db.execSQL(
"INSERT INTO Book(name,author,pages,price) VALUES(?,?,?,?",
new String[]{"The Lost Symbol", "Dan Brown", "510", "19.95"});

删除数据的方法如下:

/**
*SQL删除语句:
* DELETE FROM Book WHERE pages > 500;
*/
db.execSQL(
"DELETE FROM Book WHERE pages > ?",new String[]{"500"});

更新数据的方法如下:

/**
* SQL更新语句:
* UPDATE Book SET price = 10.99 WHERE name = "The Da Vinci Code" ;
*/
db.execSQL(
"UPDATE Book SET price = ? WHERE name = ?",
new String[]{"10.99", "The Da Vinci Code"});

查询数据的方法如下:

/**
* SQL查询语句:
* SELECT * FROM BOOK ;
*/
db.rawQuery(
"SELECT * FROM BOOK", null);

注意:除了查询数据的时候调用的是 SQLiteDatabase 的 rawQuery()方法,其他的操作都是调用的 execSQL()方法。

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;添加数据&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;

 并非所有开发者都能非常熟练度使用SQL语言,因此 Android 也提供了一系列的辅助性方法,使得在 Android 中即使不去编写 SQL 语句,也能轻松完成所有的增删改查操作。

SQLiteDatabase 中提供了一个 insert() 方法,这个方法就是专门用于添加数据的。

insert() 方法接收三个参数,第一个参数是表名,我们希望向哪张表里添加数据,这里就传入该表的名字。第二个参数用于在未指定添加数据的情况下给某些可为空的列自动赋值NULL,一般用不到这个功能,直接传入 null 即可。第三个参数是一个 ContentValues 对象,它提供了一系列的 put() 方法重载,用于向 ContentValues 中添加数据,只需要将表中的每个列名及相对应的待添加数据传入即可。

public void onClick(View v) {
//获取 SQLiteDatabase 对象
SQLiteDatabase db = dbHelper.getWritableDatabase();
//使用ContentValues 对数据进行组装
ContentValues values = new ContentValues();
//开始组装第一条数据
values.put("name", "The Da Vinci Code");
values.put(
"author", "Dan Brown");
values.put(
"pages", 454);
values.put(
"price", 16.96);
//插入第一条数据
db.insert("Book", null, values);
values.clear();
//开始组装第二条数据
values.put("name", "The Lost Symbol");
values.put(
"author", "Dan Brown");
values.put(
"pages", 510);
values.put(
"price", 19.95);
//插入第二条数据
db.insert("Book", null, values);
}

这里只对Book表里其中四列的数据进行了组装,id并没有赋值。因为创建表的时候就将 id 列设置为自动增长了,它的值会在入库的时候自动生成,不需要手动赋值。

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;更新数据&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;

SQLiteDatabase 中提供了一个非常好用的 update() 方法用于对数据进行更新,这个方法接收四个参数,第一个参数和 insert()方法一样,也是表名,在这里指定去更新哪张表里的数据。第二个参数是 ContentValues 对象,把要更新的数据在这里组装进去。第三、第四个参数用于去约束更新某一行的数据,不指定的话默认就是更新所有行。

public void onClick(View v) {
SQLiteDatabase db
= dbHelper.getWritableDatabase();
ContentValues values
= new ContentValues();
values.put(
"price", 10.99);
//?是一个占位符,通过字符串数组为每个占位符指定相应的内容
db.update("Book", values, "name = ?", new String[]{"The Da Vinci Code"});
}

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;删除数据&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;

SQLiteDatabase 中提供了一个 delete()方法专门用于删除数据,这个方法接收三个参数,第一个参数仍然是表名,第二、第三个参数用于约束删除某一行或某几行的数据,不指定的话默认就是删除所有行。

public void onClick(View v) {
SQLiteDatabase db
= dbHelper.getWritableDatabase();
db.delete(
"Book", "pages > ?", new String[]{"500"});
}

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;查询数据&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;

SQLiteDatabase 中还提供了一个 query() 方法用于对数据进行查询。这个方法的参数非常复杂,最短的一个方法重载也需要传入七个参数。

query()方法参数及对应SQL:

  table:指定查询的表名,对应 from table_name

  columns:指定查询的列名,对应 select column1,column2 &#8230;

  selection:指定 where 的约束条件,where column = value

  selectionArgs:为 where 中的占位符提供具体的值

  groupBy:指定需要分组的列,group by column

  having:对分组后的结果进一步约束,having column = value

  orderBy:指定查询结果的排序方式,order by column

虽然 query()方法的参数非常多,但是不必每条查询语句都指定上所有的参数,多数情况下只需传入少数几个参数就可以完成查询操作了。

调用 query()方法后会返回一个 Cursor 对象,查询到的所有数据都将从这个对象中取出

public void onClick(View v) {
SQLiteDatabase db
= dbHelper.getWritableDatabase();
//查询Book表中的所有数据
Cursor cursor = db.query("Book", null, null, null, null, null, null, null);
//遍历Curosr对象,取出数据并打印
while (cursor.moveToNext()) {
String name
= cursor.getString(cursor.getColumnIndex("name"));
String author
= cursor.getString(cursor.getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
double price = cursor.getDouble(cursor.getColumnIndex("price"));
Log.d(
"woider", "Book Name:" + name + " Author:"
+ author + " Pages:" + pages + " Price:" + price);
}
//关闭Cursor
cursor.close();
}

执行 query()方法之后会得到一个 Cursor对象,然后通过 Cursor 对象的 moveToNext()方法去遍历查询到的每一行数据。在这个循环中可以通过 Cursor 的 getColumnIndex() 方法获取到某一列在表中对应位置的索引,然后将这个索引传入到相应的取值方法中,就可以得到从数据库中读取到的数据了。最后别忘了调用 close()方法来关闭 Cursor。

 


推荐阅读
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • CentOS 6.5安装VMware Tools及共享文件夹显示问题解决方法
    本文介绍了在CentOS 6.5上安装VMware Tools及解决共享文件夹显示问题的方法。包括清空CD/DVD使用的ISO镜像文件、创建挂载目录、改变光驱设备的读写权限等步骤。最后给出了拷贝解压VMware Tools的操作。 ... [详细]
author-avatar
银仔-zxy
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有