4、Android-数据存储方案(SQLite数据库存储)
4.4、SQLite数据库存储
这是Android内置的数据库
是一款轻量级的关系型数据库
运算速度非常快、占用资源少、通常只需要几百kb的内存就够了
因而特别适合在移动端设备上使用
SQLite不仅支持标准的SQL语法
还遵循了ACID事务
有关系型数据库的使用可以很快的使用SQLite
SQLite比一般的数据库要简单的多
甚至不需要设置用户名和密码就可以使用
Android把这个功能强大的数据库镶嵌到系统当中
是得本地的持久化有了质的飞跃
在存储大量复杂的关系型数据时使用
4.4.1、创建数据库
Android专门提供了一个SQLiteOpenHelper帮助类
借助这个类可以非常简单的对数据库进行创建和升级
前要:
SQLiteOpenHelper是一个抽象类
在使用时需要需要继承它
SQLiteOpenHelper有两个抽象方法:
1、onCreate()
2、onUpgrade()
必须在继承类中重写这两个方法,然后分别在这两个方法中去实现创建、升级数据库的逻辑
SQLiteOpenHelper中还有两个重要的实例方法:
1、getReadableDatebase()
2、getWriteDatabase()
这两个方法都可以创建或打开一个现有的数据库(数据库已存在则直接打开,否则创建一个新的数据库)
并返回一个可对数据库进行读写操作的对象
当数据库不可写入的时候(如磁盘已满),getReadableDatebase()方法返回的对象将以只读的方式打开数据库
getWriteDatabase()方法则将抛异常
SQLiteOpenHellper中有两个构造方法可供重写
一般使用参数少一点的那个构造方法即可
这个构造方法中接受4个参数:
1、Context,中有它才能对数据库进行操作
2、数据库名:创建数据库时使用的就是这里指定的数据库名称
3、允许我们在查询数据时返回一个自定义的的Cursor,一般传入null
4、表示当前数据库的版本号,可用于对数据库的升级操作
构建书SQLiteHelper的实例之后
在调用getReadableDatabase()或getWriterableDatabase()方法就能够创建数据库
数据库的文件会存在/data/data/<package name>/databases/目录下
此时重写onCreate()方法会得到执行,这里通常回去处理一些创建表的逻辑
创建数据表的方法:
public static final String CREATE_BOOK= "create table Book (" +"id integer primary key autoincrement," +"author text," +"price real," +"name text);";
SQLite的数据类型很简单
interger整形
real浮点型
text文本类型
blob二进制类型
primary key设置为主键
autoincrement表示id自增
新建类:
MyDatabaseHelper 继承SQLiteOpenHelper
public class MyDatabaseHelper extends SQLiteOpenHelper { //SQL public static final String CREATE_BOOK= "create table Book (" +"id integer primary key autoincrement," +"author text," +"price real," +"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) { db.execSQL(CREATE_BOOK); Toast.makeText(mcontext,"Create succeeded",Toast.LENGTH_LONG).show(); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
first_layout.xml文件中进行设置新的按钮用于相应事件进行创建数据库
<Button android:id="@+id/create" android:text="创建数据库" android:layout_width="match_parent" android:layout_height="wrap_content" />
在MainActivity中进行绑定事件:
private MyDatabaseHelper myDatabaseHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first_layout); myDatabaseHelper=new MyDatabaseHelper(this,"bookstore.db",null,1); Button button_create = (Button) findViewById(R.id.create); button_create.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { myDatabaseHelper.getWritableDatabase(); } }); }
在onCreate()方法中构建了一个MyDatebaseHelper对象
并且通过构造函数的的参数将数据库名指定以及版本号
在点击事件中掉哟给了getWriterableDatabase()方法
当第一次点击时就会检测到但钱应用程序中并没有这个数据库
于是会调用MyDatebaseHelper对象中的onCreate方法进行创建
然后会有提示信息告我们创建成功
再次点击时,此时数据库已存在,所以不hi进行二次创建
但是其中的表是无法使用此方法进行查看的
使用adb shell进行对数据库和表的创建情况进行检测
每个数据库都会有一个xxx.db-journal是为了让数据库能够支持事务产生的临时日志文件
通常这个文件的大小都是0字节
4.4.2、升级数据库
在MyDatabaseHelper类中还有一个onUpgrade()方法是用于对数据库进行升级
在整个数据库管理工作初中有很重要的作用
public class MyDatabaseHelper extends SQLiteOpenHelper { //SQL public static final String CREATE_BOOK= "create table Book (" +"id integer primary key autoincrement," +"author text," +"price real," +"name text);"; public static final String CREATE_CATEGROY= "create table categroy (" +"id integer primary key autoincrement," +"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) { db.execSQL(CREATE_BOOK); db.execSQL(CREATE_CATEGROY); Toast.makeText(mcontext,"Create succeeded",Toast.LENGTH_LONG).show(); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
此时在onCreate()方法中添加新的创建库的方法
此时在此运行程序,并不会创建新的数据 库,此时的库依然是之前的创建的库
此时的store.db数据库已经存在了
之后不管怎么点击该onCreate()方法都不会执行
消炎药添加的表也不会进行创建
方法:
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table if exists Book"); db.execSQL("drop table if exists categroy"); onCreate(db); }
在onUPgrade()方法中执行两个drop语句
若数据库中中已经存在则进行杉树
再次调用onCreate()方法进行重建
该方法执行的条件是其此类的构造方法的第四个参数
此时要传入一个比之前大的数就可以使其执行
myDatabaseHelper=new MyDatabaseHelper(this,"store.db",null,2);
此时是可以执行成功的!!!
4.4.3、添加数据
CRUD:
Create:添加
Retrieve:查询
Update:更新
Delete:删除
每一种操作对应各自一种SQL命令
调用SQLiteOpenHelper的getReabableDatabase()或者getWriterableDatabase()方法
是可以用于创建或者升级数据库
这两个方法都会返回一个SQLiteDatebase对象借助这个对象进行CRUD操作
SQLiteDatabase中提供了一个insert()方法,用于添加数据
3个参数:
1、表名,向那个表中添加数据
2、用于在未指定添加情况下给某些可为空的咧自动赋值NULL
3、ConteentValues对象,提供了一系列的put()方法重载,用于向ContentValues中添加数据
之后需要将表中的每个列明以及相应的待添加数据传入即可
定义按钮:
<Button android:id="@+id/add" android:text="添加数据" android:layout_width="match_parent" android:layout_height="wrap_content" />
在MianActivity中:
private MyDatabaseHelper myDatabaseHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first_layout); myDatabaseHelper=new MyDatabaseHelper(this,"store.db",null,2); Button button_create = (Button) findViewById(R.id.create); button_create.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { myDatabaseHelper.getWritableDatabase(); } }); //插入数据 Button add = (Button) findViewById(R.id.add); add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase sqLiteDatabase = myDatabaseHelper.getWritableDatabase(); ContentValues contentValues = new ContentValues(); contentValues.put("id",1); contentValues.put("author","MrChegns"); contentValues.put("price",143.2); contentValues.put("name","Android"); sqLiteDatabase.insert("Book",null,contentValues); } });
首先过去SQLiteDatabase对象
然后使用ContentValues来对要添加的数据进行封装
使用insert()方法将数据添加到表中
此时点击按钮之后
使用adb shell进行查看:
数据已经添加到Book表中
4.4.4、更新数据
SQLiteDatabase中提供了一个非常好用的update()方法用于数据的更新
接受4个参数:
1、表名即将操作的数据表
2、ContentValues对象,把要更新的数据封装进入
第三第四参数主要用于约束更新某一行或者某几行的数据,不指定就是更新所有行
<Button android:id="@+id/updata" android:text="更新数据" android:layout_width="match_parent" android:layout_height="wrap_content" />
MainActivity中:
Button update = (Button) findViewById(R.id.updata); update.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase sqLiteDatabase = myDatabaseHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("author","MrChegn"); values.put("price",14.2); sqLiteDatabase.update("Book",values,"name=?",new String[]{"Android"}); } });
第三个参数相当于MySQl中的where部分 ? 是一个占位符
通过第四位参数提供一个字符串数组作为第三个参数中的每个占位符的相应的内容
点击按钮之后:
可以查询到数据已经进行更改
4.4.5、删除数据
SQLiteDatabase中提供了delete方法
专门用于删除数据
接受3个参数:
1、表名第二第三参数用于约束删除某一行或者某几行的数据,不指定就是删除所有行
定义按钮:
<Button android:id="@+id/delete" android:text="删除数据" android:layout_width="match_parent" android:layout_height="wrap_content" />
MainActivity中
//删除数据 Button delete = (Button) findViewById(R.id.delete); delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase sqlite = myDatabaseHelper.getWritableDatabase(); sqlite.delete("Book","id=?",new String[]{"1"}); } });
点击按钮的事件之后:
4.4.6、查询数据
SQLiteDatabase中提供了query()方法用于对数据库进行查询
参数终端,最短的也需要查询7个参数
1、表名
2、指定查询哪几列
3、4、约束查询某一行或者某几行,不指定默认查询所有
5、用于指定需要去group by的列,不指定则不对group by的列进行查询
6、用于对group by之后的数据进行过滤
7、用于指定查询结果的排序方式,不指定使用默认的配许方式
查询按钮:
<Button android:id="@+id/query" android:text="查询数据" android:layout_width="match_parent" android:layout_height="wrap_content" />
MainActivity
//查询数据 Button query = (Button) findViewById(R.id.query); query.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase sql = myDatabaseHelper.getWritableDatabase(); Cursor book = sql.query("Book", null, null, null, null, null, null); if (book.moveToFirst()){ do { String name= book.getString(book.getColumnIndex("name")); String price= book.getString(book.getColumnIndex("price")); Log.d("name", name); Log.d("price", price); }while (book.moveToNext()); }
book.close(); } });
点击事件出发后:
查询之后会返回一个Cursor对象
可以使用moveToFirst()方法将指针移动到第一个位置
使用getColumnIndex()方法可以获取到某一列在表中的索引位置
然后找到这个索引传入到相应的取值方法中
就可以从数据库中读取数据
book.close();最后关闭Cursor
4.4.7、使用SQL操作数据库
对于SQL的使用非常好的可以使用SQL来操作数据库
实例: