程序员Android开发Android开发经验谈

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

2018-05-09  本文已影响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 
     */
上一篇下一篇

猜你喜欢

热点阅读