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

it2022-05-05  88

目录

文章素材数据库1、认识一下SQLiteOpenHelper2、创建单例模式SQLiteOpenHelper3、单例模式下的增删改查 线程池1、示列2、调用 总结

文章素材


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

数据库


       我们都知道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


最新回复(0)