SQLite簡介
SQLite是一款輕型的資料庫,是遵守ACID的關聯式資料庫管理系統,它的設計目標是嵌入 式的,而且目前已經在很多嵌入式產品中使用了它,它佔用資源非常的低,在嵌入式裝置中,可能只需要幾百K的記憶體就夠了。它能夠支援 Windows/Linux/Unix等等主流的作業系統,同時能夠跟很多程式語言相結合,比如Tcl、PHP、Java、C++、.Net等,還有ODBC介面,同樣比起 Mysql、PostgreSQL這兩款開源世界著名的資料庫管理系統來講,它的處理速度比他們都快。
SQLite資料型別
一般資料採用的固定的靜態資料型別,而SQLite採用的是動態資料型別,會根據存入值自動判斷。SQLite具有以下五種常用的資料型別:
NULL: 這個值為空值
VARCHAR(n):長度不固定且其最大長度為 n 的字串,n不能超過 4000。
CHAR(n):長度固定為n的字串,n不能超過 254。
INTEGER: 值被標識為整數,依據值的大小可以依次被儲存為1,2,3,4,5,6,7,8.
REAL: 所有值都是浮動的數值,被儲存為8位元組的IEEE浮動標記序號.
TEXT: 值為文字字串,使用資料庫編碼儲存(TUTF-8, UTF-16BE or UTF-16-LE).
BLOB: 值是BLOB資料塊,以輸入的資料格式進行儲存。如何輸入就如何儲存,不改 變格式。
DATA :包含了 年份、月份、日期。
TIME: 包含了 小時、分鐘、秒。
資料庫SQL增刪改查語句:
sql語句不區分大小寫
-
查詢: select column1,column2 from table_name 或者 select * from table_name
-
插入: insert into table_name(column1,column2) values (value1,value2)
-
更新: 更新已有表的資料: update table_name set column1 = value1, column2 = value2 where +條件語句
向表中插入列: alter table table_name add column column_name text(varchar(10)、char等)
- 刪除: delete from table_name where +條件語句
資料庫建立:
首先建立一個類去繼承SQLiteOpenHelper,建立一個test.db的資料庫
public class DBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "test.db";
public static final int DB_VERSION = 1;
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DBDao.SQL_CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
}
}
複製程式碼
其中onCreate()是在資料庫首次建立的時候呼叫,onUpgrade()是在資料庫版本號DB_VERSION升級的時候才會呼叫
封裝增刪改查方法:
public class DBDao {
public static final String TABLE_NAME = "student";//表名
private static final String ID = "id";//id自增長
private static final String NAME = "stu_name";//姓名
private static final String AGE = "stu_age";//年齡
private static final String SEX = "stu_sex";//性別
private static final String GRADE = "stu_grade";//年級
//DB_Version2增加新欄位
private static final String SCORE = "store";
private DBHelper dbHelper;
//建立表結構
public static final String SQL_CREATE_TABLE = "create table " + TABLE_NAME + "(" +
ID + " integer primary key autoincrement," +
NAME + " text," +
AGE + " integer," +
SEX + " varchar(5)," +
GRADE + " text" +
")";
private DBDao() {
dbHelper = new DBHelper(MyApplication.getContext());
}
public static DBDao getInstance() {
return InnerDB.instance;
}
private static class InnerDB {
private static DBDao instance = new DBDao();
}
/**
* 資料庫插入資料
*
* @param bean 實體類
* @param <T> T
*/
public synchronized <T> void insert(T bean) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
try {
if (bean != null && bean instanceof Student) {
Student student = (Student) bean;
ContentValues cv = new ContentValues();
cv.put(NAME, student.getName());
cv.put(AGE, student.getAge());
cv.put(SEX, student.getSex());
cv.put(GRADE, student.getGrade());
cv.put(SCORE, student.getStore());
db.insert(TABLE_NAME, null, cv);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
db.close();
}
}
/**
* 刪除表中所有的資料
*/
public synchronized void clearAll() {
SQLiteDatabase db = dbHelper.getWritableDatabase();
String sql = "delete from " + TABLE_NAME;
try {
db.execSQL(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
db.close();
}
}
/**
* 查詢資料
*
* @return List
*/
public synchronized <T> List<T> query() {
SQLiteDatabase db = dbHelper.getReadableDatabase();
List<T> list = new ArrayList<>();
String querySql = "select * from " + TABLE_NAME;
Cursor cursor = null;
try {
cursor = db.rawQuery(querySql, null);
while (cursor.moveToNext()) {
Student student = new Student();
student.setName(cursor.getString(cursor.getColumnIndex(NAME)));
student.setAge(cursor.getInt(cursor.getColumnIndex(AGE)));
student.setSex(cursor.getString(cursor.getColumnIndex(SEX)));
student.setGrade(cursor.getString(cursor.getColumnIndex(GRADE)));
student.setStore(cursor.getString(cursor.getColumnIndex(SCORE)));
list.add((T) student);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
if (db != null) {
db.close();
}
}
return list;
}
}
複製程式碼
建立實體類:
public class Student {
private String name;
private int age;
private String grade;
//Version2新增
private String sex;
public String getStore() {
return store;
}
public void setStore(String store) {
this.store = store;
}
private String store;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Student() {
}
public Student(String name, int age, String grade, String sex,String store) {
this.name = name;
this.age = age;
this.grade = grade;
this.sex = sex;
this.store=store;
}
}
複製程式碼
執行資料庫操作:
Student student = new Student("小明", 20, "三年二班", "man");
DBDao.getInstance().insert(student);
複製程式碼
insert()方法中呼叫了dbHelper.getWritableDatabase(),此時沒有test.db資料庫則會去建立,接著執行onCreate()去建立了student表並插入了一條資料,去data/data/package_name/databases下檢視發現test.db已經被建立好了,並且表中已經有了插入的資料,如下:
到此我們已經完成了基本的資料庫建立過程。
資料庫升級:
在版本迭代的過程中,我們難免不了要去改變我們資料庫的內容,此時就要考慮我們的資料庫升級問題了,假如此時我們有個需求,要在新的版本中在資料庫表中新加一個欄位,首先我們要把DB_VERSION提升到2,那麼安裝新版本APK的時候就會執行onUpdate()操作去執行更新操作,那麼我們直接把更新的操作放到onUpdate()就可以了嗎?當然不行!我們要考慮各個版本的情況,比如使用者沒有安裝過1.0版本,直接安裝的2.0版本,那麼這種情況是不會執行onUpdate()方法的,以後有了3.0、4.0版本,邏輯將更復雜,所以單純的放到onUpdate()中是不可行的,還有一種方式:
@Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DBDao.SQL_CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
db.execSQL("DROP TABLE IF EXISTS student");
this.onCreate(db);
} catch (Exception e) {
}
}
複製程式碼
這種的在更新時直接把原來的表刪除掉然後手動去調onCreate()去重建表,個人覺得不夠優雅,首先老資料會丟失,假如要手動儲存,表中資料量大時操作起來也不方便,那麼有沒有更好一些的方法呢?看下面這種方式:
private static final String DB_NAME = "test.db";
public static final int DB_VERSION = 2;
@Override
public void onCreate(SQLiteDatabase database) {
int initDBVersion = 1;
DataBaseHelper.initDB(database);
onUpgrade(database, initDBVersion, DB_VERSION);
}
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, int newVersion) {
for (int i = oldVersion; i < newVersion; i++) {
switch (i) {
case 1:
DataBaseHelper.upToDbVersion2(database);
break;
case 2:
DataBaseHelper.upToDbVersion3(database);
break;
default:
break;
}
}
}
複製程式碼
如果使用者是從1.0升到2.0的,那麼會直接執行onUpdate(),此時oldVersion是1,執行for迴圈中的DataBaseHelper.upToDbVersion2(database),如果使用者沒有裝過1.0版本而是直接安裝的2.0版本,那麼會執行onCreate()方法,在onCreate()中手動呼叫的onUpdate()方法去執行更新操作,這樣就相容到了各種需求,同時升級到3.0、4.0版本都是可以相容的,比如在2.0時想在原有表中新加一列:
public static void upToDbVersion2(SQLiteDatabase database) {
String updateSql = "alter table " + DBDao.TABLE_NAME + " add column store varchar(5)";
database.execSQL(updateSql);
}
複製程式碼
升級到3.0時想把列store中的值全改成100:
public static void upToDbVersion3(SQLiteDatabase database) {
ContentValues values = new ContentValues();
values.put("store", 100);
database.update(DBDao.TABLE_NAME, values, null, null);
}
複製程式碼
實驗結果可知,各種情況都可以相容,個人覺得這種方案更好一些,注意資料庫的版本號只能升級,不能降級,例如不能將資料庫版本號從2降到1:
Caused by: android.database.sqlite.SQLiteException: Can't downgrade database from version 2 to 1
複製程式碼
原始碼地址:http://download.csdn.net/download/u013700502/10043778
參考:http://www.w3school.com.cn/sql/index.asp http://www.runoob.com/sqlite/sqlite-update.html http://blog.csdn.net/codeeer/article/details/30237597/