【第一行代码】DatabaseTest 和 ProviderTest

简介

DatabaseTest
对数据的可持续存储,除了将数据存到文件中或者利用SharedPreferences存储键值对。也可以用数据库来处理,并且Android系统自身就内置了一个数据库–SQLite,SQLite是一款轻量级的关系型数据库,运算速度块,占用资源少。可以轻松的应对大量且复杂的关系型数据。

ProviderTest
对DatabaseTest提供的内容提供器进行 插入 更新 删除 查询功能

项目目录列表

在这里插入图片描述在这里插入图片描述

成果展示

对于这些功能的测试都是通过log打印出来的,对数据库进行插入,更新,删除,查询已经监听数据库的数据内容都是可用的
在这里插入图片描述在这里插入图片描述

关键代码

DatabaseTest部分代码

/**
 *可以借助SQLiteOpenHelper类对数据库进行创建和升级
 *继承SQLiteOpenHelper需要重写onCreate()和onuPgrade()
 *构造函数接收四个参数
 *第一个参数是context
 *第二个是数据库名
 *第三个参数允许在查询数据的时候返回一个自定义的Cursor,一般传入null
 *第四个参数表示当前数据库的版本号,可用于对数据库进行升级操作
 */
public class MyDatabaseHelper extends SQLiteOpenHelper {
    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) {}
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}

/**
 *创建数据表
 *integer 整型; real 浮点型; text 文本类型; blob 二进制类型
 *primary key 设为主键
 *autoincreament 自增长
 */
public static final String CREATE_BOOK = "create table Book ("
        + "id integer primary key autoincrement, "
        + "author text, "
        + "price real, "
        + "pages integer, "
        + "name text)";
//然后在onCreate函数里加上
db.execSQL(CREATE_BOOK);
关于数据库的CRUD的操作:
private MyDatabaseHelper databaseHelper;
//创建数据库
databaseHelper = new MyDatabaseHelper(this,"BookStore.db", null, 1);
//获得数据库实例句柄
SQLiteDatabase database = databaseHelper.getWritableDatabase();
//insert data
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");
database.insert("Book", null, values);
//update data
ContentValues values = new ContentValues();
values.put("price", 10.99);
database.update("Book", values, "name = ?",new String[]{"The Da Vinci Code"});
//delete data
database.delete("Book", "pages > ?",new String[]{"500"});
//query data
Cursor cursor = database.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", name + " " + author +" " + pages + " " + price);
	}while (cursor.moveToNext());
}
cursor.close();

当已经用上数据库存放数据的时候,不得不考虑这样一个情况,能不能让几个应用都利用同一个数据库,即把一个数据库当成一个仓库,几个应用就好比供应商,大家都从这个仓库进行拿货存货(读写值)。
这个时候,就可以利用ContentProvider,Android四大组件之一,利用这个类可以实现将一个数据库共享出去,让其他的应用可以对这个数据库进行读写以及监听。

/**
 *新建一个DatabaseProvider类,继承ContentProvider
 *重写onCreate(), delete(), getType(), insert(), query(), update();
 */
public class DatabaseProvider extends ContentProvider {
    //初始化内容提供者的时候会调用。当ContentResolver尝试访问程序中的数据时,会被初始化
    @Override
    public boolean onCreate() {
        return false;
    }
    /**
     *从内容提供器中查询数据
     *Uri 确定查询哪张表
     *projection 确定查询哪些列
     *selection和selectionArgs 约束查询哪些行
     *sortOrder 对结果进行排序
     *查询的结果存放在Cursor对象中返回
     */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        return null;
    }
    /**
     *向内容提供器中插入数据
     *Uri 确定查询哪张表
     *values 存放需要插入的数据
     *返回一个用于表示这条新纪录的Uri
     */
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return 0;
    }
    /**
     *更新内容提供器中已有的数据
     *Uri 确定查询哪张表
     *values 存放需要插入的数据
     *selection和selectionArgs 约束更新哪些行
     *受影响的行数将作为返回值返回
     */
    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return 0;
    }
    /**
     *从内容提供器中删除	数据
     *Uri 确定查询哪张表
     *selection和selectionArgs 约束删除哪些行
     *被删除的行数将作为返回值返回
     */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }
    /**
     *根据传入的内容URI来返回相应的MIME类型
     *Uri 确定查询哪张表
     */
    @Override
    public String getType(Uri uri) {
        return null;
    }
}

ProviderTest代码

package com.example.providertest;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private String newId;

	//监听回调函数
    private ContentObserver changeObserver =
            new ContentObserver(new Handler()) {
                @Override
                public void onChange(boolean selfChange) {
                    Log.d(TAG, "onChange: ");
                }
            };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //注册监听,监听book数据表
        //需要在DatabaseProvider中重写的crud函数中,添加getContext().getContentResolver().notifyChange(uri,null);
        this.getContentResolver().registerContentObserver(
                Uri.parse("content://com.example.databasetest.provider/book"),
                true, changeObserver);

		//插入,更新,删除,查询
        //insert data
        Button addData = (Button) findViewById(R.id.add_data);
        addData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
                ContentValues values = new ContentValues();
                values.put("name", "A Clash of King");
                values.put("author", "George Martin");
                values.put("pages", 1040);
                values.put("price", 22.85);
                Uri newUri = getContentResolver().insert(uri, values);
                newId = newUri.getPathSegments().get(1);
                Log.d(TAG, "onClick: add"+newId);
            }
        });

        //update data
        Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Uri uri = Uri.parse("content://com.example.databasetest.provider/book/" + newId);
                ContentValues values = new ContentValues();
                values.put("name", "A Storm of Swords");
                values.put("pages", 1216);
                values.put("price", 24.05);
                getContentResolver().update(uri, values, null, null);
                Log.d(TAG, "onClick: update");
            }
        });

        //delete data
        Button deleteData = (Button) findViewById(R.id.delete_data);
        deleteData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Uri uri = Uri.parse("content://com.example.databasetest.provider/book/" + newId);
                getContentResolver().delete(uri, null, null);
                Log.d(TAG, "onClick: delete");
            }
        });

        //query data
        Button queryData = (Button) findViewById(R.id.query_data);
        queryData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d(TAG, "onClick: query");
                Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
                Cursor cursor = getContentResolver().query(uri, null, null,
                        null, null);
                if(cursor != null) {
                    while(cursor.moveToNext()) {
                        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", name+author+pages+price);
                    }
                    cursor.close();
                }
            }
        });
    }
}

相关知识补充

Uri格式
标准格式:content://com.example.app.provider/table1
可以在标准格式后面加上id:content://com.example.app.provider/table1/1
标准格式表示访问表中所有的数据,加id的表示访问该表中拥有相应id的数据
利用通配符可以有
*:表示匹配任意长度的任意字符
#:表示匹配任意长度的数字
content://com.example.app.provider/* ===> 匹配任意表的内容URI格式
content://com.example.app.provider/table1/# ===> 匹配table1表中任意一行数据的内容URI格式
利用UriMatcher类可以帮助实现匹配内容Uri的功能。
通过addURI方法将数据表以及数据表中的内容Uri存进去
uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
通过UriMatcher.match(uri)判断调用方期望访问的数据内容
Uri格式 --> MIME类型
content://com.example.app.provider/table1 --> vnd.android.cursor.dir/vnd.com.example.app.provider.table1
content://com.example.app.provider/table1/1 --> vnd.android.cursor.item/vnd.com.example.app.provider.table1

项目源码下载

DatabaseTest github
ProviderTest github

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值