博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android网络与数据存储_学习笔记_第六周:SQLite与ContentProvider
阅读量:4084 次
发布时间:2019-05-25

本文共 9325 字,大约阅读时间需要 31 分钟。

SQLite

什么是SQLite数据库?

特色:

轻量级、独立、隔离、跨平台、多语言接口、安全性。

如何和数据库打交道

1、设计数据库与表

创建数据库

DatabaseHelper类

public class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); }

MainActivity类

Android提供了一个名为SQLiteDatabase的类,该类封装了一些操作数据库的API,使用该类可以完成对数据进行添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)操作(这些操作简称为CRUD)。对SQLiteDatabase的学习,我们应该重点掌握execSQL()和rawQuery()方法。 execSQL()方法可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句; rawQuery()方法用于执行select语句。

DatabaseHelper databaseHelper = new DatabaseHelper(this,"test.db",null,1);        SQLiteDatabase sqLiteDatabase = databaseHelper.getReadableDatabase();

创建表

DatabaseHelper类

@Override    public void onCreate(SQLiteDatabase sqLiteDatabase) {        sqLiteDatabase.execSQL("create table user(username varchar(20) not null,password varchar(60) not null)");    }

2、对数据库进行增删改查

MainActivity类

package com.example.chenjinhua.sqlite;import android.content.ContentValues;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private SQLiteDatabase sqLiteDatabase; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button add_button = (Button) findViewById(R.id.add_button); Button query_button = (Button) findViewById(R.id.query_button); Button delete_button = (Button) findViewById(R.id.delete_button); Button update_button = (Button) findViewById(R.id.update_button); add_button.setOnClickListener(this); query_button.setOnClickListener(this); delete_button.setOnClickListener(this); update_button.setOnClickListener(this); DatabaseHelper databaseHelper = new DatabaseHelper(this,"test1.db",null,1); sqLiteDatabase = databaseHelper.getReadableDatabase(); Log.i("MainActivity","create db"); } @Override public void onClick(View view) { switch (view.getId()){ //insert: case R.id.add_button: ContentValues contentValues = new ContentValues(); contentValues.put(DatabaseHelper.USERNAME,"jinhua"); contentValues.put(DatabaseHelper.PASSWORD, "zxcv"); long rowNumber = sqLiteDatabase.insert(DatabaseHelper.USER_TABLE,null,contentValues); if ( rowNumber != -1){ Toast.makeText(MainActivity.this, "插入成功", Toast.LENGTH_SHORT).show(); } break; //query case R.id.query_button: // 游标,是要查找的数据的集合 Cursor cursor = sqLiteDatabase.query(DatabaseHelper.USER_TABLE,null,null,null,null,null,null); if (cursor.moveToFirst()){ int count = cursor.getCount();//1、count是数据库的所有数目;2、快捷键command+option+v for (int i = 0; i < count; i++) { String userName = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.USERNAME)); String password = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseHelper.PASSWORD)); Log.i("MainActivity",i + ":" + userName + "|" + password); } } break; //delete case R.id.delete_button: String whereClauseString = "userName = ?"; String[] whereArgsString = {
"jinhua"}; sqLiteDatabase.delete(DatabaseHelper.USER_TABLE,whereClauseString,whereArgsString); break; //update case R.id.update_button: ContentValues contentValues1 = new ContentValues(); contentValues1.put(DatabaseHelper.PASSWORD,"100岁"); whereClauseString = "userName = ?"; String[] whereArgsString1 = {
"jinhua"}; sqLiteDatabase.update(DatabaseHelper.USER_TABLE,contentValues1,whereClauseString,whereArgsString1); } }}

除了上述方法,还可以使用原始方法,即用SQL语句。

sqLiteDatabase.execSQL("insert into user(username,age) values('张三','5岁')");

3、优化

(1) 如何设计数据库与表

上万条数据如何建表,比如300个城市,每个城市600条信息;

为什么不用文件存储?

文件存储弊端:文件存储没有规则;
数据库优势:a、有规则,用SQL语句即可查找;b、数据库更新很方便,比如onUpgrade方法。

在手机端拆表,300个城市排序1个表,用二分法查表等。

(2)对数据库进行增删改查

a、原始SQL语句执行效率更高rawQuery execSQL;

b、只检索有用的列、有用的行,越少越好;
c、是否排序;
d、是否创建索引。//当数据很多时需要创建索引,方便查找。

执行增删改操作方法 :db.execSQL(sql); 或者db.insert()、db.delete()、db.update(),并且包括数据表的创建和删除等等也可以通过execSQL实现

(3)、事务

需要操作很多数据时,用SQL很耗费性能,用事务。

//开始事务,此时db会被锁定,其他线程需要操作数据库的话会失败        sqLiteDatabase.beginTransaction();        try {            //做操作            for (int i = 0; i <1000 ; i++) {                sqLiteDatabase.execSQL("insert into user(username,age) values('张三','5岁')");            }            //一定要设置成功,不设置的话会自动回滚提交            sqLiteDatabase.setTransactionSuccessful();        } catch (Exception e) {            e.printStackTrace();        } finally {            //关闭事务,同时才会向数据库里进行批量的提交,endTransaction即提交的意思            sqLiteDatabase.endTransaction();        }

(4)对象关系映射 ORM

