我博客的相关说明
《第一行代码》第六章学习笔记
文件储存
SharedPreference储存
SQLite是Android内置的一款轻量级数据库。它支持SQL语法,还遵循ACID事物,容易上手。
Android为开发者提供了SQLiteOpenHelper帮助类,它是一个抽象类在使用时需要建立一个帮助类来继承它。
onCreate()
和onUpgrade()
,在使用时,我们需要在自己的帮助类里边重写这两个方法,然后分别在这两个方法中实现创建、升级数据库的操作。getReadableDatabase()
和getWritableDatabase()
。这两个方法都可以创建或者打开一个数据库如果数据库存在则直接打开,否则就新建一个数据库,并且返回一个可对数据库进行读写操作的对象。二者的区别是:当数据库不可以写入的时候getReadableDatabase()
方法返回的对象会以只读的方式打开数据库,而getWritableDatabase()
方法则会出现异常。1.Context,有了它才能对数据库进行操作。
2.数据库名。
3.Cursor,这是我们可以自定义的一个在查询数据库时 的返回值一般都是传入null
4.当前数据库版本号,它可以用来对数据库进行升级操作。
一般,构建出SQLiteOpenHelper的实例以后,再调用它的getReadableDatabase()和getWritableDatabase()方法就能够创建数据库了。数据库文件一般存放在/data/data/
目录下。
示例:
我们创造一个名为BookStor.db的数据库。然后在数据库中添加一张Book表,里边有id、作者等信息。
这里建好Activity之后,我直接新建了一个Java文件,继承SQLiteOpenHelper类
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, "
+"name text)";
private Context mContext;
public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable 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,"创建成功!",Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
可以看到,建表语句被定义成了一个字符串常量,然后在onCreate()方法中又调用了SQLiteDatabase的execSQL()方法,去执行这条语句。
这样就可以保证,数据库完成创建的同时也成功创建了表。
这里放一个Button来创建数据库。
<Button
android:id="@+id/btn_create"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create Database"
android:textAllCaps="false"
android:textSize="25sp"/>
public class SQLite_test extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sqlite_test);
//构建MyDatabaseHelper对象,将文件名指定为BookStore.db
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1);
Button create = findViewById(R.id.btn_create);
create.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dbHelper.getWritableDatabase();
}
});
}
}
ok,运行程序,发现第一次点击按钮会弹出Toast但第二次就不会了因为数据库存在后不会再重复创建
这里我们用adb shell来对数据库和表的创建进行检查。
adb是Android SDK自带的调试工具,用它可以直接对连接在电脑上的手机进行操作。它存放在sdk的platfrom-tools目录下。**查看sdk路径,可依次点击AS的File→Settings…→Appearance & Behavior→System Settings→Adroid SDK。
找到路径之后复制,然后再到环境变量里配置Path就OK。
打开控制台输入adb shell,通过cd指令进入相应目录:~这里实在不好找的话建议配合Android Device Monitor来查找相应路径~(AS3.0之后的版本参考这篇文章进入Android Device Monitor)
在这里插入图片描述
使用ls(LS)命令后可以看到目录里的文件。
之后,键入sqlite3+数据库名
即可打开数据库。键入.table
即可查看数据库中有哪些表。而键入.schema
语句可以查看它们的建表语句。
MyDatabaseHelper中的onUpgrade()方法是用来升级数据库的。
如果我们还想建立一张Category表用于记录图书的分类,那么:
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = ···
public static final String CREAT_CATEGORY = "creat table Category("
+ "id integer primary key autoincrement, "
+ "category_name text, "
+ "category_code integer)";
private Context mContext;
public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREAT_CATEGORY);
Toast.makeText(mContext,"创建成功!",Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//这里的两条drop语句,如果发现Book或者Category表则将表删除,再用onCreat()方法创建
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
}
}
修改传入参数的第四个数值:
//只要比之前的数值大,onUpgrade()方法就能被执行
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);
重新运行程序,点击按钮,然后使用adb shell工具查看创建的表:
可以看到,BookSrtore.db数据库里边已经有Book和Category两张表了。
CRUD:对数据库的四种操作。增、删、查、改
C—Create添加,R—Retrieve查询,U—Update更新,D—Delete删除。
调用SQLiteOpenHelpe
r的getReadableDatabase()
或getWriteableDatabase()
方法是可以用于,创建、升级数据库的。同时,这两个方法都会返回一个SQLiteDatabase
对象,借助这个对象,开发者便可以对数据库进行CRUD操作了。
SQLiteDatabase中提供了一个inset()
方法用于添加数据。
它接收三个参数:
··········1.表名。即希望往哪一张表里边添加数据。
··········2.若未指定添加数据时,向某一些空的列自动赋值。一般为null
··········3.ContentValues对象。它提供一个put()
方法重载,用于向ContentValues中添加数据。
示例:
这里再添加一个Button按钮用于添加数据。
<Button
android:id="@+id/btn_adddata"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add Data"
android:textAllCaps="false"
android:textSize="25sp"/>
public class SQLite_test extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sqlite_test);
//构建MyDatabaseHelper对象,将文件名指定为BookStore.db
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);
Button create = findViewById(R.id.btn_create);
create.setOnClickListener(new View.OnClickListener() {···});
Button add = findViewById(R.id.btn_adddata);
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
//开始组装第一条数据
values.put("name","The Da Vinci Code");
values.put("author","Dan Brown");
values.put("pages",355);
values.put("price",32.5);
db.insert("Book",null,values);//插入第一条数据
//组装第二条数据
values.put("name","The Lost Symbol");
values.put("author","Dan Brown");
values.put("pages",423);
values.put("price",45.5);
db.insert("Book",null,values);//插入第二条数据
}
});
}
}
可以看到,这里添加了两条数据到Book表里边。点击运行,点击相应按钮。
使用adb shell查看表中数据:select *from Book;
(这里我点击了两下,就多添加了两条数据)
SQLiteDatabase中提供了一个update()
方法用于数据更新。
这个方法接收四个参数:
··········1.表名。用于指定更新哪一张表里的数据。
··········2.ContentValues对象,将更新的数据组装进去。
··········3、4.用于约束更新特定行或几行的数据,默认全部更新。
示例:
添加一个Update按钮用于数据更新
<Button
android:id="@+id/btn_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Update Data"
android:textAllCaps="false"
android:textSize="25sp"/>
public class SQLite_test extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sqlite_test);
//构建MyDatabaseHelper对象,将文件名指定为BookStore.db
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,4);
Button create = findViewById(R.id.btn_create);
create.setOnClickListener(new View.OnClickListener() {···});
Button add = findViewById(R.id.btn_adddata);
add.setOnClickListener(new View.OnClickListener() {···});
Button btn_update = findViewById(R.id.btn_update);
btn_update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price",20.8);
db.update("Book",values,"name = ?",new String[]{"The Da Vinci Code"});
}
});
}
}
这里我们指定了将价格这一列的数据,更新为20.8,然后调用了update()方法来执行具体的操作。
"name = ?"
对应的是SQL语句中的where部分,表示更新所有name等于?的行这里的?代表占位符db.update("Book",values,"name = ?",new String[]{"The Da Vinci code"});
的意思是,将名字为The Da Vinci Code这本书的价格改为20.8.与添加数据和更新数据相似,SQLiteDatabase中也提供了相应的delete()
方法。
这个方法接收三个参数:
··········1.表名
··········2、3.用于约束删除某几行
示例:
添加一个Button按钮用来删除数据
<Button
android:id="@+id/btn_delate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Delate Data"
android:textAllCaps="false"
android:textSize="25sp"/>
public class SQLite_test extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sqlite_test);
//构建MyDatabaseHelper对象,将文件名指定为BookStore.db
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,5);
···
Button btn_delete = findViewById(R.id.btn_delate);
btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("Book","pages > ? ",new String[]{"400"});
}
});
}
}
这里我们想要把页数大于400的书籍删除,运行程序,点击删除按钮。
可以看到,删除成功!
SQLiteDatabase同样提供了查询方法query()
这个方法接收七个参数:
query() 方法参数 |
对应SQL 部分 |
描 述 |
---|---|---|
table | from table_name | 指定查询的表名 |
columns | select column1,column2 | 指定查询的列名 |
selection | where column = value | 指定的where约束条件 |
selectionArgs | - | 为where中的占位符提供具体的值 |
groupBy | group by column | 指定需要group by的列 |
having | having cloumn = value | 对group by的结果进一步约束 |
orderBy | order by column1,column2 | 指定查询结果的排序方式 |
调用query()方法后会返回一个Cursor对象,查询到的数据都将从这个对象当中取出。
示例:
<Button
android:id="@+id/btn_query"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Query Data"
android:textAllCaps="false"
android:textSize="25sp"/>
public class SQLite_test extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sqlite_test);
···
Button btn_query = findViewById(R.id.btn_query);
btn_query.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
//查询表中所有数据
Cursor cursor = db.query("Book",null,null,null,null,null,null,null);
if (cursor.moveToFirst()){
do {
//遍历Cursor对象,取出并打印数据
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"));
Toast.makeText(SQLite_test.this,"name"+name+"\nauthor"+author+"\npages"+pages+"\nprice"+price,Toast.LENGTH_SHORT).show();
}while (cursor.moveToNext());
}
cursor.close();
}
});
}
}
这里只传入query()的第一个表明参数,其余全是null。表示查询这张表中的所有数据。查询完之后得到一个Cursor对象,接着调用它的moveToFrist()方法来将指针移动到列表第一行。之后遍历列表中的所有数据。我们用Toast方法将查询结果打印出来。
ok,到这里第六章的数据库存储就告一段落。
下一节:《第一行代码》使用SQL操作数据库。