Android本地数据存储之SQLite关系型数据库 ——SQLiteDatabase

数据库的创建,获取,执行sql语句:

框架搭建:dao

思考:

1.数据库保存在哪里?

2.如何创建数据库?如何创建表?

3.如何更新数据库?如何更改表的列数据?

4.如何获取数据库?

5.如何修改数据库中的表的数据?

框架思想

思考:如何使得编程更加简单?

一个sql语言,容易写错;

1.使用占位符;

2.框架解析重建法:搭建框架,对增删改查功能进行单独封装,传入容器对象即可;

思考:

1.数据库保存在哪里?

data/data/包名/databases/xiaoo.db

2.如何创建数据库?如何创建表?

db.execSQL("CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))");

3.如何更新数据库?如何更改表的列数据?

db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL ");

4.如何获取数据库?

5.如何修改数据库中的表的数据?

一、创建数据库打开助手:

二、创建dao

三、测试dao

[plain] view plaincopy

  1. import android.content.Context;
  2. import android.database.sqlite.SQLiteDatabase;
  3. import android.database.sqlite.SQLiteOpenHelper;
  4. public class MyDBOpenHelper extends SQLiteOpenHelper {
  5. /**
  6. *
  7. * @param context 应用程序上下文
  8. * @param name    数据库的名字
  9. * @param factory 查询数据库的游标工厂 一般情况下 用sdk默认的
  10. * @param version  数据库的版本 版本号必须不小1
  11. *
  12. */
  13. public MyDBOpenHelper(Context context) {
  14. super(context, "xiaoo.db", null, 6);
  15. }
  16. // 在mydbOpenHelper 在数据库第一次被创建的时候  会执行onCreate();
  17. @Override
  18. public void onCreate(SQLiteDatabase db) {
  19. System.out.println("我被调用了 oncreate");
  20. db.execSQL("CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))");
  21. }
  22. // 通过version的增加来执行数据库版本更新,版本号改为6的同时,调用onUpgrade ,让程序员执行具体更新;
  23. @Override
  24. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  25. System.out.println("on update ");
  26. db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL ");
  27. }
  28. }

二、创建dao

[html] view plaincopy

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import android.content.Context;
  4. import android.database.Cursor;
  5. import android.database.sqlite.SQLiteDatabase;
  6. import android.util.Log;
  7. import cn.itcast.db.MyDBOpenHelper;
  8. import cn.itcast.db.domain.Person;
  9. public class PersonDao {
  10. private static final String TAG = "PersonDao";
  11. private MyDBOpenHelper dbOpenHelper;
  12. // 在personDao被new出来的时候 就完成初始化
  13. public PersonDao(Context context) {
  14. dbOpenHelper = new MyDBOpenHelper(context);
  15. // dbOpenHelper.getReadableDatabase()
  16. // dbOpenHelper.getWritableDatabase()
  17. }
  18. // 增删改查
  19. /**
  20. * 往数据库添加一条数据
  21. */
  22. public void add(String name, String phone) {
  23. boolean result = find(name);
  24. if (result)
  25. return;
  26. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  27. if (db.isOpen()) {
  28. db.execSQL("insert into person (name,phone) values (?,?)",
  29. new Object[] { name, phone });
  30. // 关闭数据库 释放数据库的链接
  31. db.close();
  32. }
  33. }
  34. /**
  35. * 查找数据库的操作
  36. */
  37. public boolean find(String name) {
  38. boolean result = false;
  39. SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
  40. if (db.isOpen()) {
  41. Cursor cursor = db.rawQuery("select * from person where name=?",
  42. new String[] { name });
  43. if (cursor.moveToFirst()) {
  44. int index = cursor.getColumnIndex("phone"); // 得到phone在表中是第几列
  45. String phone = cursor.getString(index);
  46. Log.i(TAG, "phone =" + phone);
  47. result = true;
  48. }
  49. // 记得关闭掉 cursor
  50. cursor.close();
  51. result = false;
  52. // 释放数据库的链接
  53. db.close();
  54. }
  55. return result;
  56. }
  57. /**
  58. * 删除一条记录
  59. *
  60. * @param name
  61. */
  62. public void delete(String name) {
  63. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  64. if (db.isOpen()) {
  65. db.execSQL("delete from person where name =?",
  66. new Object[] { name });
  67. db.close();
  68. }
  69. }
  70. /**
  71. * 更新一条记录
  72. *
  73. */
  74. public void update(String name, String newname, String newphone) {
  75. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  76. if (db.isOpen()) {
  77. db.execSQL("update person set name=? , phone=? where name=?",
  78. new Object[] { newname, newphone, name });
  79. db.close();
  80. }
  81. }
  82. /**
  83. * 查找全部
  84. */
  85. public List<Person> getAllPersons() {
  86. List<Person> persons=null;
  87. SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
  88. if (db.isOpen()) {
  89. persons = new ArrayList<Person>();
  90. Cursor cursor = db.rawQuery("select * from person ", null);
  91. while (cursor.moveToNext()) {
  92. Person person = new Person();
  93. int nameindex = cursor.getColumnIndex("name");
  94. int phoneindex = cursor.getColumnIndex("phone");
  95. String name = cursor.getString(nameindex);
  96. String phone = cursor.getString(phoneindex);
  97. person.setName(name);
  98. person.setNumber(phone);
  99. persons.add(person);
  100. }
  101. cursor.close();
  102. db.close();
  103. }
  104. return persons;
  105. }
  106. }