将一个对象和关系型数据库的一张表对应起来,这样不需要和复杂的SQL语句打交道,只需要简单的操作对象的属性和方法就行。

练习:

a) 做一个登录界面,数据库字段包含用户名、密码以及是否登录中的状态

b) 模拟登录成功后,将登录的用户名及登录状态(登录中)写入数据库,并跳转新页面,有退出按钮
c) 当点击退出时,将当前用户登录中的状态清除
d) 下一次登录时,显示上一次登录的用户名
e) 保存所有用户登录的历史,但一个用户名只保留一条记录。

遇到报错:

sqLiteDatabase.execSQL(“create table ” + LOGIN_TABLE + “(” +

USER_NAME + ” varchar(20) not null,” + PASSWORD + ” varchar(60) not
null,” + LOGIN_STATE + ” varchar(20) not null);”);

error: no such table。

stackoverflow查了:

simply Change Your Databse name in Data base class which you implemented Using SQliteDatabase

然后我修改了数据库名字,然后问题就解决了。可是我还没明白为什么。。


ContentProvider

一、什么是ContentProvider?

  • 应用程序 间 共享数据的一种方式
  • 为存储和获取数据提供了统一的接口
  • Android为常见的一些数据提供了默认的ContentProvider
  • 四大组件之一

系统提供的封装好的ContentProvider,如:sdk- samples- notePad。

ContentProvider //提供者

1、提供query(uri)、delete(uri)、insert(uri)、update(uri)方法;
2、这些方法都要传入uri;
3、根据不同的uri做不同的db操作。

sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);        sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);        sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);        sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);switch (sUriMatcher.match(uri)) {           case NOTES:               qb.setProjectionMap(sNotesProjectionMap);               break;           case NOTE_ID:               qb.setProjectionMap(sNotesProjectionMap);               qb.appendWhere(                   NotePad.Notes._ID +    // the name of the ID column;                   "=" + uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION));               break;           case LIVE_FOLDER_NOTES:               qb.setProjectionMap(sLiveFolderProjectionMap);               break;           default:               throw new IllegalArgumentException("Unknown URI " + uri);       }

如何使用ContentProvider?

/*        1、ContentProvider就是一系列封装的接口,把数据封装起来,对外提供一系列增删改查接口给别人;uri就是获取数据的路径。        2、通过ContentProvider提供的query这个接口,把通讯录里所有联系人查询出来,操作数据;        3、ContentProvider可以用封装的,也可以自己封装ContentProvider,给自己应用用,也可以给其他应用程序用。        * */        //ContentResolver内容解析器        ContentResolver contentResolver = getContentResolver();        //通用资源标识符,表示资源(图像、视频、音频)路径,有3个字段表示:scheme(content://)、host(包名)、path;        Uri uri = Uri.parse("content://com.android.contacts/contacts");        //把这个xxx包里面xxx这个表里id为10的username字段的值        Uri uri1 = Uri.parse("content://com.example.chenjinhua.testcontentprovider/table_name/10/username");        Cursor cursor = contentResolver.query(uri,null,null,null,null);        if ( cursor != null && cursor.moveToFirst()){}

二、ContentProvider的实现过程

  1. Database
  2. Uri
  3. UriMatcher
  4. ContentProvider
  5. query/insert/update/delete
  6. AndroidManifest.xml

1、Database

DatabaseHelper类建立db以及两张表

package com.example.chenjinhua.sqlite;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import android.util.Log;/** * Created by chenjinhua on 16/4/3. */public class DatabaseHelper extends SQLiteOpenHelper {
public static final String USER_TABLE = "user"; public static final String USERNAME = "username"; public static final String PASSWORD = "password"; public static final String BOOK_TABLE = "book_table"; public static final String BOOK_NAME = "book_name"; public static final String BOOK_PRICE = "book_price"; public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { sqLiteDatabase.execSQL("create table " + USER_TABLE + "(" + USERNAME + " varchar(20) not null," + PASSWORD + " varchar(60) not null)"); sqLiteDatabase.execSQL("create table " + BOOK_TABLE + "(" + BOOK_NAME + " varchar(20) not null," + BOOK_PRICE + " varchar(60) not null)"); } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { }}

2、Uri

新建package包、包内新建TestContentProvider类和URIList类

6、AndroidManifest.xml注册

转载地址:http://feani.baihongyu.com/

你可能感兴趣的文章
【转】设计模式六大原则(5):迪米特法则
查看>>
css选择器有哪些
查看>>
git pull没有指定branch的报错
查看>>
Air打包exe
查看>>
界面编程之QT的Socket通信20180730
查看>>
ASP。net 之view
查看>>
C#轻量级配置文件组件EasyJsonConfig
查看>>
222. Count Complete Tree Nodes
查看>>
Atitit.软件硕士 博士课程 一览表 attilax 总结
查看>>
C++ 复制控制之复制构造函数
查看>>
Python pip 常用命令
查看>>
webworker
查看>>
洛谷P3980:[NOI2008]志愿者招募
查看>>
【Python图像特征的音乐序列生成】图像特征在旋律生成中有什么用
查看>>
SpringBoot 集成Mybatis时 使用通用插件Mapper 注意事项
查看>>
git开发错分支
查看>>
java中几个特殊的类
查看>>
zt 设计模式六大原则(3):依赖倒置原则
查看>>
面向对象
查看>>
C# 枚举器和迭代器
查看>>