• 使用SQLite存储数据


    一.SQLite
    Android 为了让我们能够更加方便地管理数据库, 专门提供了一个SQLiteOpenHelper 帮助类,借助这个类就可以非常简单地对数据库进行创建和升级.

    1.SQLiteOpenHelper 是一个抽象类,这意味着如果我们想要使用它的话,就需要创建一个自己的帮助类去继承它。SQLiteOpenHelper 中有两个抽象方法,分别是onCreate()和onUpgrade(),我们必须在自己的帮助类里面重写这两个方法,然后分别在这两个方法中去实现创建、升级数据库的逻辑

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

    3.SQLiteOpenHelper 中有两个构造方法可供重写,一般使用参数少一点的那个构造方法即可。这个构造方法中接收四个参数,第一个参数是Context,这个没什么好说的,必须要有它才能对数据库进行操作。第二个参数是数据库名,创建数据库时使用的就是这里指定的名称。第三个参数允许我们在查询数据的时候返回一个自定义的Cursor,一般都是传入null。第四个参数表示当前数据库的版本号,可用于对数据库进行升级操作。

    构建出SQLiteOpenHelper 的实例之后, 再调用它的getReadableDatabase() 或getWritableDatabase() 方法就能够创建数据库了, 数据库文件会存放在/data/data/<package name>/databases/目录下。此时,重写的onCreate()方法也会得到执行,所以通常会在这里去处理一些创建表的逻辑。

    4.adb操作sqlite:
    (1).将adb添加到环境变量,将sdk下platform-tools目录添加到环境变量
    (2).adb shell
    (3).cd /data/data/包名目录/databases
    (4).sqlite3 db名称
    (5).列出数据表: .table
    建表语句: .schema
    其余的sql语句


    二.示例

    1.新建MyDatabaseHelper,继承自SQLiteOpenHelper:

    public class MyDatabaseHelper extends SQLiteOpenHelper {
    
        public static final String CREATE_SQL = "create table Book (" +
                "id integer primary key autoincrement," +
                "author text," +
                "price real," +
                "pages integer," +
                "name text)";
    
        private Context context;
    
        public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
                                int version) {
            super(context, name, factory, version);
            this.context = context;
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_SQL);
            Toast.makeText(context, "数据表已经建立", Toast.LENGTH_LONG).show();
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
           
        }
    }
    

      

    2.MainActivity中代码

    public class MainActivity extends Activity {
        MyDatabaseHelper dbHelper;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            dbHelper = new MyDatabaseHelper(this, "Book.db", null, 1);
        }
    
        protected void createDb(View v){
            if( v.getId() == R.id.btn ){
                dbHelper.getWritableDatabase();
            }
        }
    }
    

      

    3.但我们第一次点击创建时,提示创建完毕.第二次点击时,将没有反应.

    4.数据库升级.
    (1).如果我们再新建一个表

    public static final String CREATE_BOOK_CAT = "create table BookCat (" +
                "id integer primary key autoincrement," +
                "author text," +
                "price real," +
                "pages integer," +
                "name text)";
    

      

    (2).在onCreate中执行

    db.execSQL(CREATE_BOOK_CAT);
    

      

    点击按钮后,发现并不会有任何反应,这在于数据库之前已经有新建.

    (3).升级数据库代码(onUpgrade)

    public class MyDatabaseHelper extends SQLiteOpenHelper {
    
        public static final String CREATE_SQL = "create table Book (" +
                "id integer primary key autoincrement," +
                "author text," +
                "price real," +
                "pages integer," +
                "name text)";
        public static final String CREATE_BOOK_CAT = "create table BookCat (" +
                "id integer primary key autoincrement," +
                "author text," +
                "price real," +
                "pages integer," +
                "name text)";
    
        private Context context;
    
        public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
                                int version) {
            super(context, name, factory, version);
            this.context = context;
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_SQL);
            db.execSQL(CREATE_BOOK_CAT);
            Toast.makeText(context, "数据表已经升级", Toast.LENGTH_LONG).show();
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("drop table if exists Book");
            db.execSQL("drop table if exists BookCat");
            onCreate(db);
        }
    }
    

      

    每一个数据库版本都会对应一个版本号, 当指定的数据库版本号大于当前数据库版本号的时候, 就会进入到onUpgrade()方法中去执行更新操作。

    因此还需要在活动中更改数据库的版本号

    dbHelper = new MyDatabaseHelper(this, "Book.db", null, 2);
    

      


    三.SQLite增加/修改/删除/查询数据(CRUD)

    1.增加数据:

    protected void addData(View v){
            if( v.getId() == R.id.add_btn ) {
                SQLiteDatabase sqLiteDatabase = dbHelper.getWritableDatabase();
                ContentValues values = new ContentValues();
                values.put("author", "john");
                values.put("price", 10.2);
                values.put("pages", 500);
                values.put("name", "奇幻之旅");
                sqLiteDatabase.insert("Book", null,values);
            }
        }
    

      

    2.修改数据

    protected void updateData(View v){
            if( v.getId() == R.id.update_btn ) {
                SQLiteDatabase sqLiteDatabase = dbHelper.getWritableDatabase();
                ContentValues values = new ContentValues();
                values.put("name", "qihuanzhilv2");
                sqLiteDatabase.update("Book", values, "author=?", new String[]{"john"});
            }
        }
    

      

    3.删除数据

    SQLiteDatabase sqLiteDatabase = dbHelper.getWritableDatabase();
    sqLiteDatabase.delete("Book", "pages>=?", new String[]{"500"});
    

      

    4.查询数据
    SQLiteDatabase 中还提供了一个query()方法用于对数据进行查询。这个方法的参数非常复杂,最短的一个方法重载也需要传入七个参数。那我们就先来看一下这七个参数各自的含义吧,第一个参数不用说,当然还是表名,表示我们希望从哪张表中查询数据。第二个参数用于指定去查询哪几列,如果不指定则默认查询所有列。第三、第四个参数用于去约束查询某一行或某几行的数据,不指定则默认是查询所有行的数据。第五个参数用于指定需要去group by 的列,不指定则表示不对查询结果进行group by 操作。第六个参数用于对group by 之后的数据进行进一步的过滤,不指定则表示不进行过滤。第七个参数用于指定查询结果的排序方式,不指定则表示使用默认的排序方式。更多详细的内容可以参考下表。其他几个query()方法的重载其实也大同小异.

    关键代码:

    protected  void readData(View v){
            if( v.getId() == R.id.read_btn ){
                SQLiteDatabase sqLiteDatabase = dbHelper.getWritableDatabase();
                Cursor cursor = sqLiteDatabase.query("Book",null,null,null,null,null,null);
                // sql执行
                cursor = sqLiteDatabase.rawQuery("SELECT * FROM Book;",null);
                if( cursor.moveToFirst() ){
                    do{
                        Log.d("ID:"+cursor.getInt(cursor.getColumnIndex("id")),
                                cursor.getString(cursor.getColumnIndex("name")));
    
                    }while (cursor.moveToNext());
                }
                cursor.close();
            }
        }
    

      


    5.使用sql语句:

    添加数据的方法如下:

    db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",new String[] { "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" });


    更新数据的方法如下:

    db.execSQL("update Book set price = ? where name = ?", new String[] { "10.99", "The DaVinci Code" });
    

      


    删除数据的方法如下:

    db.execSQL("delete from Book where pages > ?", new String[] { "500" });
    

      


    查询数据的方法如下:

    db.rawQuery("select * from Book", null);
    

      


    可以看到,除了查询数据的时候调用的是SQLiteDatabase 的rawQuery()方法,其他的操作都是调用的execSQL()方法。

  • 相关阅读:
    多态
    多继承
    传宗接代——继承
    解决vue项目更新版本后浏览器的缓存问题
    escape()、encodeURI()、encodeURIComponent()三种编码方式的区别
    epoll使用总结
    探讨c/c++的指针
    基于linux的pthread_t封装一个Thread类
    unix高并发编程中遇到的问题和笔记
    面向对象分析与设计 实验七
  • 原文地址:https://www.cnblogs.com/itfenqing/p/6740977.html
Copyright © 2020-2023  润新知