三、单元测试:测试dao

1.配置

[html] view plaincopy

  1. instrumentation 和 uses-library

[html] view plaincopy

  1. <instrumentation
  2. android:name="android.test.InstrumentationTestRunner"   //使用测试框架中的哪个测试运行器
  3. android:targetPackage="cn.xiaoo.db" />      //测试哪个工程?
  4. <application
  5. android:icon="@drawable/ic_launcher"
  6. android:label="@string/app_name" >
  7. <uses-library android:name="android.test.runner" />      //该程序需要添加哪个jar包(用于测试)?

2.编程测试

[plain] view plaincopy

  1. package cn.itcast.db.dao.test;
  2. import java.util.List;
  3. import cn.itcast.db.dao.PersonDao;
  4. import cn.itcast.db.domain.Person;
  5. import android.test.AndroidTestCase;
  6. public class TestPersonDao extends AndroidTestCase {
  7. PersonDao dao;
  8. // 测试在执行测试代码时候的流程
  9. //1 .new TestPersonDao 框架new出来
  10. //2. 调用 setUp()
  11. //3. testAdd()  这个时候 上下文 才被创建出来
  12. /*  @Override
  13. protected void setUp() throws Exception {
  14. dao = new PersonDao(getContext());
  15. super.setUp();
  16. }*/
  17. public void testAdd() throws Exception{
  18. PersonDao dao = new PersonDao(getContext());
  19. for(int i=0;i<100;i++){
  20. dao.add("lisi"+i, "123456789"+i);
  21. }
  22. }
  23. public void testdelete() throws Exception{
  24. PersonDao dao = new PersonDao(getContext());
  25. dao.delete("lisi99");
  26. }
  27. public void testupdate() throws Exception{
  28. PersonDao dao = new PersonDao(getContext());
  29. dao.update("lisi98", "wangwu", "120");
  30. }
  31. public void testFindAll() throws Exception{
  32. PersonDao dao = new PersonDao(getContext());
  33. List<Person>  persons  = dao.getAllPersons();
  34. assertEquals("testFindAll获取集合的大小",98, persons.size());
  35. }
  36. /**
  37. * 测试的流程:
  38. */
  39. /*
  40. [2012-10-05 13:47:51 - db] ------------------------------
  41. [2012-10-05 13:47:51 - db] Android Launch!    //系统启动
  42. [2012-10-05 13:47:51 - db] adb is running normally.   //调试桥正常运行
  43. [2012-10-05 13:47:51 - db] Performing android.test.InstrumentationTestRunner JUnit launch   //运行测试运行器,启动JUnit
  44. [2012-10-05 13:47:51 - db] Automatic Target Mode: using existing emulator ‘emulator-5554‘ running compatible AVD ‘2.3.3_QVGA‘
  45. [2012-10-05 13:47:53 - db] Application already deployed. No need to reinstall.//不需要重新安装
  46. [2012-10-05 13:47:53 - db] Launching instrumentation android.test.InstrumentationTestRunner on device emulator-5554//在设备上运行测试运行器
  47. [2012-10-05 13:47:53 - db] Collecting test information //收集运行信息
  48. [2012-10-05 13:47:56 - db] Sending test information to Eclipse  //发送测试信息到Eclipse
  49. [2012-10-05 13:47:56 - db] Running tests...    //执行代码
  50. [2012-10-05 13:47:58 - db] Test run finished   //执行完毕
  51. */
  52. }

框架思想

思考:如何使得编程更加简单?

一条sql语句,容易写错;

