Android | SQLite的使用(附步骤提炼)

核心:SQLiteOpenHelper帮助类(是一个抽象类)

借助这个类就可以非常简单地对数据库进行创建和升级;

创建数据库

  • SQLiteOpenHelper是抽象类,需创建自己的类继承;

  • 其中有两个抽象方法,
    onCreate()onUpgrade()
    需重写,实现创建升级数据库的逻辑。

  • 还有两个重要的实例方法:
    getReadableDatabase()getWritableDatabase()
    都可创建打开现有数据库(数据库已经存在则直接打开,没有则创建),
    并返回可对数据库进行读写操作的对象。

    其不同:当数据库不可写入时(如磁盘空间已满)
    前者返回的对象以getReadableDatabase()打开数据库,getWritableDatabase()将出现异常

  • SQLiteOpenHelper有两个构造方法可供重写,
    一般使用参数少一点的那个构造方法,
    其接收四个参数:
    Context
    数据库名,创建数据库时使用的就是这里指定的名称
    允许查询数据时返回一个自定义的Cursor(一般传入null),
    当前数据库版本号(用于升级操作)。

构建SQLiteOpenHelper实例后,
再调用他的getReadableDatabase()/getWritableDatabase()方法就能创建数据库
(数据库文件会存放在/data/data//databases/目录下)。
此时重写的onCreate()方法被执行(通常处理创建表的逻辑)。!!!!!!

示例代码

创建名为BookStore.db的数据库,并新建一张Book表。
新建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)" ;
    private Context mContext;

    public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //在数据库创建完成时创建Book表
        db.execSQL(CREATE_BOOK);
        Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

注意autoincrement表示id是自增长的;

使用MyDatabaseHelper创建数据库

public class MainActivity extends AppCompatActivity {
    private MyDatabaseHelper dbhelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //构建SQLiteOpenHelper实例
        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) {
                //调用SQLiteOpenHelper实例的getReadableDatabase()/getWritableDatabase()方法
              //就能创建数据库了
              //此时重写的onCreate()方法被执行
              //如以上所写,则创建了Book表
                dbhelper.getWritableDatabase();
            }
        });
    }
}

升级(更新)数据库

基于以上代码,
再添加一张Category表用于记录图书分类,
在继承自SQLiteOpenHelperMyDatabaseHelper类中添加代码:
(添加的地方以感叹号标记,一共四处)

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)" ;
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1.
    public static final String CREATE_CATEGORY = "create table Category ("
            + "id integer primary key autoincrement, "
            + "category_name text, "
            + "category_code integer)";**

    private Context mContext;

    public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //在数据库创建完成时创建Book表
        db.execSQL(CREATE_BOOK);

        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2.
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    
        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 3.
        db.execSQL("drop table if exists Book");
        db.execSQL("drop table if exists Category");
        onCreate(db); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 4.

    }
}

再次调用getWritableDatabase();时,
onCreate()不会再执行了,
因为数据库只能创建一次,刚刚已经创建过了;

所以这里只能在onUpgrade()中,
执行Drop将原来的表删掉,
再重新调用onCreate()方法,
这样一开始的表新加的表都会被创建;

调用onUpgrade()

构造SQLiteOpenHelper实例的时候,
第四个参数(version)传入大于旧版本的数字
即可让onUpgrade()执行,进而更新数据库:

public class MainActivity extends AppCompatActivity {
    private MyDatabaseHelper dbhelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        dbhelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        Button createDatabase = (Button) findViewById(R.id.create_database);
        createDatabase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dbhelper.getWritableDatabase();
            }
        });
    }
}

CRUD核心:
getReadableDatabase()getWritableDatabase()返回的SQLiteDatabase对象;
在Android中即使不去编写SQL语句,
提供了一系列辅助性方法,
也能轻松完成所有CRUD操作。

SQLiteOpenHelper的两个实例方法getReadableDatabase()/getWritableDatabase()
会返回SQLiteDatabase对象,
借助这个对象就可对数据进行CRUD操作。

添加数据

首先调用ContentValues实例的各种重载的put(表的某个属性,值)方法,
ContentValues实例自身中添加数据

接着调用insert()即可将数据加到对应的表中;
它接收三个参数:

  1. 表名,指定向哪张表添加数据;
  2. 用于在未指定添加数据的情况下,
    给某些可为空的列自动复赋值NULL,
    一般用不到这个功能,
    直接传入NULL即可;
  3. ContentValues实例;
public class MainActivity extends AppCompatActivity {
    private MyDatabaseHelper dbhelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dbhelper = new MyDatabaseHelper(this, "BookStore.db", null, 2);
        Button createDatabase = ...

        Button addData = (Button) findViewById(R.id.add_data);
        addData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbhelper.getWritableDatabase();
               
                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);//插入第二条数据
            }
        });
        ...

更新数据

  1. 首先调用ContentValues实例的各种重载的put(表的某个属性,值)方法,
  2. 接着调用update()实现更新——
    第三、四个参数用于约束更新某一行或某几行数据,
    默认更新所有行;
    第三个参数对应SQL的where语句,占位符
    通过第四个参数提供的字符串数组指定相应内容
    第一参数表名,第二参数ContentValues实例;
 Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            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"});
            }
        });

上述代码表达的意图将name为The Da Vinci Code的这本书的价格改成10.99;

删除数据

  • 直接用SQLiteDatabase实例调用delete()
    其第一参,表明;
    二三参,同update()的三四参;
 Button button = (Button) findViewById(R.id.delete_data);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbhelper.getWritableDatabase();
                db.delete("Book", "pages > ?", new String[]{"500"});
            }
        });

查询数据

  • 通过query()进行查询;
    其重载方法多,参数复杂,
    我们看参数最少(7个参数)的一个;
    参数对应内容可参考下表:
    (其三四参,同update()的三四参;)
    Android | SQLite的使用(附步骤提炼)_第1张图片

  • query()参数多,
    但是多数情况不必要全部参数都用,
    指定少数几个参数即可完成查询
    (如只传入第一个参数表名,
    后面全为null,则查询表中的所有数据);

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

示例代码:

Button queryButton = (Button) findViewById(R.id.query_data);
        queryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbhelper.getWritableDatabase();
                //查询Book表中所有数据
                Cursor cursor = db.query("Book", null,null,null,null,null,null);
                if (cursor.moveToFirst()){
                    do {
                        //遍历Cursor对象,取出数据并打印
                        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("MainActivity", "book name is " + name);
                        Log.d("MainActivity", "book author is " + author);
                        Log.d("MainActivity", "book pages is " + pages);
                        Log.d("MainActivity", "book price is " + price);
                    }while (cursor.moveToNext());
                }
                cursor.close();
            }
        });

Cursor实例每次指向返回数据表的一行,
通过moveToFirst()moveToNext()等方法来调节其指向的位置;
令其指向某一行,或者一行一行遍历返回的数据表,
对返回的数据进行处理即可。

项目码云地址

你可能感兴趣的:(Android | SQLite的使用(附步骤提炼))