對於開發者來說肯定都對於數據庫不會陌生,今天就來分享一篇關於android的數據庫的一些操作和簡單封裝 ,好,廢話不多說,直接上代碼(大部分解釋都註釋在代碼中了)
MySQLiteOpenHelper.java
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
private static MySQLiteOpenHelper helper;
public static final String DB_NAME = "Topeasy.db";// 數據庫名稱
public static final int VERSION = 1;
/**
* 支持創建持數據表時判斷是否存在,存在則不創建,不存在則創建,相應語句如下:
* create table if not exists
* MySQL官方對CREATE TABLE IF NOT EXISTS SELECT給出的解釋是:
* CREATE TABLE IF NOT EXIST… SELECT的行爲,先判斷表是否存在,
* 如果存在,語句就相當於執行insert into select;
* 如果不存在,則相當於create table … select。
* 解析: 1)integer 表示整型, 2)real 表示浮點型, 3)text 表示文本類型, 4)blob
* 表示二進制類型。
* 爲了確保數據的完整性和一致性,在創建表時指定字段名稱,字段類型和字段屬性外,還需要使用約束(constraint),
* 索引 (index),主鍵(primary key)和外鍵(foregin key)等。
* 約束條件:
* not null 非空約束
* unique 唯一性約束
* primary key 主鍵約束
* foreign key 外鍵約束
* check 檢查約束
* auto_increment 自動標識列(值會自動增1)
*/
public static final String CREATE_CUSTOMER = "create table " + TableConfig.TABLE_CUSTOMER + " ("
+ "id integer not null primary key autoincrement,"
+ TableConfig.Customer.CUSTOMER_NAME + " verchar(20),"
+ TableConfig.Customer.DELIVERY_PHONE + " verchar(20),"
+ TableConfig.Customer.ADDR + " verchar(20) ,"
+ TableConfig.Customer.ACCESS_TYPE + " verchar(20),"
+ TableConfig.Customer.CUSTOMER_RATING + " verchar(20), "
+ TableConfig.Customer.LAYERS + " verchar(20),"
+ TableConfig.Customer.CONTACTS + " verchar(20),"
+ TableConfig.Customer.REMARK + " verchar(20))";
//構造器,傳入四個參數Context對象,數據庫名字name,操作數據庫的Cursor對象,版本號version。
private MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
//爲了簡化構造器的使用,我們自定義一個構造器
private MySQLiteOpenHelper(Context context, String name) {
this(context, name, null, VERSION);//傳入Context和數據庫的名稱,調用上面那個構造器
}
//將自定義的數據庫創建類單例。 synchronize單例 防止多線程同時那啥 雙重鎖定
public static MySQLiteOpenHelper getInstance(Context context) {
if (helper == null) {
synchronized (MySQLiteOpenHelper.class) {
if (helper == null)
helper = new MySQLiteOpenHelper(context, DB_NAME);//數據庫名稱爲create_db。
}
}
return helper;
}
@Override
public void onCreate(SQLiteDatabase db) {
//在創建數據庫時,初始化創建數據庫中包含的數據庫表。這裏以一個“客戶”的數據表爲例
/*
customer 創建 "客戶"數據表
*/
db.execSQL(CREATE_CUSTOMER);// 執行sql語句
}
/**
* 對數據庫進行升級,注意: switch 中每一個 case的最後都是沒有使用 break ,
* 這是爲了保證在跨版本升級的時候,每一次的數據庫修改都能被全部執行到
* //當打開數據庫時傳入的版本號與當前的版本號不同時會調用該方法。
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//switch (oldVersion) {
// case 1:
// db.execSQL(CREATE_CUSTOMER);
// APP.mToast("更新數據庫,舊版本是" + oldVersion);
// case 2:
// db.execSQL(CREATE_CUSTOMER);
// APP.mToast("更新數據庫,舊版本是" + oldVersion);
// default:
// }
db.execSQL("drop table if exists "+TableConfig.TABLE_CUSTOMER); // 如果存在表Book,則刪除該表
onCreate(db); // 重新調用onCreate(),創建表
}
代碼中註釋已經解釋的好清楚了,就不多bb了好吧
DbManager.java
import android.database.sqlite.SQLiteDatabase;
import com.my_movingbricks.app.APP;
/**
* TP0826 創建數據庫類
* Created by 搬磚小能手 on 2017/4/6.
* E-mail:[email protected].
* Signature:當你的才華滿足不了你的野心的時候,那麼你應該靜下心來學習.
* Alert:語言的巨人,行動的矮子!
*/
public class DbManager {
private static DbManager manager;
private MySQLiteOpenHelper mySQLiteOpenHelper;
private SQLiteDatabase db;
/**
* 私有化構造器
*
*/
private DbManager() {
//創建數據庫
mySQLiteOpenHelper = MySQLiteOpenHelper.getInstance(APP.getInstance());
if (db == null) {
db = mySQLiteOpenHelper.getWritableDatabase();
}
}
/**
* 單例DbManager類
*
* @return 返回DbManager對象
*/
public static DbManager newInstances() {
if (manager == null) {
synchronized (DbManager.class) {
if (manager == null) {
manager = new DbManager();
}
}
}
return manager;
}
/**
* 獲取數據庫的對象
*
* @return 返回SQLiteDatabase數據庫的對象
*/
public SQLiteDatabase getDataBase() {
return db;
}
/**
* 關閉數據庫
*/
public void close() {
mySQLiteOpenHelper.close();
mySQLiteOpenHelper = null;
db.close();
db = null;
manager = null;
}
}
初始化數據庫,關閉等等。。
ChannelDaoInface.java
import java.util.ArrayList;
public interface ChannelDaoInface<T> {
/**
* 插入一條數據
*
* @param item 傳進來的item
* @return 是否插入成功
*/
public boolean addCache(String tableName, T item);
/**
* 刪除一條數據
*
* @param tableName 刪除數據庫的表名
* @param whereClause "url=?"; 刪除的字段名
* @param whereArgs {name} 刪除的字段的值
* @return
*/
public boolean deleteCache(String tableName, String whereClause, String whereArgs);
/**
* 更新
*
* @param tableName 更改數據的數據表
* @param columnName "url=?" 更改的數據的字段名
* @param columnValue {name}; 更改的數據的字段值
* @param object 更改的數據
* @return
*/
public boolean updateCache(String tableName, String columnName, String columnValue, Object object);
/**
*
* @param tableName 查詢的數據庫的名字
* @param entityType 查詢的數據庫所對應的module
* @param fieldName 查詢的字段名
* @param value 查詢的字段值
* @return
*/
public <T> ArrayList<T> queryCache(String tableName, Class<T> entityType, String fieldName, String value);
public void clearFeedTable();
}
一些數據庫操作
ChannelDao.java
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.my_movingbricks.dbinit.db.DbManager;
import com.my_movingbricks.dbinit.db.MySQLiteOpenHelper;
import com.my_movingbricks.dbinit.dbinterface.ChannelDaoInface;
import java.lang.reflect.Field;
import java.util.ArrayList;
/**
* TP0826 操作數據庫的封裝類
* Created by 搬磚小能手 on 2017/4/6.
* E-mail:40492459@qq.com.
* Signature:當你的才華滿足不了你的野心的時候,那麼你應該靜下心來學習.
* Alert:語言的巨人,行動的矮子!
*/
public class ChannelDao<T> implements ChannelDaoInface<T> {
private DbManager manager;
private SQLiteDatabase db;
public ChannelDao() {
//創建數據庫
manager = DbManager.newInstances();
db = manager.getDataBase();
}
/**
* 向數據庫插入數據
*
* @param tableName 數據庫插入數據的數據表
* @param item 數據庫插入的對象
*/
@Override
public boolean addCache(String tableName, T item) {
boolean flag = false;
long id = 0;
Class clazz = item.getClass();
Field[] fields = clazz.getDeclaredFields();//獲取該類所有的屬性
ContentValues value = new ContentValues();
for (Field field : fields) {
try {
field.setAccessible(true); //取消對age屬性的修飾符的檢查訪問,以便爲屬性賦值
String content = (String) field.get(item);//獲取該屬性的內容
value.put(field.getName(), content);
field.setAccessible(false);//恢復對age屬性的修飾符的檢查訪問
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
id = db.insert(tableName, null, value);
flag = (id != -1 ? true : false);
return flag;
}
/**
* 刪除數據
*
* @param tableName 刪除數據庫的表名
* @param whereClause 刪除的字段名
* @param whereArgs 刪除的字段的值
*/
@Override
public boolean deleteCache(String tableName, String whereClause, String whereArgs) {
boolean flag = false;
int count = 0;
count =db.delete(tableName, whereClause + "=?", new String[]{whereArgs});
flag = (count > 0 ? true : false);
return flag;
}
/**
* 更改數據庫內容
*
* @param tableName 更改數據的數據表
* @param columnName 更改的數據的字段名
* @param columnValue 更改的數據的字段值
* @param object 更改的數據
*/
@Override
public boolean updateCache(String tableName, String columnName, String columnValue, Object object) {
boolean flag = false;
int count = 0;
try {
Class clazz = object.getClass();
Field[] fields = clazz.getDeclaredFields();//獲取該類所有的屬性
ContentValues value = new ContentValues();
for (Field field : fields) {
field.setAccessible(true); //取消對age屬性的修飾符的檢查訪問,以便爲屬性賦值
String content = (String) field.get(object);//獲取該屬性的內容
value.put(field.getName(), content);
field.setAccessible(false);//恢復對age屬性的修飾符的檢查訪問
}
count=db.update(tableName, value, columnName + "=?", new String[]{columnValue});
flag = (count > 0 ? true : false);
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
return flag;
}
/**
*
* @param tableName 查詢的數據庫的名字
* @param entityType 查詢的數據庫所對應的module
* @param fieldName 查詢的字段名
* @param value 查詢的字段值
* @param <T> 泛型代表AttendInformation,Customer,Order,User,WorkDaily類
* @return 返回查詢結果,結果爲AttendInformation,Customer,Order,User,WorkDaily對象
*/
@Override
public <T> ArrayList<T> queryCache(String tableName, Class<T> entityType, String fieldName, String value) {
ArrayList<T> list = new ArrayList();
Cursor cursor = db.query(tableName, null, fieldName + " like ?", new String[]{value}, null, null, " id desc", null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {//返回遊標是否指向第最後一行的位置
try {
T t = entityType.newInstance();
for (int i = 0; i < cursor.getColumnCount(); i++) {
String columnName = cursor.getColumnName(i);// 獲取數據記錄第i條字段名的
String content = cursor.getString(i);//獲得獲取的數據記錄第i條字段的內容
Field field = entityType.getDeclaredField(columnName);//獲取該字段名的Field對象。
field.setAccessible(true);//取消對age屬性的修飾符的檢查訪問,以便爲屬性賦值
field.set(t, content);
field.setAccessible(false);//恢復對age屬性的修飾符的檢查訪問
}
list.add(t);
cursor.moveToNext();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
return list;
}
/**
* 刪除表中的數據
*/
@Override
public void clearFeedTable() {
String sql = "DELETE FROM " + MySQLiteOpenHelper.CREATE_CUSTOMER + ";";
db.execSQL(sql);
revertSeq();
}
/**
* 以SQLHelper.TABLE_CHANNEL表作爲條件,新建表sqlite_sequence,當name=表名的時候
* 更新seq=0;
*/
private void revertSeq() {
String sql = "update sqlite_sequence set seq=0 where name='"
+ MySQLiteOpenHelper.CREATE_CUSTOMER + "'";
db.execSQL(sql);
}
//關閉數據庫
private void OnCliar(ContentValues value) {
value.clear();
}
}
操作的實現
TableOperate.java
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.my_movingbricks.dbinit.db.DbManager;
/**
* abc
* Created by 搬磚小能手 on 27/10/2017.
* E-mail:[email protected].
* Signature:當你的才華滿足不了你的野心的時候,那麼你應該靜下心來學習.
* Alert:語言的巨人,行動的矮子!
*/
public class TableOperate {
private DbManager manager;
private SQLiteDatabase db;
public TableOperate() {
//創建數據庫
manager = DbManager.newInstances();
db = manager.getDataBase();
}
/**
* 添加數據
*/
public void insertData(String tableName, ContentValues values) {
db.insert(tableName, null, values);// 插入一條數據
}
public ContentValues initContentValues(String[] key, String[] values) {
if (key.length != values.length) return null;
ContentValues cv = new ContentValues();
for (int i = 0; i < key.length; i++) {
cv.put(key[i], values[i]);
}
return cv;
}
public void insertData(String tableName, String[] key, String[] values) {
db.insert(tableName, null, initContentValues(key, values));// 插入一條數據
}
/**
* 更新數據
*
* @param values
* @param whereClause "url=?"
* @param whereArgs {name};
*/
public void updateData(String tableName, ContentValues values, String whereClause, String[] whereArgs) {
db.update(tableName, values, whereClause,
whereArgs);
}
public void updateData(String tableName, String[] key, String[] values, String whereClause, String[] whereArgs) {
db.update(tableName, initContentValues(key, values), whereClause, whereArgs);
}
/**
* 刪除數據
*
* @param whereClause "url=?"
* @param whereArgs {name};
*/
public void deleteData(String tableName, String whereClause, String[] whereArgs) {
db.delete(tableName, whereClause, whereArgs);
}
/**
* 查詢數據
*
* @param tableName 表名,不能爲null
* @param columns 要查詢的列名,可以是多個,可以爲null,表示查詢所有列
* @param selection 查詢條件,比如id=? and name=? 可以爲null
* @param selectionArgs 對查詢條件賦值,一個問號對應一個值,按順序 可以爲null
* @param groupBy
* @param having 語法have,可以爲null
* @param orderBy 語法,按xx排序,可以爲null
* @return
*/
public Cursor selectData(String tableName, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
Cursor cursor = db.query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy);
return cursor;
}
public void selectData(Cursor cursor, String... key) {
if (cursor.moveToFirst()) { // 返回假時 那就爲空 移動光標到第一行
do {
for (int i = 0; i < key.length; i++) {
String name=cursor.getString(cursor.getColumnIndex(key[i]));
}
} while (cursor.moveToNext());
}
cursor.close();
}
/**
if (cursor.moveToFirst()) {// 返回假時 那就爲空 移動光標到第一行
do {
// 遍歷cursor對象,取出數據 對比搜索到的數據,如果有則爲已收藏收藏
String url = cursor.getString(cursor.getColumnIndex("url"));
String theme = cursor.getString(cursor.getColumnIndex("theme"));
String content = cursor.getString(cursor
.getColumnIndex("content"));
}
} while (cursor.moveToNext());
*/
}
另一個實現類,以便滿足多種需求
好了 就這麼愉快的分享完了,總體來說比較簡單,當然大家可以去使用目前比較成熟的框架greenDAO或者是xutlis的db模塊,也是比較通俗易懂的,這裏就不做介紹了哈, 如果文章有錯誤希望小夥伴們告知一下哈 。
文章末尾附上設計的幾個類的下載地址:點擊傳送