Android本地数据库基础操作|多线程操作数据库|数据库的增删改查|批量插入数据库|线程池基础使用|玉念聿辉

文章素材


       本文素材来源于作者(玉念聿辉)的愚蠢操作,最近在一个项目有使用到本地数据库,一段猛如虎的操作下来后发现没法进行多线程操作,大致是报一个数据库被占用的错(具体错误忘记截图了),亲自跑度娘一趟发现使用单例模式可以解决,又一次猛如虎的操作下来发现数据插入太慢等等,因此有了这篇笔记。

数据库


       我们都知道Android虽然给我们提供了一个SQLiteOpenHelper,但粗心的朋友很可能跟我一样,稍在一些细节上不注意就会引发大患。

1、认识一下SQLiteOpenHelper
public class DatabaseHelper extends SQLiteOpenHelper {

@Override
    public void onCreate(SQLiteDatabase db) {
	//在这里创建数据库
	}

@Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
	//在这里可以做升级等
    }
}
2、创建单例模式SQLiteOpenHelper
public class DatabaseHelper extends SQLiteOpenHelper {
    final String TAG = DatabaseHelper.class.getSimpleName();

    private static DatabaseHelper mInstance;

    public DatabaseHelper(Context context) {
        super(context, "database", null, 1);// 创建数据库名
    }

	//创建DatabaseHelper
    public synchronized static DatabaseHelper getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new DatabaseHelper(context);
        }
        return mInstance;
    }

	//关闭DatabaseHelper
    public synchronized static void destoryInstance() {
        if (mInstance != null) {
            mInstance.close();
        }
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table table_name(id Integer primary key autoincrement, note text,changeTime text)");// 创建表
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
3、单例模式下的增删改查
/**
*不进行批量插入的插入方法(不开启事务)
*/
public synchronized void insertData(){
	ContentValues values=new ContentValues();
	values.put("note ", "备注");
	values.put("changeTime ", new date());
	getWritableDatabase().insert("table_name", null, values);
}

/**
*批量插入(开启事务)
*/
public synchronized void insertData(List<ContentValues> cvList) {
        SQLiteDatabase db = getWritableDatabase();
        db.beginTransaction();
        try {
            for (ContentValues values : cvList) {
                db.insert("init_table", null, values);
            }
            db.setTransactionSuccessful(); // 设置事务处理成功,不设置会自动回滚不提交
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 结束事务
            db.endTransaction();
            db.close();
            Log.i(TAG, "插入数据库完成");
        }
 }

/**
 * 查询数据库中table_name表数据的总条数.
 *  * @return
*/
public synchronized int getAllCaseNum() {
        SQLiteDatabase db = getWritableDatabase();
        db.beginTransaction();
        String sql = "select count(*) from table_name";
        Cursor cursor = null;
        long count = 0;
        try {
            cursor = db.rawQuery(sql, null);
            cursor.moveToFirst();
            count = cursor.getLong(0);
            Log.i(TAG, "init_table表总数据条数: " + count);
            db.setTransactionSuccessful(); // 设置事务处理成功,不设置会自动回滚不提交
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cursor.close();
            // 结束事务
            db.endTransaction();
            db.close();
        }
        return (int) count;
}

注:
* 多线程管理开启单例模式即可(synchronized);
* 数据库的增删改查尽量开启事务来执行,执行完要记得关闭;
* Cursor使用结束记得关闭;

参见文章:https://www.cnblogs.com/zhujiabin/p/4240769.html

线程池


       通过将SQLiteOpenHelper设置单例模式后,我们还是需要线程池来调用才能确保速度上的提升了,这里就简单贴一下需要注意的地方,如线程池大小、空闲时间等(也就是ThreadPoolExecutor的参数设置)。

在这里插入图片描述

1、示列
private static final BlockingQueue<Runnable> POOL_QUEUE_TASK = new SynchronousQueue<Runnable>();
private static final ThreadFactory TASK_FACTORY = new ThreadFactory() {
private final AtomicInteger COUNT = new AtomicInteger(1);

public Thread newThread(Runnable runnable) {
      int count = COUNT.getAndIncrement();
           return new Thread(runnable, "Func #" + count);
      }
};

/**
* 线程池
*/
public static final ExecutorService FUNC_TASK = new ThreadPoolExecutor(8,
            Integer.MAX_VALUE, 3L, TimeUnit.SECONDS, POOL_QUEUE_TASK,
            TASK_FACTORY);
2、调用
FUNC_TASK.execute(new Runnable() {
      @Override
       public void run() {
            //例如在这里进行调用插入数据的方法
       }
});

总结


       开发速度固然重要,但实际过程中我们往往会忽略一些简单的细节处理,希望每一次bug都是我们成长的见证,文章仅作为笔记,如有错误欢迎大家指点。

       最后推荐一款学习硬件开发的IDE,对于我这种菜鸟C|C++的人来说,Arduino确实是一个不错的选择。

我的第一个demo:https://blog.csdn.net/qq_35350654/article/details/94876016
Arduino学习资料:https://www.arduino.cn/thread-1066-1-1.html

发布了63 篇原创文章 · 获赞 103 · 访问量 9万+
展开阅读全文

找不到数据库的表,我用sql语句写的,在问问是否要开辟一个子线程

09-20

09-19 11:25:32.349: E/SQLiteLog(28075): (1) no such table: classlist 09-19 11:25:32.358: D/AndroidRuntime(28075): Shutting down VM 09-19 11:25:32.358: W/dalvikvm(28075): threadid=1: thread exiting with uncaught exception (group=0xb4ea3288) 09-19 11:25:32.379: E/AndroidRuntime(28075): FATAL EXCEPTION: main 09-19 11:25:32.379: E/AndroidRuntime(28075): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kakabuli.phonesafe/com.kakabuli.phonesafe.CommonNumberActivity}: android.database.sqlite.SQLiteException: no such table: classlist (code 1): , while compiling: select count(*) from classlist 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.app.ActivityThread.access$600(ActivityThread.java:130) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.os.Handler.dispatchMessage(Handler.java:99) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.os.Looper.loop(Looper.java:137) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.app.ActivityThread.main(ActivityThread.java:4745) 09-19 11:25:32.379: E/AndroidRuntime(28075): at java.lang.reflect.Method.invokeNative(Native Method) 09-19 11:25:32.379: E/AndroidRuntime(28075): at java.lang.reflect.Method.invoke(Method.java:511) 09-19 11:25:32.379: E/AndroidRuntime(28075): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 09-19 11:25:32.379: E/AndroidRuntime(28075): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 09-19 11:25:32.379: E/AndroidRuntime(28075): at dalvik.system.NativeStart.main(Native Method) 09-19 11:25:32.379: E/AndroidRuntime(28075): Caused by: android.database.sqlite.SQLiteException: no such table: classlist (code 1): , while compiling: select count(*) from classlist 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:882) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:493) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253) 09-19 11:25:32.379: E/AndroidRuntime(28075): at com.kakabuli.phonesafe.db.dao.CommonNumberDao.getGroupCount(CommonNumberDao.java:23) 09-19 11:25:32.379: E/AndroidRuntime(28075): at com.kakabuli.phonesafe.CommonNumberActivity$CommonNumberAdapter.getGroupCount(CommonNumberActivity.java:63) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.widget.ExpandableListConnector.getCount(ExpandableListConnector.java:397) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.widget.ListView.setAdapter(ListView.java:460) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.widget.ExpandableListView.setAdapter(ExpandableListView.java:470) 09-19 11:25:32.379: E/AndroidRuntime(28075): at com.kakabuli.phonesafe.CommonNumberActivity.onCreate(CommonNumberActivity.java:39) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.app.Activity.performCreate(Activity.java:5008) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079) 09-19 11:25:32.379: E/AndroidRuntime(28075): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023) 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览