Android数据存储(三)——SQLiteDatabase 操作 SQLite

一、创建数据库

1、SQLiteOpenHelper

Android 提供了SQLiteOpenHelper这个抽象类对数据库创建和升级,必须要重写onCreate()onUpgrade()才行

这个类有两个重要实例方法,getReadableDatabase()getWritableDatabase(),两者都能打开数据库【存在则打开,否则创建后打开】,并返回一个可供读写操作的对象。当数据库不可被写入的时候,getReadableDatabase()会以只读的方式打开数据库,getWritableDatabase()则抛出异常

这个类有构造方法可供重写,其有四个参数:

  1. Context:上下文对象
  2. 数据库名,创建数据库指定的名称
  3. 一般传入null
  4. 数据库版本号,用于数据库升级

数据库文件默认存储位置:/data/data/<package name>/databases/

2、实战

新建一个空项目:day12_DatabaseTest

a. SQL

建一张BookStore.db数据库,其有一张Book表,SQL语句如下:

create table Book(
	id integer primary key autoincrement,
	author text,
	price real,
	pages integer,
	name text)

real 表示浮点型,blob表示二进制型

在代码中执行这段语句,需要新建MyDatabaseHelper类继承自SQLiteOpenHelper,代码如下:

ublic class MyDatabaseHelper extends SQLiteOpenHelper {
    private Context mContext;

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

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

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

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

b. 主页

主布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="创建数据库"
        android:id="@+id/create_database"/>

</LinearLayout>

主活动

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, 1);
        Button createDatabase = findViewById(R.id.create_database);
        createDatabase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dbHelper.getWritableDatabase();
            }
        });
    }
}

c. 运行

多次点击按钮,会发现这里的Toast只会弹出一次,因为数据库已经建好了
在这里插入图片描述
查看数据库文件:
在这里插入图片描述
我们可以看到数据库BookStore.db,那么它里面的数据表数和查看呢?

d. 查看数据表

查看数据表需要adb工具adb工具Android SDK下的platform-tools目录下,为了便于使用它,想把它的路径添加到环境变量:
在这里插入图片描述
打开命令行,输入adb shell就能进入控制台,输入su切换超级管理员:
在这里插入图片描述
接下来cd到数据库目录下:
在这里插入图片描述
输入sqlite3 数据库名就能打开数据库
在这里插入图片描述
查看有哪些表:.table
查看建表语句:.schema
在这里插入图片描述
android_metadatasqlite_sequence是自动创建的表,不用管
最后.exit退出

二、升级数据库

任务:再添加一个Category表在数据库里,建表语句

create table Category(
	id integer primary key autoincrement,
	category_name text,
	category_code integer)

1、要注意的问题

  • 原来的数据库已经存在了,那么再次CreateonCreate()也不会执行,那么新的表就无法创建了
  • 因此,我们要定义onUpgrade()逻辑:当存在旧的表时,就删除旧的表,再执行onCreate()重新建表
  • 如何让onUpgrade()执行呢,修改SQLiteOpenHelper的构造方法第四个参数,版本号改大就行

2、实战

在代码中修改MyDatabaseHelper类继承自SQLiteOpenHelper,代码如下:

public class MyDatabaseHelper extends SQLiteOpenHelper {
    private Context mContext;

    public static final String CREATE_BOOK = "create table Book( id integer primary key autoincrement, author text, price real, pages integer, name text)";
    public static final String CREATE_CATAGORY = "create table Category( id integer primary key autoincrement, category_name text, category_code integer)";

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

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

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

主活动只需要改一下版本号:

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

运行的的时候发现,也是点击一次有Toast,多次点击并没有Toast,这是因为版本号的限制

最后在adb下查看数据表:
在这里插入图片描述

三、增

SQLiteOpenHelper.insert() 三个参数:

