第六章《第一行代码》3.数据库储存

我博客的相关说明

持久化技术

《第一行代码》第六章学习笔记

主要介绍三种方式

  • 文件储存

  • SharedPreference储存

文章目录

  • 持久化技术
    • 主要介绍三种方式
      • 3.SQLite数据库存储
        • 3.1 创建数据库
          • ①.新建一个Activity
          • ②.修改相应布局文件
          • ③.修改住程序代码
          • ④.查看创建的文件
        • 3.2 升级数据库
          • ①.在MyDatabaseHelper中修改代码
          • ②.修改主程序中MyDatabaseHelper
        • 3.3 添加数据到表中
          • ①.再添加一个Button按钮
          • ②.修改主程序代码
        • 3.4 更新数据
          • ①.添加一个Button按钮
          • ②.修改主程序代码
        • 3.5 删除数据
          • ①.添加一个Button按钮
          • ②.修改主程序代码
        • 3.6 查询数据
          • ①.添加Button按钮
          • ②.修改主程序代码

  • 数据库储存

3.SQLite数据库存储

SQLite是Android内置的一款轻量级数据库。它支持SQL语法,还遵循ACID事物,容易上手。

3.1 创建数据库

Android为开发者提供了SQLiteOpenHelper帮助类,它是一个抽象类在使用时需要建立一个帮助类来继承它

  • SQLiteOpenHelper中有两个抽象方法:onCreate()onUpgrade(),在使用时,我们需要在自己的帮助类里边重写这两个方法,然后分别在这两个方法中实现创建、升级数据库的操作。
  • SQLiteOpenHelper之中还有两个很重要的方法:getReadableDatabase()getWritableDatabase()。这两个方法都可以创建或者打开一个数据库如果数据库存在则直接打开,否则就新建一个数据库,并且返回一个可对数据库进行读写操作的对象。二者的区别是:当数据库不可以写入的时候getReadableDatabase()方法返回的对象会以只读的方式打开数据库,而getWritableDatabase()方法则会出现异常。
    SQLiteOpenHelper中有两个构造方法可以重写,但一般只用参数少的那一个构造方法。
    这个构造方法接收四个参数:

1.Context,有了它才能对数据库进行操作。
2.数据库名。
3.Cursor,这是我们可以自定义的一个在查询数据库时 的返回值一般都是传入null
4.当前数据库版本号,它可以用来对数据库进行升级操作。

一般,构建出SQLiteOpenHelper的实例以后,再调用它的getReadableDatabase()和getWritableDatabase()方法就能够创建数据库了。数据库文件一般存放在/data/data//database/目录下。
示例:
我们创造一个名为BookStor.db的数据库。然后在数据库中添加一张Book表,里边有id、作者等信息。

①.新建一个Activity

这里建好Activity之后,我直接新建了一个Java文件,继承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(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        Toast.makeText(mContext,"创建成功!",Toast.LENGTH_SHORT).show();
    }

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

可以看到,建表语句被定义成了一个字符串常量,然后在onCreate()方法中又调用了SQLiteDatabase的execSQL()方法,去执行这条语句。
这样就可以保证,数据库完成创建的同时也成功创建了表。

②.修改相应布局文件

这里放一个Button来创建数据库。

<Button
        android:id="@+id/btn_create"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Create Database"
        android:textAllCaps="false"
        android:textSize="25sp"/>
③.修改住程序代码
public class SQLite_test extends AppCompatActivity {

    private MyDatabaseHelper dbHelper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sqlite_test);
        //构建MyDatabaseHelper对象,将文件名指定为BookStore.db
        dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1);
        Button create = findViewById(R.id.btn_create);
        create.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dbHelper.getWritableDatabase();
            }
        });
    }
}

ok,运行程序,发现第一次点击按钮会弹出Toast但第二次就不会了因为数据库存在后不会再重复创建

④.查看创建的文件

这里我们用adb shell来对数据库和表的创建进行检查。
adb是Android SDK自带的调试工具,用它可以直接对连接在电脑上的手机进行操作。它存放在sdk的platfrom-tools目录下。**查看sdk路径,可依次点击AS的File→Settings…→Appearance & Behavior→System Settings→Adroid SDK。
找到路径之后复制,然后再到环境变量里配置Path就OK。

