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

 

二、创建dao

 

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

 

 

三、单元测试:测试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.   
  5. <application  
  6.     android:icon="@drawable/ic_launcher"  
  7.     android:label="@string/app_name" >  
  8.     <uses-library android:name="android.test.runner" />      //该程序需要添加哪个jar包(用于测试)?  



 

2.编程测试

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



 

框架思想

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

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

 

最复杂的方法是查询: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.   
  12.     StringBuilder query = new StringBuilder(120);  
  13.   
  14.     query.append("SELECT ");  
  15.     if (distinct) {  
  16.         query.append("DISTINCT ");  
  17.     }  
  18.     if (columns != null && columns.length != 0) {  
  19.         appendColumns(query, columns);  
  20.     } else {  
  21.         query.append("* ");  
  22.     }  
  23.     query.append("FROM ");  
  24.     query.append(tables);  
  25.     appendClause(query, " WHERE ", where);  
  26.     appendClause(query, " GROUP BY ", groupBy);  
  27.     appendClause(query, " HAVING ", having);  
  28.     appendClause(query, " ORDER BY ", orderBy);  
  29.     appendClause(query, " LIMIT ", limit);  
  30.   
  31.     return query.toString();  
  32. }  



 

另一种增删改查:dao

 

 

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