  • 参数一:表名
  • 参数二:传null
  • 参数三:ContentValues对象,提供了一系列的put()方法重载,传入列名和数据就行

1、主布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
......
    
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:id="@+id/insert"/>

</LinearLayout>

2、主活动

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 = findViewById(R.id.create_database);
        Button button_insert = findViewById(R.id.insert);
        createDatabase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dbHelper.getWritableDatabase();
            }
        });
        button_insert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                ContentValues values = new ContentValues();
                // 第一条数据
                values.put("name", "老人与海");
                values.put("author", "海明威");
                values.put("pages", 456);
                values.put("price", 18.88);
                db.insert("Book", null, values);
                values.clear();
                // 第二条数据
                values.put("name", "绿野仙踪");
                values.put("author", "莱曼·弗兰克·鲍姆");
                values.put("pages", 345);
                values.put("price", 16.66);
                db.insert("Book", null, values);
            }
        });
    }
}

3、运行

点击三下增按钮:
在这里插入图片描述
adb中查一下,果然增加了三组:
在这里插入图片描述

四、改

SQLiteOpenHelper.update() 四个参数:

  • 参数一:表名
  • 参数二:ContentValues对象,提供了一系列的put()方法重载,传入列名和数据就行
  • 参数三、参数四用于约束,限制某一行或某几行的数据,不指定则是更新所有行

1、主布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

。。。。。。
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:id="@+id/update"/>

</LinearLayout>

2、主活动

Button button_update = findViewById(R.id.update);
        button_update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getReadableDatabase();
                ContentValues values = new ContentValues();
                values.put("price", 10.99);
                db.update("Book",values, "name = ?",new String[]{"老人与海"});
            }
        });

第三个参数对应SQL语句中的where部分,表示更新所有name = ?的行,?是个占位符,即第四个参数提供的字符数组的第一个数即对应内容。

完整意义:
Book表中,把name 等于 老人与海 的行的price修改为10.99

3、运行

点击一下改按钮:
在这里插入图片描述
相应三行的数据都被修改【之前的截图也放到一起,便于对比
】:
在这里插入图片描述

五、删

SQLiteOpenHelper.delete() 三个参数:

  • 参数一:表名
  • 参数二、参数三用于约束,限制某一行或某几行的数据,不指定则是删除所有相应行

修改主布局~
修改主活动:

Button button_delete = findViewById(R.id.delete);
        button_delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getReadableDatabase();
                db.delete("Book", "pages > ?", new String[]{"400"});
            }
        });

运行:

六、查

SQLiteOpenHelper.quary() 七个参数:

  • 参数一:table,表名
  • 参数二:columns,列名
  • 参数三:selection,where约束条件
  • 参数四:selectionArgs,占位符提供值
  • 参数五:groupBy,分组查询
  • 参数六:having,进一步约束
  • 参数七:orderBy,排序方式
  • 会返回Cursor对象,查询到的数据从这个对象中取出

主布局修改~
主活动修改:

Button button_quary = findViewById(R.id.quary);
        button_quary.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getReadableDatabase();
                // 查询表中所有的数据
                Cursor cursor = db.query("Book",null, null, null, null, null, null);
                if (cursor.moveToFirst()){
                    do{
                        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(TAG, "--------------------");
                        Log.d(TAG, "书名:"+name);
                        Log.d(TAG, "作者:"+author);
                        Log.d(TAG, "页数:"+pages);
                        Log.d(TAG, "价格:"+price);
                        Log.d(TAG, "--------------------");
                    }while (cursor.moveToNext());
                }
                cursor.close();
            }
        });

别忘了最后要关闭cursor

运行:
在这里插入图片描述

七、使用SQL操作数据库

艹,前面的白学了,使用下面这个最简单

1、增

db.execSQL("insert into 表名(列1,列2,列3...) values (值1,值2,值3...)")

2、删

db.execSQL("delete from 表名 wherr 列名 > ?", new String[]{})

3、改

db.execSQL("update 表名 set 列名 = ? where 列名 > ?", new String[]{1,值2})

4、查

db.rawQuery("select * from Book", null);
发布了156 篇原创文章 · 获赞 13 · 访问量 7219

猜你喜欢

转载自blog.csdn.net/qq_41205771/article/details/104190555