美文网首页程序员Android开发Android开发经验谈
Android中的数据库操作(保证线程安全)

Android中的数据库操作(保证线程安全)

作者: 林祖朋 | 来源:发表于2018-05-09 11:26 被阅读48次

    类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 
         */
    

    相关文章

      网友评论

        本文标题:Android中的数据库操作(保证线程安全)

        本文链接:https://www.haomeiwen.com/subject/nfjnrftx.html