Android中的資料庫操作(保證執行緒安全)
摘要:
類DbHelper:
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
publi...
類DbHelper:
import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DbHelper extends SQLiteOpenHelper { //資料庫名字 private static final String DATABASE_NAME = "lindb"; //資料庫版本 private static final int DATABASE_VERSION = 100; private DbHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } public DbHelper(Context context) { this(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { //建立學生表 db.execSQL("create table students(id integer primary key autoincrement,name text )"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //處理版本升級 } }
類DbManager:
import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.util.Log; import java.util.concurrent.atomic.AtomicInteger; public class DbManager { //執行緒安全的i++或i--操作,初始值為0 private AtomicInteger openCounter = new AtomicInteger(0); //資料庫管理單例 private static DbManager instance; //要管理的資料庫 private static SQLiteDatabase database; private DbHelper dbHelper; private DbManager(Context context) { dbHelper = new DbHelper(context); } /** * 需要在Application * 初始化資料庫單例 * * @param context */ public static void initDbManager(Context context) { if (instance == null) { instance = new DbManager(context); } } /** * 同步獲取該資料庫管理類單例 */ public static synchronized DbManager getInstance() { if (instance == null) { throw new IllegalStateException("DbManager is not init in application"); } return instance; } /** * 這個方法可能需要很長時間才能返回, * 所以你不應該從應用程式主執行緒呼叫它, * 包括from ContentProvider.onCreate() */ public SQLiteDatabase openDb() { Log.v("Lin2", "openDb:" + openCounter.get()); if (openCounter.incrementAndGet() == 1) { Log.v("Lin2", "打開了db"); database = dbHelper.getWritableDatabase(); } else { Log.v("Lin2", "返回開啟的db"); } return database; } public void closeDb() { Log.v("Lin2", "closeDb:" + openCounter.get()); if (openCounter.decrementAndGet() == 0) { Log.v("Lin2", "關閉了db"); database.close(); } else { Log.v("Lin2", "還有其他執行緒操作db"); } } }
在Application中初始化:
import android.app.Application; public class AppInit extends Application { @Override public void onCreate() { super.onCreate(); DbManager.initDbManager(getApplicationContext()); } }
MainActivity:
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Thread1 T1 = new Thread1(); T1.start(); Thread2 T2 = new Thread2(); T2.start(); } class Thread1 extends Thread { public void run() { Log.v("Lin2", "Running Thread1"); try { DbManager.getInstance().openDb(); for (int i = 5; i > 0; i--) { Log.v("Lin2", "Thread: Thread1" + ", " + i); // 模擬資料庫操作 Thread.sleep(1000); } DbManager.getInstance().closeDb(); } catch (InterruptedException e) { Log.v("Lin2", "Thread: Thread1" + ", " + " interrupted."); } Log.v("Lin2", "Thread: Thread1" + ", " + " exiting."); } } class Thread2 extends Thread { public void run() { Log.v("Lin2", "Running Thread2"); try { DbManager.getInstance().openDb(); for (int i = 10; i > 0; i--) { Log.v("Lin2", "Thread: Thread2" + ", " + i); // 模擬資料庫操作 Thread.sleep(1000); } DbManager.getInstance().closeDb(); } catch (InterruptedException e) { Log.v("Lin2", "Thread: Thread2" + ", " + " interrupted."); } Log.v("Lin2", "Thread: Thread2" + ", " + " exiting."); } } }
列印的資料:

data.png
資料庫操作類
import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.util.Log; import java.util.ArrayList; import java.util.List; public class DbHandle { /** * 新增名字 * * @param name * @return 是否新增成功 */ public static boolean insertStudents(String name) { ContentValues contentValues = new ContentValues(); SQLiteDatabase database = DbManager.getInstance().openDb(); database.beginTransaction(); contentValues.put("name", name); long execSql = database.insert("students", null, contentValues); contentValues.clear(); database.setTransactionSuccessful(); database.endTransaction(); //關閉database DbManager.getInstance().closeDb(); return execSql != -1; } /** * 查詢所有的名字 * * @return 名字列表 */ public static List<String> getNameList() { List<String> list = new ArrayList<>(); SQLiteDatabase database = DbManager.getInstance().openDb(); Cursor cursor = database.query("students", null, null, null, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { list.add(cursor.getString(cursor.getColumnIndex("name"))); } cursor.close(); } DbManager.getInstance().closeDb(); return list; } /** * 刪除 * * @param name * @return 刪除的行數 */ public static int delName(String name) { SQLiteDatabase database = DbManager.getInstance().openDb(); int delNumber = database.delete("students", "name=?", new String[]{name}); DbManager.getInstance().closeDb(); return delNumber; } /** * 修改 * * @param newName 修改後的 * @param oldName 要修改的 * @return 修改的行數 */ public static int updateName(String newName, String oldName) { ContentValues contentValues = new ContentValues(); SQLiteDatabase database = DbManager.getInstance().openDb(); database.beginTransaction(); contentValues.put("name", newName); int updateNumber = database.update("students", contentValues, "name=?", new String[]{oldName}); contentValues.clear(); database.setTransactionSuccessful(); database.endTransaction(); DbManager.getInstance().closeDb(); return updateNumber; } /** * 以上增刪改查的方法檢視原始碼就會知道最終執行是拼接的sql語句,但這些方法有時候並不能為所欲為。 * 下面是直接運用sql語句來實現增刪改查 */ //增 insert into students(name) values('xxx') public static void insertBySql(String name) { SQLiteDatabase database = DbManager.getInstance().openDb(); database.beginTransaction(); try { database.execSQL("insert into students(name) values ('" + name + "')"); } catch (Exception e) { Log.e("Lin2", "students插入失敗原因:" + e.getMessage()); } finally { database.setTransactionSuccessful(); database.endTransaction(); DbManager.getInstance().closeDb(); } } //刪 delete from students where name='xxx' public static void delBySql(String name) { SQLiteDatabase database = DbManager.getInstance().openDb(); try { database.execSQL("delete from students where name='" + name + "'"); } catch (Exception e) { Log.e("Lin2", "students刪除失敗原因:" + e.getMessage()); } finally { DbManager.getInstance().closeDb(); } } //改 update students set name='xx' where name='xx' public static void updateBySql(String newName, String oldName) { SQLiteDatabase database = DbManager.getInstance().openDb(); database.beginTransaction(); try { database.execSQL("update students set name='" + newName + "'" + "where name='" + oldName + "'"); } catch (Exception e) { Log.e("Lin2", "students更新失敗原因:" + e.getMessage()); } finally { database.setTransactionSuccessful(); database.endTransaction(); DbManager.getInstance().closeDb(); } } //查 select * from students public static List<String> getListBySql() { List<String> list = new ArrayList<>(); SQLiteDatabase database = DbManager.getInstance().openDb(); try { Cursor cursor = database.rawQuery("select * from students", null); if (cursor != null) { while (cursor.moveToNext()) { list.add(cursor.getString(cursor.getColumnIndex("name"))); } cursor.close(); } }catch (Exception e){ Log.e("Lin2", "students查詢失敗原因:" + e.getMessage()); }finally { DbManager.getInstance().closeDb(); } return list; } /** * 以上是都是簡單的基礎的sql */