创建数据库
SQLiteOpenHelper是一个抽象类。
- 包含抽象方法:onCreat()、onUpgrade()。
- 包含实例方法:getReadableDatabase()、getWritableDatabase()。
两个实例方法都可创建或打开一个现有的数据库,并返回一个可对数据库进行读写操作的对象。但当数据可以不可写入的时候,getReadableDatabase()方法返回的对象将以只读的方式打开,而getWritableDatabase()方法则出现异常。 - 包含两个构造方法:一般使用参数少(4个)的构造方法。
参数包括:Context;数据库名(创建数据库是使用的就是这路指定的名称);允许我们在 查询数据的时候返回一个自定义的Cursor(一般传入null);当前数据库的版本号,用于对数据库进行升级操作。
构建出SQLiteOpenHelper实例后,再调用getReadableDatabase()或getWritableDatabase()就能创建数据库。
建表语句
- integer表示整型
- real表示浮点型
- text表示文本类型
- blob表示二进制类型
- primary key将id设为主键
- autoincreament关键字表示id列时自增长的
示例
- 新建项目MyDatabaseTest。
- 新建类MyDatabaseHelper继承自SQLiteDatabaseHelper。
package com.example.databasetest;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
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(Context context, String name,
SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
//exwcSQL()方法执行建表语句
db.execSQL(CREATE_BOOK);
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
- 编辑activity_main.xml,添加按钮用于创建数据库
<Button
android:id="@+id/creat_database"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Creat database"/>
- 编辑MainActivity。
package com.example.databasetest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper deHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
deHelper = new MyDatabaseHelper(this,"Book_Store.db",null,1);//库名指定为BookStore.db,版本号指定为1
Button button = (Button) findViewById(R.id.creat_database);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
deHelper.getWritableDatabase();
}
});
}
}
升级数据库
再添加一张Category表用于记录图书的分类
- 修改MyDatabaseHelper。
在onUpgrade()方法中执行两条DROP语句,如果发现数据库中已存在Book或Category表,就将这两个表删除,再调用onCreat()方法重建。
//在MyDatabaseHelper中添加建表语句
public static final String CREATE_CATEGORY = "create table Category ("
+ "id integer primary key autoincrement, "
+ "category_name text, "
+ "category_code integer)";
//创建Category数据库
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}
//对数据库进行升级
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
}
- 修改MainActivity,让onUpgrade()方法得到执行
在构造器的版本好重传入一个比之前版本号大的新版本号,即比1大的数,就可以让onUpgrade()方法得到执行。
//deHelper = new MyDatabaseHelper(this,"Book_Store.db",null,1);
deHelper = new MyDatabaseHelper(this,"Book_Store.db",null,2);//升级
添加数据
insert()方法:
- 第一个参数是表名,向该表中添加数据。
- 第二个参数用于在未指添加数据的情况下给某些可为空的列自动赋值NULL,一般直接传null。
- 第三个参数是一个ContentValues对象,它提供一系列的put()方法重载,用于向ContentValues中添加数据,只需将表中的每个列名以及相应的待添加数据传入即可。
示例
- 修改activity_main.xml,新增添加数据的按钮。
在对数据进行组装时,id那一列并没有给它赋值,这是因为在前面创建表的时候,我们就将id列设置为自增长了,它的值会在入库的时候自动生成,所以不需要手动给它赋值。
<Button
android:id="@+id/add_database"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add database"/>
- 修改MainActivity,编写添加数据的逻辑。
Button addData = (Button)findViewById(R.id.add_database);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase database = deHelper.getWritableDatabase();
ContentValues values = new ContentValues();
//组装第一条数据
values.put("name","The Da Vinve Code");
values.put("author","fei du");
values.put("pages",459);
values.put("price",16.95);
//添加数据
database.insert("Book",null,values);
values.clear();
//组装第二条数据
values.put("name","The lost laymbol");
values.put("author","luo wen zhou");
values.put("pages",537);
values.put("price",53.4);
//添加数据
database.insert("Book",null,values);
}
});
- 输入查询语句aelect * from Book。
更新数据
updata()方法:
- 第一个参数:表名,指定更新哪张表中的数据。
- 第二个参数:ContentValues对象,要把更新数据在这里组装进去。
- 第三、四个参数用于约束更新某一行或某几行中的数据,不指定的话就默认更新所有行。
这里使用第三、第四个参数来指定具体更新哪几行,第三个参数对应的是SQL语句的where部分,表示更新所有name等于?的行,而?是一个占位符,可以通过第四个参数提供的一个字符串数组为第三个参数中的每个占位符指定相应的内容。
示例
- 修改activity_main.xml,新增更新数据的按钮
<Button
android:id="@+id/updata_database"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Updata database"/>
- 修改MainActivity,编写更新数据的逻辑
这里使用
//更新数据
Button updataData = (Button) findViewById(R.id.updata_database);
updataData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase db = deHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price",10.56);
//将The Da Vinve Code书的价格改为10.56
db.update("Book",values,"name = ?",new String[] {"The Da Vinve Code"});
}
});
- 输入查询语句查看表中的数据情况。
删除数据
delete()方法:
- 第一个参数:表名。
- 第二、三个参数:用于约束删除某一行或某几行的数据,不指定则默认删除所有行。
示例
- 修改activity_main.xml,新增删除按钮。
<Button
android:id="@+id/delet_database"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delet_database"/>
- 修改MainActivity,编写删除逻辑。
通过第二、第三个参数来指定仅删除那些页数超过500页的书。
//删除数据
final Button deletData = (Button)findViewById(R.id.delet_database);
deletData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase database = deHelper.getWritableDatabase();
database.delete("Book","pages > ?", new String[] {"500"});
}
});
查询数据
query()方法中的参数:
- table:指定查询的表名。
- colums:指定查询的列名。
- selection:指定where的约束条件。
- selectionArgs:为where中的占位符提供具体的值。
- groupBy:指定需要group by的列。
- having:对group by后的结构进一步约束。
- orderBy:指定查询结果的排序方式。
不必为每条查询语句都指定所有的参数
示例
- 添加查询按钮。
<Button
android:id="@+id/query_database"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Query database"/>
- 编写查询逻辑
在query()方法的参数中只适用第一个参数指明查询Book表,后面的参数全为null,表示希望查询该表中的所有数据。
Cursor对象的moveToFirst()方法将数据的指针移动到第一行的位置。
//查询数据
Button queryData = (Button)findViewById(R.id.query_database);
queryData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SQLiteDatabase db = deHelper.getReadableDatabase();
//差询Book表中所有数据
Cursor cursor = db.query("Book",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"));
Log.d("MainActivity","book name is " + name);
Log.d("MainActivity","book author is "+ author);
Log.d("MainActivity","book pages is " + pages);
Log.d("MainActivity","book price is " + price);
}while(cursor.moveToNext());
}
cursor.close();
}
});
}