打开控制台输入adb shell,通过cd指令进入相应目录:~这里实在不好找的话建议配合Android Device Monitor来查找相应路径~(AS3.0之后的版本参考这篇文章进入Android Device Monitor)
第六章《第一行代码》3.数据库储存_第1张图片
在这里插入图片描述
第六章《第一行代码》3.数据库储存_第2张图片
使用ls(LS)命令后可以看到目录里的文件。
之后,键入sqlite3+数据库名即可打开数据库。键入.table即可查看数据库中有哪些表。而键入.schema语句可以查看它们的建表语句。
第六章《第一行代码》3.数据库储存_第3张图片

3.2 升级数据库

MyDatabaseHelper中的onUpgrade()方法是用来升级数据库的。
如果我们还想建立一张Category表用于记录图书的分类,那么:

①.在MyDatabaseHelper中修改代码
public class MyDatabaseHelper extends SQLiteOpenHelper {

    public static final String CREATE_BOOK = ···
    
    public static final String CREAT_CATEGORY = "creat table Category("
        + "id integer primary key autoincrement, "
        + "category_name text, "
        + "category_code integer)";

    private Context mContext;

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

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREAT_CATEGORY);
        Toast.makeText(mContext,"创建成功!",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    //这里的两条drop语句,如果发现Book或者Category表则将表删除,再用onCreat()方法创建
        db.execSQL("drop table if exists Book");
        db.execSQL("drop table if exists Category");
        onCreate(db);
    }
}
②.修改主程序中MyDatabaseHelper

修改传入参数的第四个数值:

//只要比之前的数值大,onUpgrade()方法就能被执行
        dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);

重新运行程序,点击按钮,然后使用adb shell工具查看创建的表:
第六章《第一行代码》3.数据库储存_第4张图片
可以看到,BookSrtore.db数据库里边已经有Book和Category两张表了。

3.3 添加数据到表中

CRUD:对数据库的四种操作。增、删、查、改
C—Create添加,R—Retrieve查询,U—Update更新,D—Delete删除。

调用SQLiteOpenHelper的getReadableDatabase()getWriteableDatabase()方法是可以用于,创建、升级数据库的。同时,这两个方法都会返回一个SQLiteDatabase对象,借助这个对象,开发者便可以对数据库进行CRUD操作了。

SQLiteDatabase中提供了一个inset()方法用于添加数据。
它接收三个参数:

··········1.表名。即希望往哪一张表里边添加数据。
··········2.若未指定添加数据时,向某一些空的列自动赋值。一般为null
··········3.ContentValues对象。它提供一个put()方法重载,用于向ContentValues中添加数据。

示例:

①.再添加一个Button按钮

这里再添加一个Button按钮用于添加数据。

<Button
        android:id="@+id/btn_adddata"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Add Data"
        android:textAllCaps="false"
        android:textSize="25sp"/>
②.修改主程序代码
public class SQLite_test extends AppCompatActivity {

    private MyDatabaseHelper dbHelper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sqlite_test);
        //构建MyDatabaseHelper对象,将文件名指定为BookStore.db
        dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);
        Button create = findViewById(R.id.btn_create);
        create.setOnClickListener(new View.OnClickListener() {···});
        Button add = findViewById(R.id.btn_adddata);
        add.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",355);
                values.put("price",32.5);
                db.insert("Book",null,values);//插入第一条数据
                //组装第二条数据
                values.put("name","The Lost Symbol");
                values.put("author","Dan Brown");
                values.put("pages",423);
                values.put("price",45.5);
                db.insert("Book",null,values);//插入第二条数据
            }
        });
    }
}

可以看到,这里添加了两条数据到Book表里边。点击运行,点击相应按钮。
第六章《第一行代码》3.数据库储存_第5张图片
使用adb shell查看表中数据:select *from Book;
第六章《第一行代码》3.数据库储存_第6张图片
(这里我点击了两下,就多添加了两条数据)

3.4 更新数据

SQLiteDatabase中提供了一个update()方法用于数据更新。
这个方法接收四个参数:

··········1.表名。用于指定更新哪一张表里的数据。
··········2.ContentValues对象,将更新的数据组装进去。
··········3、4.用于约束更新特定行或几行的数据,默认全部更新。

示例:

①.添加一个Button按钮

添加一个Update按钮用于数据更新

<Button
        android:id="@+id/btn_update"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Update Data"
        android:textAllCaps="false"
        android:textSize="25sp"/>
②.修改主程序代码
public class SQLite_test extends AppCompatActivity {

    private MyDatabaseHelper dbHelper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sqlite_test);
        //构建MyDatabaseHelper对象,将文件名指定为BookStore.db
        dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,4);
        Button create = findViewById(R.id.btn_create);
        create.setOnClickListener(new View.OnClickListener() {···});
        Button add = findViewById(R.id.btn_adddata);
        add.setOnClickListener(new View.OnClickListener() {···});

        Button btn_update = findViewById(R.id.btn_update);
        btn_update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                ContentValues values = new ContentValues();
                values.put("price",20.8);
                db.update("Book",values,"name = ?",new String[]{"The Da Vinci Code"});
            }
        });
    }
}

这里我们指定了将价格这一列的数据,更新为20.8,然后调用了update()方法来执行具体的操作。

  • 第三个参数"name = ?"对应的是SQL语句中的where部分,表示更新所有name等于?的行这里的?代表占位符
  • 第四个参数提供一个字符串数组为第三个参数中每一个对应的?指定相应的内容。
    所以db.update("Book",values,"name = ?",new String[]{"The Da Vinci code"});的意思是,将名字为The Da Vinci Code这本书的价格改为20.8.
    在这里插入图片描述

3.5 删除数据

与添加数据和更新数据相似,SQLiteDatabase中也提供了相应的delete()方法。
这个方法接收三个参数:

··········1.表名
··········2、3.用于约束删除某几行

示例:

①.添加一个Button按钮

添加一个Button按钮用来删除数据

<Button
        android:id="@+id/btn_delate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Delate Data"
        android:textAllCaps="false"
        android:textSize="25sp"/>
②.修改主程序代码
public class SQLite_test extends AppCompatActivity {

    private MyDatabaseHelper dbHelper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sqlite_test);
        //构建MyDatabaseHelper对象,将文件名指定为BookStore.db
        dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,5);
        ···
        Button btn_delete = findViewById(R.id.btn_delate);
        btn_delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                db.delete("Book","pages > ? ",new String[]{"400"});
            }
        });
    }
}

这里我们想要把页数大于400的书籍删除,运行程序,点击删除按钮。
在这里插入图片描述
可以看到,删除成功!

3.6 查询数据

SQLiteDatabase同样提供了查询方法query()
这个方法接收七个参数:

query()方法参数 对应SQL部分 描 述
table from table_name 指定查询的表名
columns select column1,column2 指定查询的列名
selection where column = value 指定的where约束条件
selectionArgs - 为where中的占位符提供具体的值
groupBy group by column 指定需要group by的列
having having cloumn = value 对group by的结果进一步约束
orderBy order by column1,column2 指定查询结果的排序方式

调用query()方法后会返回一个Cursor对象,查询到的数据都将从这个对象当中取出。
示例:

①.添加Button按钮
<Button
        android:id="@+id/btn_query"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Query Data"
        android:textAllCaps="false"
        android:textSize="25sp"/>
②.修改主程序代码
public class SQLite_test extends AppCompatActivity {

    private MyDatabaseHelper dbHelper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sqlite_test);
        ···
        Button btn_query = findViewById(R.id.btn_query);
        btn_query.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                //查询表中所有数据
                Cursor cursor = db.query("Book",null,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"));
                        Toast.makeText(SQLite_test.this,"name"+name+"\nauthor"+author+"\npages"+pages+"\nprice"+price,Toast.LENGTH_SHORT).show();
                    }while (cursor.moveToNext());
                }
                cursor.close();
            }
        });
    }
}

这里只传入query()的第一个表明参数,其余全是null。表示查询这张表中的所有数据。查询完之后得到一个Cursor对象,接着调用它的moveToFrist()方法来将指针移动到列表第一行。之后遍历列表中的所有数据。我们用Toast方法将查询结果打印出来。
第六章《第一行代码》3.数据库储存_第7张图片
ok,到这里第六章的数据库存储就告一段落。

下一节:《第一行代码》使用SQL操作数据库。

你可能感兴趣的:(Android自学笔记)