[html] view plaincopy

  1. 操作表
  2. insert into person (name,phone) values (?,?)---------public long insert(String table, String nullColumnHack, ContentValues values)
  3. delete from person where name =?---------------------public int delete(String table, String whereClause, String[] whereArgs)
  4. update person set name=? , phone=? where name=?------public int update(String table, ContentValues values, String whereClause, String[] whereArgs)
  5. select * from person where name=?--------------------public Cursor query(boolean distinct, String table, String[] columns,
  6. String selection, String[] selectionArgs, String groupBy,
  7. String having, String orderBy, String limit)
  8. insert:在哪张表插入哪些数据?string string contentvalues
  9. delete:在哪张表删除哪些数据?String String String[]
  10. update:在哪张表的那条数据上更改什么数据? String ContentValues String  String[]
  11. query:是否保证唯一?查哪张表?查哪些列?
  12. 什么查询条件?占位符值?分组?
  13. 包含?排序?区间?
  14. 操作数据库:
  15. CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))
  16. ALTER TABLE person ADD phone VARCHAR(12) NULL

怎办办?

1.使用占位符;

2.框架解析重建法:搭建框架,对增删改查功能进行单独封装,传入容器对象即可;

[java] view plaincopy

  1. 1.原生:  db.execSQL("insert into person (name,age) values ("xiaoli",20)");
  2. 2.站位符:db.execSQL("insert into person (name,age) values (?,?)",new Object[]{"xiaoli",20});
  3. 3.框架 :
  4. ContentValues values = new ContentValues();
  5. values.put("name", name);
  6. values.put("age", age);
  7. db.insert("person", null, values);
  8. public void add(String name, int age) {
  9. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  10. if (db.isOpen()) {
  11. ContentValues values = new ContentValues();
  12. values.put("name", name);
  13. values.put("age", age);
  14. // 如果 contentvalues为空
  15. db.insert("person", null, values); // 组拼sql语句完成的添加的操作
  16. // insert into person name values (NULL) ;
  17. db.close();
  18. }
  19. }

最复杂的方法是查询:query

我们一起来看看底层是怎么封装的:

[java] view plaincopy

  1. public static String buildQueryString(
  2. boolean distinct, String tables, String[] columns, String where,
  3. String groupBy, String having, String orderBy, String limit) {
  4. if (TextUtils.isEmpty(groupBy) && !TextUtils.isEmpty(having)) {
  5. throw new IllegalArgumentException(
  6. "HAVING clauses are only permitted when using a groupBy clause");
  7. }
  8. if (!TextUtils.isEmpty(limit) && !sLimitPattern.matcher(limit).matches()) {
  9. throw new IllegalArgumentException("invalid LIMIT clauses:" + limit);
  10. }
  11. StringBuilder query = new StringBuilder(120);
  12. query.append("SELECT ");
  13. if (distinct) {
  14. query.append("DISTINCT ");
  15. }
  16. if (columns != null && columns.length != 0) {
  17. appendColumns(query, columns);
  18. } else {
  19. query.append("* ");
  20. }
  21. query.append("FROM ");
  22. query.append(tables);
  23. appendClause(query, " WHERE ", where);
  24. appendClause(query, " GROUP BY ", groupBy);
  25. appendClause(query, " HAVING ", having);
  26. appendClause(query, " ORDER BY ", orderBy);
  27. appendClause(query, " LIMIT ", limit);
  28. return query.toString();
  29. }

另一种增删改查:dao

