不是sqlite源码!!!本人sql太渣,通过SQLiteDatabase 学习一下
硬知识
SQLiteSession
- WAL:https://zh.wikipedia.org/wiki/%E9%A2%84%E5%86%99%E5%BC%8F%E6%97%A5%E5%BF%97
- 在开启WAL之后,sqlite支持并行的读和写事务;否则,只有只读事务可以并行。具体解释
- 套嵌事务的成功必须是每个子事务都是成功的,事务可以通过yieldTransaction释放。yield时会把事务当前的操作commit掉,但是yield之后不能回滚
- EXCLUSIVE和IMMEDIATE事务:http://blog.csdn.net/degwei/article/details/9672795;还有一个DEFERRED事务,仅在事务第一次进行数据库操作时才获取锁。三个mode的锁类型不同,详见源码
- 锁类型:
- SHARED:当前线程只可读,其他线程可读写
- RESERVED :当前线程可读写,其他线程只可读
- EXCLUSIVE :当前线程可读写,其他线程被锁
SQLiteDatabase
- 可以调deleteDatabase删除所有数据库相关文件
- WAL官方形容:使用多个connection进行数据库操作,在写完成前,所有读(包括并发的)都是读旧值。内存使用量会有显著的提高。WAL模式下,所有的事务都应该用noExclusive模式
- 如果执行了Attach database或内存数据库或只读数据库,WAL都不生效
- open的时候传入ENABLE_WRITE_AHEAD_LOGGING参数,启动WAL的效率更高
SQLiteCursor
- 数据库操作是发生在cursor里的,时机是在getCount和Move类函数执行时
合理设计
SQLiteSession
- 每个线程(ThreadLocal)中每个Database对应一个session(单例),保证:
- 不会同一线程中的读写死锁
- 不会因为胡乱写导致db的connection超过上限
- 导致了会有数据库被lock的异常
- session仅在执行事务(单条sql语句也是个隐性事务)时持有一个connection,保证了连接池足够小
- Transaction是一个树形结构,所有transaction只负责自己和最顶层的transaction的成功与否(在end时标记二者的成功与否)。所以,transaction的数据结构中只保存父节点指针,session只保存当前执行的transaction节点,这样保证了以最少的指针保存完整调用关系
SQLiteDatabase
- 所有真实的query操作都放到了一个单独的接口实现(SQLiteCursorDriver)中,使用了Template模式,可以方便的进行加密之类的附加操作(实现一个SQLiteCursorDriver,并复写相关的数据操作)。当然最好是提供setDriver方法,省去了集成
技巧
SQLiteDatabase
- WeakXXX的引用holder只有WeakReference和WeakHashMap,可以把
WeakHashMap<Target,Object>
当做WeakHashSet用 - Yield只是commit/rollback一下当前操作,这样就足以完成线程间的锁切换,对于多线程的任务重入也可以使用差不多的办法。yield传入时间,会直接调用Thread.sleep
SQLiteClosable
- 手写一个引用计数器,作为资源释放的统一调用方
功能-sql记录
SELECT
- 完整语句:SELECT [DISTINCT] FROM tableName WHERE whereClause GROUP BY groupClause HAVING havingClause ORDER BY orderClause LIMIT limitClause。其中:
- Distinct 保证指定域的独立性
- GROUP BY用来以某列来合并数据
- HAVING 支持合计函数的WHERE
INSERT
- 完整语句:INSERT [conflictMethod] INTO tableName [(columnNames)] VALUES (values)
- Conflict method有:
- OR ROLLBACK:冲突后直接回滚本次事务(可能把之前的操作一起搞掉)
- OR ABORT:本insert语句无效,事务不回滚
- OR FAIL:返回SQLITE_CONSTRAINT,但是所有修改(包括本语句的部分修改)不回滚
- OR IGNORE:忽略
- OR REPLACE:可能有变!!!
- UNIQUE冲突:先删除相同主键的行,再insert(如果本次的数据不全,会丢失数据!!!)
- NOT NULL冲突:试图以default value填入null列,失败则Abort
- CHECK冲突:使用IGNORE策略
DELETE
- 完整语句:DELETE FROM tableName WHERE whereClause
UPDATE
- 完整语句:UPDATE [confictMethod] tableName SET columnName=value WHERE whereClause
- conflictMethod 同insert
其他
- ALTER TABLE
- CREATE or DROP table / trigger / view / index / virtual table
- REINDEX
- RELEASE:删除保存点后的修改
- SAVEPOINT:保存点
- PRAGMA