zoukankan      html  css  js  c++  java
  • Android数据存储(4):SQLite Database

      Android系统存储数据的第四种方式是SQLite Database,即数据库存储。

      该方式(数据库存储)的特点是存储私有数据,且数据是具有数据结构的,存储位置/data/data/<包名>/databases目录下。

      数据库存储有两个核心类:

      SQLiteOpenHelper类:  数据库管理类

      SQLiteDatabase类:   数据库操作类

      

      SQLiteOpenHelper查阅官方文档知:

      

      从上可知:SQLiteOpenHelper是一个帮助类,用来管理数据库的创建和数据库的版本,一般定义它的子类,实现它的两个方法onCreate,onUpdate。

      eg:

        
     1 public class DBHelper extends SQLiteOpenHelper {
     2 
     3     public DBHelper(Context context)
     4     {
     5         //第一个参数是Context对象
     6         //第二个参数是数据库的名字
     7         //第三个参数是管理游标的工厂类对象
     8         //第四个参数是当前数据库的版本
     9         super(context, "user.db", null, 1);
    10     }
    11 
    12     //创建数据库时执行该方法
    13     //表中字段必须含有一个  _id
    14     @Override
    15     public void onCreate(SQLiteDatabase db) {
    16 
    17         db.execSQL("create table t_user(_id integer primary key,name text,age int,tel text)");
    18 
    19     }
    20 
    21     //数据库版本升级时执行该方法
    22     @Override
    23     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    24 
    25         if(newVersion>oldVersion)
    26         {
    27             db.execSQL("drop table if exists t_user");
    28         }
    29     }
    30 
    31 }
    SQLiteOpenHelper子类的创建

      

      SQLiteOpenHelper类的构造方法:

      

      这里我们一般使用第一个有四个参数的构造方法,其参数含有分别为:

        

        Context context:  context对象

        String name:    创建的数据库名字

        SQLiteDatabase.CursorFactory factory:  管理数据库中游标的工厂类对象,一般设为null

        int version:    数据库的版本号,用于数据库版本的升级或降级

      SQLiteOpenHelper类的公共方法:

      

        其中我们较长使用的是:

          getReadableDatabase();  获取一个可读(不包含可写)的数据库对象,返回的是一个SQLiteDatabase对象

           getWriteableDatabase();  获取一个可写(包含可读)的数据库对象,返回的是一个SQLiteDatabase对象

      SQLiteDatabase查阅官方文档知:

        

        根据以上可知SQLiteDatabase是一个实际操作数据库的类,可执行数据库的增删改查操作。

        获取SQLiteData对象,我们一般使用上面所介绍的方法:getReadableDatabase()和getWriteableDatabase()。此外我们也可以使用SQLiteDatabase的静态方法打开一个指定的数据库。

        使用SQLiteDatabase的静态方法打开数据库:    

          

        eg:

    1 // 被操作的数据库文件的路径
    2     public static final String DB_PATH = Environment
    3             .getExternalStorageDirectory() + "/cache/db/gp.db";
    4 
    5         SQLiteDatabase  db = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);

        注释:这里打开的数据库文件位于手机的扩展卡上,此处我们也可以知道数据库存储位置也可以位于扩展卡,SQLiteDatabase可以操作扩展卡上的数据库文件。

        SQLiteDatabase常用操作:

          

       数据库存储的操作中,最重要的是查询操作,对于数据库的查询,会返回一个Cursor对象,通过Cursor对象,我们可以获取查询的结果。

       Cursor即游标,是一个与数据库操作紧密相关的类,查阅官方文档知:

          

      Cursor的常用方法:

          moveToNext();

         getColumnCount();

         getColumnNames();  返回一个字符串数组

         getColumnName();

         getColumnIndex();

         getString(),getInt(),...

       设想这样一种情景:通过数据库查询,获取结果,然后在界面ListView中显示出来。显然我们是通过适配器来适配数据,对于Cursor的使用有如下两种方式:

       方式一:可以使用一般的适配器,从Cursor中获取数据,初始化数据源。

     1 private void initListView(){
     2         ListView listView = (ListView) findViewById(R.id.listView);
     3 
     4         List<Map<String,Object>> data = new ArrayList<Map<String,Object>>();
     5 
     6         SQLiteDatabase db = dbHelper.getReadableDatabase();
     7         Cursor cursor = db.rawQuery("select * from t_user",null);
     8         while(cursor.moveToNext()){
     9             Map<String,Object> map = new HashMap<String,Object>();
    10             map.put("_id",cursor.getInt(cursor.getColumnIndex("_id")));
    11             map.put("name",cursor.getString(cursor.getColumnIndex("name")));
    12             map.put("age",cursor.getInt(cursor.getColumnIndex("age")));
    13             map.put("tel",cursor.getInt(cursor.getColumnIndex("tel")));
    14             data.add(map);
    15         }
    16 
    17         SimpleAdapter adapter =
    18                 new SimpleAdapter(this,data,R.layout.item_user,
    19                         new String[]{"_id","name","age","tel"},
    20                         new int[]{R.id.text_id,R.id.text_name,R.id.text_age,R.id.text_tel});
    21 
    22         listView.setAdapter(adapter);
    23     }

         注释:这里dbHelper是一个DatabaseOpenHelper子类的对象,已经提前创建,该处使用的是SimpleAdapter适配器。

      方式二:使用与Cursor相对应的适配器SimpleCursorAdapter

     1  private void initListView(){
     2         String[] columns={"_id","name","age","tel"};
     3         int[] to ={R.id.text_id,R.id.text_name,R.id.text_age,R.id.text_tel};
     4 
     5         ListView listView = (ListView) findViewById(R.id.listView);
     6         Cursor cursor = null;
     7         SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item_user,cursor,
     8                 columns,
     9                 to,
    10                 SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    11 
    12         listView.setAdapter(adapter);
    13 
    14 
    15         //加载数据
    16         SQLiteDatabase db = dbHelper.getReadableDatabase();
    17         cursor = db.query("t_user", columns, null, null, null, null, null);
    18 
    19         //游标中的数据变化了,需要切换适配器的数据源
    20         adapter.swapCursor(cursor);
    21 
    22     }

       这里将相应的代码分别全部集中于同一个方法,看起来有些繁琐,当然使用的时候可以从实际情况出发,以上仅为了作为例子的方便使用才这么做。

       对比这两种方式,可知:对于数据库的操作,更多的时候会返回一个Cursor对象,当我们为了在AdapterView中显示数据库中的数据,我们可以使用SimpleCursorAdapter这个类,它可以将AdapterView和Cursor(数据源)直接沟通起来.

       补上数据库添加数据的部分:

     1 private void initData() {
     2         SQLiteDatabase db = dbHelper.getWritableDatabase();
     3 
     4         ContentValues values = null;
     5 
     6         for(int i=0;i<20;i++){
     7             values = new ContentValues();
     8             values.put("_id", i);
     9             values.put("name", "Tom "+ i);
    10             values.put("age", 18 + i);
    11             values.put("tel","2323"+i);
    12 
    13             db.insert("t_user", null, values);
    14         }
    15         db.close();
    16     }

        数据库文件位置:

          

      采用两种方式呈现的结果相同:

       

       关于Cursor和SimpleCursorAdapter的详细内容,请查询相关文档或参见后续文章。

       未完,待续。  

      

        

      

        

       

  • 相关阅读:
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印一个菱形
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 打印九九乘法表
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第三题
    Martix工作室考核题 —— 201938 第一题
    fiddler模拟发送post请求
  • 原文地址:https://www.cnblogs.com/enjoy-coding/p/4896307.html
Copyright © 2011-2022 走看看