[html] view plaincopy

    1. import java.util.ArrayList;
    2. import java.util.List;
    3. import cn.itcast.db.MyDBOpenHelper;
    4. import cn.itcast.db.domain.Person;
    5. import android.content.ContentValues;
    6. import android.content.Context;
    7. import android.database.Cursor;
    8. import android.database.sqlite.SQLiteDatabase;
    9. public class PersonDBDao {
    10. private Context context;
    11. MyDBOpenHelper dbOpenHelper;
    12. public PersonDBDao(Context context) {
    13. this.context = context;
    14. dbOpenHelper = new MyDBOpenHelper(context);
    15. }
    16. /**
    17. * 添加一条记录
    18. */
    19. public void add(String name, int age) {
    20. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    21. if (db.isOpen()) {
    22. // db.execSQL("insert into person (name,age) values (?,?)",new
    23. // Object[]{name,age});
    24. // db.execSQL("insert into person ",null) // 不合法的sql语句
    25. ContentValues values = new ContentValues();
    26. values.put("name", name);
    27. values.put("age", age);
    28. // 如果 contentvalues为空
    29. db.insert("person", null, values); // 组拼sql语句完成的添加的操作
    30. // insert into person name values (NULL) ;
    31. db.close();
    32. }
    33. }
    34. /**
    35. * 删除一条记录
    36. */
    37. public void delete(String name) {
    38. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    39. if (db.isOpen()) {
    40. db.delete("person", "name=?", new String[] { name });
    41. db.close();
    42. }
    43. }
    44. /**
    45. * 数据库的更改操作
    46. */
    47. public void update(String name, String newname, int newage) {
    48. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    49. if (db.isOpen()) {
    50. ContentValues values = new ContentValues();
    51. values.put("name", newname);
    52. values.put("age", newage);
    53. db.update("person", values, "name=?", new String[] { name });
    54. db.close();
    55. }
    56. }
    57. /**
    58. * 数据库的查询操作
    59. */
    60. public boolean find(String name) {
    61. boolean result = false;
    62. SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
    63. if (db.isOpen()) {
    64. // select * from person
    65. Cursor cursor = db.query("person", null, "name=?",
    66. new String[] { name }, null, null, null);
    67. if (cursor.moveToFirst()) {
    68. result = true;
    69. }
    70. cursor.close();
    71. db.close();
    72. }
    73. return result;
    74. }
    75. /**
    76. * 查询所有信息
    77. */
    78. public List<Person> findAll() {
    79. List<Person> persons = null;
    80. SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
    81. if (db.isOpen()) {
    82. Cursor cursor = db.query("person", null, null, null, null, null,
    83. null);
    84. persons = new ArrayList<Person>();
    85. while (cursor.moveToNext()) {
    86. Person person = new Person();
    87. String name = cursor.getString(cursor.getColumnIndex("name"));
    88. person.setName(name);
    89. int age = cursor.getInt(cursor.getColumnIndex("age"));
    90. person.setAge(age);
    91. persons.add(person);
    92. }
    93. cursor.close();
    94. db.close();
    95. }
    96. return persons;
    97. }
    98. /**
    99. * 查询所有信息
    100. */
    101. public Cursor findAllbyCursor() {
    102. SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
    103. if (db.isOpen()) {
    104. /*Cursor cursor = db.query("person", null, null, null, null, null,
    105. null);*/
    106. Cursor cursor = db.rawQuery("select personid as _id,age,name from person", null);
    107. return cursor;
    108. // 注意了  一定不要把数据库 关闭了
    109. }
    110. return null;
    111. }
    112. /**
    113. * 银行转账的方法
    114. * 1.开始事务:db.beginTransaction();
    115. * 2.设置事务成功:db.setTransactionSuccessful();
    116. * 3.结束事务:db.endTransaction();
    117. * 4.关闭连接:db.close();
    118. */
    119. public void transaction() {
    120. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    121. if (db.isOpen()) {
    122. try {
    123. // 开启数据库的事务
    124. db.beginTransaction();
    125. // 给张三设置1000块钱的账户
    126. db.execSQL("update person set account=? where name=?",
    127. new Object[] { 1000, "zhangsan98" });
    128. // 把张三的账户扣除200块钱
    129. db.execSQL("update person set account=account-? where name=?",
    130. new Object[] { 200, "zhangsan98" });
    131. // 出现了异常
    132. // 把张三的钱给李四
    133. //初始化李四账户 为 0
    134. db.execSQL("update person set account=? where name=?",
    135. new Object[] { 0, "lisi" });
    136. db.execSQL("update person set account=account+? where name=?",
    137. new Object[] { 200, "lisi" });
    138. db.setTransactionSuccessful();
    139. }
    140. // 显示的设置事务是否成功
    141. catch (Exception e) {
    142. // TODO: handle exception
    143. } finally {
    144. db.endTransaction();
    145. db.close();
    146. }
    147. }
    148. }
    149. }
时间: 2024-08-03 23:29:54

Android本地数据存储之SQLite关系型数据库 ——SQLiteDatabase的相关文章

处女男学Android(十四)---Android 重量级数据存储之SQLite

前言 不知不觉的Android基础系列已经写了十三篇了,这是第十四篇~上一篇blog记录了Android中的一种数据存储方案,即共享参数(Sharedpreferences)的使用(处女男学Android(十三)---Android 轻量级数据存储之SharedPreferences).最近初学如何在Android中应用SQLite,写了一个基于ListView的增删查的小例子,本篇blog就记录一下我学习到的如何在Android中操作SQLite持久化客户端数据. 初始化SQLite 关于SQ

