Android数据存储(七) SQLite使用注意和SQL语句
来源:互联网 发布:excel数据分析回归 编辑:程序博客网 时间:2024/06/14 23:02
1、数据类型的问题
SQLite内部只支持NULL、INTEGER、REAL(浮点数)、TEXT(文本)和BLOB(大二进制对象)这5种数据类型,但实际上SQLite完全可以接受varchar(n)、char(n)、decimal(p,s)等数据类型,只不过SQLite会在原酸或保存时将他们转换为上面5种数据类型中相应的类型。
除此之外,SQLite还有一个特点:它允许把各种类型的数据保存到任何类型字段中,开发者可以不用关心声明该字段所使用的数据类型。例如程序可以把字符串类型的值存入到INTEGER类型的字段中,也可以把数值数据类型的值存入到布尔类型的字段中。。。。但是有一中情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数,当向这种字段保存除整数意外的其他类型的数据时,SQLite会产生错误。
并且,可以向字符串字段中插入任意长度的字符串,即使声明varchar(20)加以限制。
2、数据库何时关闭问题
我们使用SQLiteOpenHelper获取一个SQLiteDatabase数据库对象,然后就可以去使用这个数据库了。那么这个数据库何时关闭呢。一般我们不需要操作一次数据库,就去关闭它,因为这样很耗资源。毕竟这不是像J2EE上面的数据库,J2EE服务器上的数据库会根据访问的用户生成许多数据库连接,所以需要关闭。但是在Android手机上,只有我们当前的应用程序再回有一个数据库的连接,当然不需要用一次关闭一次。
所以,我们只需要完成了所有的数据库操作,或者退出程序的时候,选择一个恰当的实际关闭。
3、SQLiteDatabase对象的获取问题。
我们获取数据库实例时使用了getWritableDatabase()方法,也许朋友们会有疑问,在getWritableDatabase()和getReadableDatabase()中,你为什么选择前者作为整个应用的数据库实例呢?在这里我想和大家着重分析一下这一点。
我们来看一下SQLiteOpenHelper中的getReadableDatabase()方法:
在getReadableDatabase()方法中,首先判断是否已存在数据库实例并且是打开状态,如果是,则直接返回该实例,否则试图获取一个可读写模式的数据库实例,如果遇到磁盘空间已满等情况获取失败的话,再以只读模式打开数据库,获取数据库实例并返回,然后为mDatabase赋值为最新打开的数据库实例。既然有可能调用到getWritableDatabase()方法,我们就要看一下了:
public synchronized SQLiteDatabase getWritableDatabase() { if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) { // 如果mDatabase不为空已打开并且不是只读模式 则返回该实例 return mDatabase; } if (mIsInitializing) { throw new IllegalStateException("getWritableDatabase called recursively"); } // If we have a read-only database open, someone could be using it // (though they shouldn't), which would cause a lock to be held on // the file, and our attempts to open the database read-write would // fail waiting for the file lock. To prevent that, we acquire the // lock on the read-only database, which shuts out other users. boolean success = false; SQLiteDatabase db = null; // 如果mDatabase不为空则加锁 阻止其他的操作 if (mDatabase != null) mDatabase.lock(); try { mIsInitializing = true; if (mName == null) { db = SQLiteDatabase.create(null); } else { // 打开或创建数据库 db = mContext.openOrCreateDatabase(mName, 0, mFactory); } // 获取数据库版本(如果刚创建的数据库,版本为0) int version = db.getVersion(); // 比较版本(我们代码中的版本mNewVersion为1) if (version != mNewVersion) { db.beginTransaction();// 开始事务 try { if (version == 0) { // 执行我们的onCreate方法 onCreate(db); } else { // 如果我们应用升级了mNewVersion为2,而原版本为1则执行onUpgrade方法 onUpgrade(db, version, mNewVersion); } db.setVersion(mNewVersion);// 设置最新版本 db.setTransactionSuccessful();// 设置事务成功 } finally { db.endTransaction();// 结束事务 } } onOpen(db); success = true; return db;// 返回可读写模式的数据库实例 } finally { mIsInitializing = false; if (success) { // 打开成功 if (mDatabase != null) { // 如果mDatabase有值则先关闭 try { mDatabase.close(); } catch (Exception e) { } mDatabase.unlock();// 解锁 } mDatabase = db;// 赋值给mDatabase } else { // 打开失败的情况:解锁、关闭 if (mDatabase != null) mDatabase.unlock(); if (db != null) db.close(); } } }
大家可以看到,几个关键步骤是,首先判断mDatabase如果不为空已打开并不是只读模式则直接返回,否则如果mDatabase不为空则加锁,然后开始打开或创建数据库,比较版本,根据版本号来调用相应的方法,为数据库设置新版本号,最后释放旧的不为空的mDatabase并解锁,把新打开的数据库实例赋予mDatabase,并返回最新实例。
看完上面的过程之后,大家或许就清楚了许多,如果不是在遇到磁盘空间已满等情况,getReadableDatabase()一般都会返回和getWritableDatabase()一样的数据库实例,所以我们在DBManager构造方法中使用getWritableDatabase()获取整个应用所使用的数据库实例是可行的。当然如果你真的担心这种情况会发生,那么你可以先用getWritableDatabase()获取数据实例,如果遇到异常,再试图用getReadableDatabase()获取实例,当然这个时候你获取的实例只能读不能写了。
并且,同一个数据库只会返回一个SQLiteDatabase数据库实例。
4、在Android中对数据库操作语句和方法
SQLite中sql语句和MySql非常类似,完全可以去参照MySql的sql语句。
- Android数据存储(七) SQLite使用注意和SQL语句
- Android数据存储之SQLite中常用的SQL语句
- Android数据存储SQLite-使用sql操作数据库
- android使用sqlite存储数据
- Android 数据存储 &SQLite使用,
- Android使用SQLite存储数据
- Android进阶#(5/12)独特高效的数据存储——SQLite数据库_SQLite中的SQL语句
- SQLITE SQL语句的注意
- 野人学Android基础篇之数据存储第一课--SQLite的使用及注意点
- Android-数据存储( SQLite )
- Android数据存储(二):SQLite存储
- Android数据存储(SqLite数据库存储)
- Android数据存储(六)、SQLite数据库使用实例
- Android开发使用SQLite存储数据
- 【Android数据存储】SQLite使用实例
- Android数据存储—使用SQLite数据库
- Android数据存储—使用SQLite数据库
- android数据存储之SQLite的使用
- 完全背包
- How to root Samsung Galaxy Ace Plus
- 2012年2月到2012年8月个人总结
- 第十四章 老板回来我不知道--观察者模式(读书笔记)
- tuxedo 客户端使用gcc编译
- Android数据存储(七) SQLite使用注意和SQL语句
- 求两个字符串的最长的连续公共子串
- 开学 OR 放假
- 个人工作后的感想
- Silverlight与WCF之间的通信(2)利用WCF的双工通信“推送”给SL数据
- Android之JNI和NDK的那些事
- IE6 IE7 IE8 css bug兼容性解决方法总结归纳
- windowsphone7数据绑定的一种用法
- 中国电子行业企业排名100强