前言
本文用于介绍SQLite,SQLite是Android内置的数据库,是一款轻量级的关系型数据库。它具有运算速度快、占用资源少等优点。支持SQL语法同时遵循数据库的ACID事务。
创建数据库
Android为我们提供了一个SQLiteOpenHelper帮助类,我们可以在这里面实现创建数据库、升级数据库的逻辑。在SQLiteOpenHelper里面,有两个非常重要的方法:getReadabledatabase()和getWriteableDatabase(),这两个方法都可以打开一个现有的数据库(存在该数据库则打开,不存在则创建),并返回一个可以对数据库进行读写操作的对象(SQLiteDatabase)。不同点是当数据库不可写入时(如磁盘空间满了),getReadabledatabase()将以只读的方式打开数据库,而getWriteableDatabase()方法将出现异常。
下面我们来构建一个SQLiteOpenHelper实例,取名为MyDatabaseHelper,这里我们希望创建一个名为BookStore.db的数据库,数据库中有一张叫Book的表。
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,"+"image blob,"+"name text)";private Context mContext;public StatusDatabase(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);mContext=context;}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_BOOK);//创建成功时弹出Create succeedToast.makeText(mContext,"Create succeed",Toast.LENGTH_SHORT).show();}//用于对数据库进行升级时@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}
这里简单介绍一下CREATE_BOOK的建表语句:首先字段在前,数据类型在后,我们还可以给字段设置一些特殊的属性,例如id字段primary key表示设置id为主键,autoincrement表示id是自增长的,其他的感兴趣可以自己去查找。另外讲一下数据类型,integer表示整型,text表示文本型,real表示浮点数,blob表示二进制类型,常用它来存储图片数据(最后会具体讲解)。
接下来我们只需创建出MyDatabaseHelper实例并调用它的getWriteableDatabase()方法来创建数据库即可:
MyDatabaseHelper dbHelper=new MyDatabaseHelper(this,"BookStore.db",null,1);
BookStore.db表示创建出的数据库的名字叫做BookStore.db,1表示数据库版本是1,后续我们升级了数据库版本也会随之改变。
升级数据库
我们在编写MyDatabaseHelper时还有一个方法onUpgrade()没编写,它就是用来进行数据库升级的,例如此刻我们想加入一张新的表Category用来表示书的分类,在编写好Category的建表语句后,只需在onCreate()方法里像创建Book表一样创建Category表(db.execSQL(CREATE_CATEGORY)),接着我们要在onUpgrade()方法中删除原来创建好的表再重新创建表,要不然程序会报错,如下:
@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("drop table if exists Book");db.execSQL("drop table if exists Category");onCreate(db);}
接着我们要再想创建出MyDatabaseHelper的实例并调用它的getWriteableDatabase()方法来创建数据库,版本号就要传入2了:
MyDatabaseHelper dbHelper=new MyDatabaseHelper(this,"BookStore.db",null,2);
添加数据
上面说到过,要想对数据库进行操作,我们要调用getReadabledatabase()或getWriteableDatabase()方法打开数据库,并且该方法会返回一个数据库操作对象,如下:
SQLiteDatabase db=dbHelper.getWriteableDatabase();
ContentValues cv=new ContentValues();//用于对要添加的数据进行组装
cv.put("name","zhangsan");
cv.put("price",12.12);
...
db.insert("Book",null,cv);//调用insert方法将数据插入到Book表中
这样数据就存到了我们的Book表中,上面要想继续向Category表中存数据,只需先调用cv.clear()方法将cv中的数据清空,然后重复cv.put()、db.insert()即可
关于图片的存储与读取放在后面具体来讲解。
更新数据
更新数据时我们还是先获取一个ContentValues对象来对数据进项组装,与上面不同的是这次我们是调用update()方法
SQLiteDatabse db=dbHelper.getWriteableDatabse();
ContentValues cv=new ContentValues();
values.put("price",10.00);//将price字段12.12改为10.00
db.update("Book",cv,"name=?",new String[]{"zhangsan"});//条件是name=zhangsan
//完整的是将name=zhangsan的一条数据中的price由12.12改为10.00
当然update()方法后面你也可以传两个null进去表示没有条件
删除数据
获取到数据库操作对象直接执行删除操作
SQLiteDatabse db=dbHelper.getWriteableDatabse();
db.delete("Book","pages>?",new String[]{"500"});//删除pages大于500的数据
查询数据
书上的查询讲了非常多内容,我们查询的query()方法有六个方法,对应了查询的约束条件、分组条件等等,这里不用害怕,我们只需掌握最基础的查询即可,因为以后这些查询操作都是交给后端来实现的,这里我就介绍一下最简单的查询。
调用query()方法会给我们返回一个Cursor对象,查询到的所有数据都从这个对象中取出。
SQLiteDatabse db=dbHelper.getWriteableDatabse();
Cursor cursor=db.query("Book",null,null,null,null,null,null);
if(cursor.moveToFirst()){//遍历Cursor对象,取出查询到的所有数据do{String bookName=cursor.getString(cursor.getColumnIndex("name"));//查询字段名为name的字段将值赋给bookNameint bookPages=cursor.getInt(cursor.getColumnIndex("pages"));//查询字段名为pages的字段将值赋给bookPagesdouble bookPrice=cursor.getDouble(cursor.getColumnIndex("price"));//查询字段名为price的字段将值赋给bookPrice}while(cursor.moveToNext());
}
cursor.close();
使用SQL操作数据库
Android为我们提供了直接使用SQL来操作数据库。
- 添加数据
db.execSQL("insert into Book(name,author,pages,price) values(?,?,?,?)",new String[]{"..","..","..",".."});
- 更新数据
db.execSQL("update Book set price=? where name=?",new String[]{"..",".."});
- 删除数据
db.execSQL("dlete from Book where Pages>?",new String[]{"500"});
- 查询数据
db.rawQuery("select * from Book",null);
图片的存与取
- 存
要保存的图片类型一定要是Bitmap类型的
//字节输出流,保存图片
ByteArrayOutputStream os = new ByteArrayOutputStream();
//bitmap为要保存到数据库的对象
bitmap.compress(Bitmap.CompressFormat.PNG, 1, os);SQLiteDatabase db=dbHelper.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put("image",os.toByteArray());
db.insert("Book",null,cv);
- 取
SQLiteDatabase db=dbHelper.getWritableDatabase();
Cursor cursor=db.query("Book",null,null,null,null,null,null,null);
f (cursor.moveToFirst()){do {byte[] data = cursor.getBlob(cursor.getColumnIndex("image"));bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);//将图片设置进iv图片iv.setImageBitmap(bitmap);}while(cursor.moveToNext());
}
cursor.close();