理解 Android 本地数据存储 API

利用首选项.SQLite 和内部及外部内存 API 对于需要跨应用程序执行期间或生命期而维护重要信息的应用程序来说,能够在移动设备上本地存储数据是一种非常关键的功能.作为一名开发人员,您经常需要存储诸如用户首选项或应用程序配置之类的信息.您还必须根据一些特征(比如访问可见性)决定是否需要涉及内部或外部存储器,或者是否需要处理更复杂的.结构化的数据类型.跟随本文学习 Android 数据存储 API,具体来讲就是首选项.SQLite 和内部及外部内存 API. http://www.ibm.com

Python3网络爬虫实战-34、数据存储:非关系型数据库存储:Redis

Redis 是一个基于内存的高效的键值型非关系型数据库,存取效率极高,而且支持多种存储数据结构,使用也非常简单,在本节我们介绍一下 Python 的 Redis 操作,主要介绍 RedisPy 这个库的用法. 1. 准备工作 在本节开始之前请确保已经安装好了 Redis 及 RedisPy库,如果要做数据导入导出操作的话还需要安装 RedisDump,如没有安装可以参考第一章的安装说明. 2. Redis.StrictRedis RedisPy 库提供两个类 Redis 和 StrictRedi

Android:数据存储之SQLite

Android在运行时集成了SQLite , 所以每个Android应用程序都可以使用SQLite数据库. 我们通过SQLiteDatabase这个类的对象操作SQLite数据库,而且不需要身份验证. 数据库存放的位置:data/<项目文件夹>/databases/ public class MainActivity extends Activity { private Button createDatabase, createTable, selectData, insertData, up

大数据时代的数据存储,非关系型数据库MongoDB

在过去的很长一段时间中,关系型数据库(Relational Database Management System)一直是最主流的数据库解决方案,他运用真实世界中事物与关系来解释数据库中抽象的数据架构.然而,在信息技术爆炸式发展的今天,大数据已经成为了继云计算,物联网后新的技术革命,关系型数据库在处理大数据量时已经开始吃力,开发者只能通过不断地优化数据库来解决数据量的问题,但优化毕竟不是一个长期方案,所以人们提出了一种新的数据库解决方案来迎接大数据时代的到来——NoSQL(非关系型数据库). 为什

大数据时代的数据存储,非关系型数据库MongoDB(一)

爆炸式发展的NoSQL技术 在过去的很长一段时间中,关系型数据库(Relational Database Management System)一直是最主流的数据库解决方案,他运用真实世界中事物与关系来解释数据库中抽象的数据架构.然而,在信息技术爆炸式发展的今天,大数据已经成为了继云计算,物联网后新的技术革命,关系型数据库在处理大数据量时已经开始吃力,开发者只能通过不断地优化数据库来解决数据量的问题,但优化毕竟不是一个长期方案,所以人们提出了一种新的数据库解决方案来迎接大数据时代的到来——NoSQ

Python3网络爬虫实战-33、数据存储:非关系型数据库存储:MongoDB

NoSQL,全称 Not Only SQL,意为不仅仅是 SQL,泛指非关系型的数据库.NoSQL 是基于键值对的,而且不需要经过 SQL 层的解析,数据之间没有耦合性,性能非常高. 非关系型数据库又可以细分如下: 键值存储数据库,代表有 Redis, Voldemort, Oracle BDB 等. 列存储数据库,代表有 Cassandra, HBase, Riak 等. 文档型数据库,代表有 CouchDB, MongoDB 等. 图形数据库,代表有 Neo4J, InfoGrid, Inf

数据存储之非关系型数据库存储----MongoDB存储

MongoDB存储----文档型数据库 利用pymongo连接MongoDB import pymongo client = pymongo.MongoClient(host='localhost', port=27017) # 或 pymongo.MongoClient('mongodb://localhost:23017/') # 默认端口为:27017 # pymongo.MongoClient()方法 指定数据库 # 指定操作test数据库# db = client.test 或 db

Android基础之十四数据存储 之 SQLite数据库详解

Android基础之十四数据存储 之 SQLite数据库详解 SQLite 是一款 轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 K 的内存就足够了,因而特别适合在移动设备上使用. SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID( 原子性(Atomicity) .一致性(Consistency) . 隔离性(Isolation) . 持久性(Durability))事务,所以只要你以前使用过其他的关系型数据库,就可以很快地上手 SQLite.而