一、前言:
SQLite 是一款輕量級的關(guān)系型數(shù)據(jù)庫入篮,它的運算速度非吵率荩快,占用資源很少潮售,通常只需要幾百 KB 的內(nèi)存就夠了痊项,SQLite 不僅支持標(biāo)準(zhǔn)的 SQL 語法,還遵循了數(shù)據(jù)庫的 ACID事務(wù)饲做。
1. 什么是 SQLite线婚?
SQLite是一個進(jìn)程內(nèi)的庫,實現(xiàn)了自給自足的盆均、無服務(wù)器的塞弊、零配置的、事務(wù)性的 SQL 數(shù)據(jù)庫引擎泪姨。它是一個零配置的數(shù)據(jù)庫游沿,這意味著與其他數(shù)據(jù)庫一樣,您不需要在系統(tǒng)中配置肮砾。
就像其他數(shù)據(jù)庫诀黍,SQLite 引擎不是一個獨立的進(jìn)程,可以按應(yīng)用程序需求進(jìn)行靜態(tài)或動態(tài)連接仗处。SQLite 直接訪問其存儲文件眯勾。
一個事務(wù)本質(zhì)上有四個特點ACID:
- Atomicity原子性
- Consistency一致性
- Isolation隔離性
- Durability耐久性
2. 為什么要用 SQLite枣宫?
- 不需要一個單獨的服務(wù)器進(jìn)程或操作的系統(tǒng)(無服務(wù)器的)。
- SQLite 不需要配置吃环,這意味著不需要安裝或管理也颤。
- 一個完整的 SQLite 數(shù)據(jù)庫是存儲在一個單一的跨平臺的磁盤文件。
- SQLite 是非常小的郁轻,是輕量級的翅娶,完全配置時小于 400KiB,省略可選功能配置時小于250KiB好唯。
- SQLite 是自給自足的竭沫,這意味著不需要任何外部的依賴。
- SQLite 事務(wù)是完全兼容 ACID 的骑篙,允許從多個進(jìn)程或線程安全訪問蜕提。
- SQLite 支持 SQL92(SQL2)標(biāo)準(zhǔn)的大多數(shù)查詢語言的功能。
- SQLite 使用 ANSI-C 編寫的替蛉,并提供了簡單和易于使用的 API贯溅。
- SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中運行拄氯。
二躲查、基本語法:
1. SQLite 命令
與關(guān)系數(shù)據(jù)庫進(jìn)行交互的標(biāo)準(zhǔn) SQLite 命令類似于 SQL。命令包括 CREATE译柏、SELECT镣煮、INSERT、UPDATE鄙麦、DELETE 和 DROP典唇。這些命令基于它們的操作性質(zhì)可分為以下幾種:
DDL - 數(shù)據(jù)定義語言
命令 | 描述 |
---|---|
CREATE | 創(chuàng)建一個新的表,一個表的視圖胯府,或者數(shù)據(jù)庫中的其他對象介衔。 |
ALTER | 修改數(shù)據(jù)庫中的某個已有的數(shù)據(jù)庫對象,比如一個表骂因。 |
DROP | 刪除整個表炎咖,或者表的視圖,或者數(shù)據(jù)庫中的其他對象寒波。 |
DML - 數(shù)據(jù)操作語言
命令 | 描述 |
---|---|
INSERT | 創(chuàng)建一條記錄乘盼。 |
UPDATE | 修改記錄。 |
DELETE | 刪除記錄俄烁。 |
DQL - 數(shù)據(jù)查詢語言
命令 | 描述 |
---|---|
SELECT | 從一個或多個表中檢索某些記錄绸栅。 |
2. SQLite 語法
- SQLite 是不區(qū)分大小寫的具垫,但也有一些命令是大小寫敏感的弯洗,比如 GLOB 和 glob 在 SQLite 的語句中有不同的含義咖气。
- 所有的 SQLite 語句可以以任何關(guān)鍵字開始,如 SELECT绿映、INSERT、UPDATE汪拥、DELETE雪标、ALTER、DROP 等议忽,所有的語句以分號(;)結(jié)束懒闷。
3. SQLite 數(shù)據(jù)類型
SQLite 數(shù)據(jù)類型是一個用來指定任何對象的數(shù)據(jù)類型的屬性。SQLite 中的每一列栈幸,每個變量和表達(dá)式都有相關(guān)的數(shù)據(jù)類型愤估。
您可以在創(chuàng)建表的同時使用這些數(shù)據(jù)類型。SQLite 使用一個更普遍的動態(tài)類型系統(tǒng)速址。在 SQLite 中玩焰,值的數(shù)據(jù)類型與值本身是相關(guān)的,而不是與它的容器相關(guān)芍锚。
SQLite 存儲類
每個存儲在 SQLite 數(shù)據(jù)庫中的值都具有以下存儲類之一:
存儲類 | 描述 |
---|---|
NULL | 值是一個 NULL 值昔园。 |
INTEGER | 值是一個帶符號的整數(shù),根據(jù)值的大小存儲在 1并炮、2默刚、3、4逃魄、6 或 8 字節(jié)中荤西。 |
REAL | 值是一個浮點值,存儲為 8 字節(jié)的 IEEE 浮點數(shù)字伍俘。 |
TEXT | 值是一個文本字符串邪锌,使用數(shù)據(jù)庫編碼(UTF-8、UTF-16BE 或 UTF-16LE)存儲癌瘾。 |
BLOB | 值是一個 blob 數(shù)據(jù)觅丰,完全根據(jù)它的輸入存儲。 |
注意:
- SQLite 沒有單獨的 Boolean 存儲類妨退。相反妇萄,布爾值被存儲為整數(shù) 0(false)和 1(true)。
- SQLite 沒有一個單獨的用于存儲日期和/或時間的存儲類碧注,但 SQLite 能夠把日期和時間存儲為 TEXT嚣伐、REAL 或 INTEGER 值。
三萍丐、基本用法:
1. MyDatabaseHelper類
Android 提供的 SQLiteOpenHelper.java 是一個抽象類轩端。那么我們要使用它,必須自己寫一個類來繼承它逝变,實現(xiàn)它的抽象方法基茵。
public class MyDatabaseHelper extends SQLiteOpenHelper {
private Context mContext;
//創(chuàng)建表SQL語句
public static final String CREATE_BOOK = "create table Book("
+"_id integer primary key autoincrement,"
+"author text,"
+"price real,"
+"pages integer,"
+"name text )";
// String stu_table="create table usertable(_id integer primary key autoincrement,sname text,snumber text)";
/**
* 構(gòu)造函數(shù)
* @param context
* @param name
* @param factory
* @param version
*/
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
/**
* 創(chuàng)建數(shù)據(jù)庫
* @param db
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
Toast.makeText(mContext,"創(chuàng)建成功",Toast.LENGTH_SHORT).show();
}
/**
* 數(shù)據(jù)庫升級
* @param db
* @param oldVersion
* @param newVersion
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d("LUO","oldVersion============"+oldVersion);
Log.d("LUO","newVersion============"+newVersion);
}
}
2. 創(chuàng)建表
創(chuàng)建一張表的步驟很簡單:
- 編寫創(chuàng)建表的SQL語句
- 調(diào)用SQLiteDatabase的execSQL()方法來執(zhí)行SQL語句
下面的代碼創(chuàng)建了一張用戶表奋构,屬性列為:id(主鍵并且自動增加)、sname(學(xué)生姓名)拱层、snumber(學(xué)號)
private void createTable(SQLiteDatabase db){
//創(chuàng)建表SQL語句
String stu_table="create table usertable(_id integer primary key autoincrement,sname text,snumber text)";
//執(zhí)行SQL語句
db.execSQL(stu_table);
}
3. 插入數(shù)據(jù)有兩種方法:
①SQLiteDatabase的insert(String table,String nullColumnHack,ContentValues values)方法弥臼,
參數(shù)1 表名稱,
參數(shù)2 空列的默認(rèn)值
參數(shù)3 ContentValues類型的一個封裝了列名稱和列值的Map根灯;
②編寫插入數(shù)據(jù)的SQL語句径缅,直接調(diào)用SQLiteDatabase的execSQL()方法來執(zhí)行
第一種方法的代碼:
private void insert(SQLiteDatabase db){
//實例化常量值
ContentValues cValue = new ContentValues();
//添加用戶名
cValue.put("sname","xiaoming");
//添加密碼
cValue.put("snumber","01005");
//調(diào)用insert()方法插入數(shù)據(jù)
db.insert("stu_table",null,cValue);
}
第二種方法的代碼:
private void insert(SQLiteDatabase db){
//插入數(shù)據(jù)SQL語句
String stu_sql="insert into stu_table(sname,snumber) values('xiaoming','01005')";
//執(zhí)行SQL語句
db.execSQL(sql);
}
4. 刪除數(shù)據(jù)
刪除數(shù)據(jù)也有兩種方法:
①調(diào)用SQLiteDatabase的delete(String table,String whereClause,String[] whereArgs)方法
參數(shù)1 表名稱
參數(shù)2 刪除條件
參數(shù)3 刪除條件值數(shù)組
②編寫刪除SQL語句,調(diào)用SQLiteDatabase的execSQL()方法來執(zhí)行刪除烙肺。
第一種方法的代碼:
private void delete(SQLiteDatabase db) {
//刪除條件
String whereClause = "id=?";
//刪除條件參數(shù)
String[] whereArgs = {String.valueOf(2)};
//執(zhí)行刪除
db.delete("stu_table",whereClause,whereArgs);
}
第二種方法的代碼:
private void delete(SQLiteDatabase db) {
//刪除SQL語句
String sql = "delete from stu_table where _id = 6";
//執(zhí)行SQL語句
db.execSQL(sql);
}
5. 更改數(shù)據(jù)
修改數(shù)據(jù)有兩種方法:
①調(diào)用SQLiteDatabase的update(String table,ContentValues values,String whereClause, String[] whereArgs)方法
參數(shù)1 表名稱
參數(shù)2 跟行列ContentValues類型的鍵值對Key-Value
參數(shù)3 更新條件(where字句)
參數(shù)4 更新條件數(shù)組
②編寫更新的SQL語句纳猪,調(diào)用SQLiteDatabase的execSQL執(zhí)行更新。
第一種方法的代碼:
private void update(SQLiteDatabase db) {
//實例化內(nèi)容值 ContentValues values = new ContentValues();
//在values中添加內(nèi)容
values.put("snumber","101003");
//修改條件
String whereClause = "id=?";
//修改添加參數(shù)
String[] whereArgs={String.valuesOf(1)};
//修改
db.update("usertable",values,whereClause,whereArgs);
}
第二種方法的代碼:
private void update(SQLiteDatabase db){
//修改SQL語句
String sql = "update stu_table set snumber = 654321 where id = 1";
//執(zhí)行SQL
db.execSQL(sql);
}
6. 查詢數(shù)據(jù)
在Android中查詢數(shù)據(jù)是通過Cursor類來實現(xiàn)的桃笙,當(dāng)我們使用SQLiteDatabase.query()方法時氏堤,會得到一個Cursor對象,Cursor指向的就是每一條數(shù)據(jù)搏明。它提供了很多有關(guān)查詢的方法鼠锈,具體方法如下:
public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);
各個參數(shù)的意義說明:
參數(shù)table:表名稱
參數(shù)columns:列名稱數(shù)組
參數(shù)selection:條件字句,相當(dāng)于where
參數(shù)selectionArgs:條件字句星著,參數(shù)數(shù)組
參數(shù)groupBy:分組列
參數(shù)having:分組條件
參數(shù)orderBy:排序列
參數(shù)limit:分頁查詢限制
參數(shù)Cursor:返回值购笆,相當(dāng)于結(jié)果集ResultSet
Cursor是一個游標(biāo)接口,提供了遍歷查詢結(jié)果的方法强饮,如移動指針方法move()由桌,獲得列值方法getString()等.
Cursor游標(biāo)常用方法
方法名稱 | 方法描述 |
---|---|
getCount() | 獲得總的數(shù)據(jù)項數(shù) |
isFirst() | 判斷是否第一條記錄 |
isLast() | 判斷是否最后一條記錄 |
moveToFirst() | 移動到第一條記錄 |
moveToLast() | 移動到最后一條記錄 |
move(int offset) | 移動到指定記錄 |
moveToNext() | 移動到下一條記錄 |
moveToPrevious() | 移動到上一條記錄 |
getColumnIndexOrThrow(String columnName) | 根據(jù)列名稱獲得列索引 |
getInt(int columnIndex) | 獲得指定列索引的int類型值 |
getString(int columnIndex) | 獲得指定列縮影的String類型值 |
下面就是用Cursor來查詢數(shù)據(jù)庫中的數(shù)據(jù)为黎,具體代碼如下:
private void query(SQLiteDatabase db) {
//查詢獲得游標(biāo)
Cursor cursor = db.query ("usertable",null,null,null,null,null,null);
//判斷游標(biāo)是否為空
if(cursor.moveToFirst() {
//遍歷游標(biāo)
for(int i=0;i<cursor.getCount();i++){
cursor.move(i);
//獲得ID
int id = cursor.getInt(0);
//獲得用戶名
String username=cursor.getString(1);
//獲得密碼
String password=cursor.getString(2);
//輸出用戶信息 System.out.println(id+":"+sname+":"+snumber);
}
}
}
7. 刪除指定表
編寫插入數(shù)據(jù)的SQL語句邮丰,直接調(diào)用SQLiteDatabase的execSQL()方法來執(zhí)行
private void drop(SQLiteDatabase db){
//刪除表的SQL語句
String sql ="DROP TABLE stu_table";
//執(zhí)行SQL
db.execSQL(sql);
}
四、SQLiteOpenHelper介紹:
該類是SQLiteDatabase一個輔助類铭乾。這個類主要生成一 個數(shù)據(jù)庫剪廉,并對數(shù)據(jù)庫的版本進(jìn)行管理。當(dāng)在程序當(dāng)中調(diào)用這個類的方法getWritableDatabase()或者 getReadableDatabase()方法的時候炕檩,如果當(dāng)時沒有數(shù)據(jù)斗蒋,那么Android系統(tǒng)就會自動生成一個數(shù)據(jù)庫。 SQLiteOpenHelper 是一個抽象類笛质,我們通常需要繼承它泉沾,并且實現(xiàn)里面的3個函數(shù):
1. onCreate(SQLiteDatabase)
在數(shù)據(jù)庫第一次生成的時候會調(diào)用這個方法,也就是說妇押,只有在創(chuàng)建數(shù)據(jù)庫的時候才會調(diào)用跷究,當(dāng)然也有一些其它的情況,一般我們在這個方法里邊生成數(shù)據(jù)庫表敲霍。
2. onUpgrade(SQLiteDatabase俊马,int丁存,int)
當(dāng)數(shù)據(jù)庫需要升級的時候,Android系統(tǒng)會主動的調(diào)用這個方法柴我。一般我們在這個方法里邊刪除數(shù)據(jù)表解寝,并建立新的數(shù)據(jù)表,當(dāng)然是否還需要做其他的操作艘儒,完全取決于應(yīng)用的需求聋伦。
3. onOpen(SQLiteDatabase):
這是當(dāng)打開數(shù)據(jù)庫時的回調(diào)函數(shù),一般在程序中不是很常使用界睁。
4. MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) :
必須要有構(gòu)造函數(shù)
5. MainActivity類
public class MainActivity extends AppCompatActivity {
@BindView(R.id.insert)
Button insert;
@BindView(R.id.update)
Button update;
@BindView(R.id.delete)
Button delete;
@BindView(R.id.query)
Button query;
SQLiteDatabase dbHelper;
@BindView(R.id.et_content)
EditText etContent;
String inputStr;
@BindView(R.id.show)
TextView show;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
inputStr = etContent.getText().toString();
init();
}
private void init() {
//依靠DatabaseHelper帶全部參數(shù)的構(gòu)造函數(shù)創(chuàng)建數(shù)據(jù)庫
MyDatabaseHelper db = new MyDatabaseHelper(MainActivity.this, "test_db", null, 1);
dbHelper = db.getWritableDatabase();
}
@OnClick({R.id.insert, R.id.update, R.id.delete, R.id.query})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.insert:
//創(chuàng)建存放數(shù)據(jù)的ContentValues對象
ContentValues values = new ContentValues();
values.put("author", "小明");
values.put("price", 33.33);
values.put("pages", "8");
values.put("name", "Android");
//數(shù)據(jù)庫執(zhí)行插入命令
dbHelper.insert("Book", null, values);
values.clear();
//第二組數(shù)據(jù)
values.put("author", "小剛");
values.put("price", 68.33);
values.put("pages", "88");
values.put("name", "Java");
//數(shù)據(jù)庫執(zhí)行插入命令
dbHelper.insert("Book", null, values);
break;
case R.id.update:
ContentValues values2 = new ContentValues();
values2.put("name", "小剛");
dbHelper.update("Book", values2, "name = ?", new String[]{"小趙"});
break;
case R.id.delete:
dbHelper.delete("Book", "name=?", new String[]{inputStr});
break;
case R.id.query:
//創(chuàng)建游標(biāo)對象
Cursor cursor = dbHelper.query("Book", new String[]{"name,author,price,pages"}, null, null, null, null, null);
//利用游標(biāo)遍歷所有數(shù)據(jù)對象
//為了顯示全部嘉抓,把所有對象連接起來,放到TextView中
String textview_data = "";
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
String pages = cursor.getString(cursor.getColumnIndex("pages"));
String price = cursor.getString(cursor.getColumnIndex("price"));
textview_data = textview_data + "\n" + name+ "\n" +author+ "\n" +pages+ "\n" +price;
}
show.setText(textview_data);
// 關(guān)閉游標(biāo)晕窑,釋放資源
cursor.close();
break;
default:
break;
}
}
}
6. activity_main.xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.function.luo.sqlitedemo.MainActivity"
android:orientation="vertical"
>
<EditText
android:id="@+id/et_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入內(nèi)容"
/>
<Button
android:id="@+id/insert"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="插入數(shù)據(jù)"
/>
<Button
android:id="@+id/update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="更新數(shù)據(jù)"
/>
<Button
android:id="@+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="刪除數(shù)據(jù)"
/>
<Button
android:id="@+id/query"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="查詢數(shù)據(jù)"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="展示結(jié)果:"
/>
<TextView
android:id="@+id/show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="~"
android:textColor="#FF0000"
android:textSize="20dp"
/>
</LinearLayout>
參考:https://www.runoob.com/sqlite/sqlite-create-table.html
參考:https://www.cnblogs.com/foxy/p/7725010.html
參考:https://blog.csdn.net/midnight_time/article/details/80834198