SQLite总结
SQLite DatabaseSQLite is an embedded relational database engine. Its developers call it a self-contained, serverless, zero-configuration and transactional SQL database engine. 其实只需要记住SQLite不需要数据库服务器,不需要额外配置,其数据库本身就是一个文件的一个小型数据库。 通常情况下在android中创建数据库,系统会在"DATA/data/APP_NAME/databases".目录为我们创建数据库文件。SQLite BasicDataTypes
SQLite支持的数据类型有很多,但他们总共可以分为以下几类:
- desc <table> //查看表结构
- select * from <table> //查询所有更
- select , from table ;//查看指定列
- select distinct , from table ;//非重复查询
- insert into users(_id,username,password) select * from users;//复制
- select username from users where username like 'S%' ;//非重名字首字母为大写S的用户
- select username from users where username like '__S%' ;//非重名字第三个字母为大写S的用户
- select * from users where _id in(001,220,230);
- select * from user order by _id;//以id的顺序排列
- select * from user order by _id desc;//以id反的顺序排
常用Select语句
- desc <table> //查看表结构
- select * from <table> //查询所有更
- select , from table ;//查看指定列
- select distinct , from table ;//非重复查询
- insert into users(_id,username,password) select * from users;//复制
- select username from users where username like 'S%' ;//非重名字首字母为大写S的用户
- select username from users where username like '__S%' ;//非重名字第三个字母为大写S的用户
- select * from users where _id in(001,220,230);
- select * from user order by _id;//以id的顺序排列
- select * from user order by _id desc;//以id反的顺序排
图形环境很少有人直接在程序当中直接编写SQL语句,麻烦且容易出错。所以最好应该先在一个图形化的环境把SQL语句写好,测试好再加入到代码当中。 而且,SQLite数据库本身就是一个独立的文件,很容易从模拟器上抓取出来。可以使用图形化界面进行分析,和修改 etc.
SQLite expert 是个简单小巧的SQLite数据库管理软件,有免费版和,收费版两种,一般来讲免费版足以应付我们需求。
sqliteexpert官方网址软件界面截图

为了创建一张table 首先要有一个数据库文件,点击"File"->""New Database然后选择文件的路径,点击OK便创建了一个数据库文件 创建完数据库之后创建表格,右击数据库文件名选择"New Table"如下图所示:





点击SQL,执行以下SQL语句,为表格增加一个用户:
- INSERT INTO user_accounts(row_id,username,password) VALUES(001,'John','abcdef');

- INSERT INTO user_accounts(row_id,username,password) VALUES(002,'David','123456');
- INSERT INTO user_accounts(row_id,username,password) VALUES(003,'Sarah','00000000');
执行下面的语句删除用户David:
- DELETE FROM user_accounts WHERE username = 'David';
执行以下语句修改Sarah的密码:
- update user_accounts SET password='666666' WHERE username = 'Sarah';
- SELECT * FROMM user_accounts;
- SELECT username,password FROM user_accounts;
SQL可以通过给定查询条件进行精确查找,比如我们只需要John的密码。就可以使用这样的语句
- SELECT password FROM user_accounts WHERE username = 'John';




















获取数据行总数:
最简单的方法是:SELECT所有的行,再调用curosr.getCount() ;取得行数,但这样效率会很低。 SQLite为我们提供了一个函数很容易查出总共有多少行。有个名为cet6_table的表格,我们想知道总共有多少行的word;可以使用如下 语句来完成:
- SELECT count(word) AS number FROM cet6_table;
count()函数为我们返回一个Int整形,代表有多少行数据。返回的列的名字叫count(word),为了方便阅读和处理用as number给这个列取个 别名number;
- SELECT [word],[explanation] FROM cet6_table ORDER BY word LIMIT 100 OFFSET 200"
详情见示例程序!多线程自带数据库
有些程序比如,字典,输入法等程序会在apk中带有数据库。思路很简单,把预先准备好的数据库放入asset或者raw目录当中 使用时复制到对应的手机目录上;再打开。以下代码会把raw目录中的名为cet6的数据库文件写入sd卡根目录并打开。 对于一些常用或者比较重要的数据建议放在程序的私有目录当中。
- public void init(Context context) {
- try {
- String databasePath = Environment.getExternalStorageDirectory().getAbsolutePath();
- String databaseFilename = databasePath + "/" + DATABASE_FILENAME;
- File dir = new File(databasePath);
- if (!dir.exists()){
- dir.mkdir();
- }
- if (!(new File(databaseFilename)).exists()) {
- InputStream is = context.getResources().openRawResource(
- R.raw.cet6);
- FileOutputStream fos = new FileOutputStream(databaseFilename);
- byte[] buffer = new byte[1024];
- int count = 0;
- while ((count = is.read(buffer)) > 0) {
- fos.write(buffer, 0, count);
- }
- fos.flush();
- fos.close();
- is.close();
- }
- mCet6Db = SQLiteDatabase.openOrCreateDatabase(databaseFilename,
- null);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
SQLite有很多函数支持日期的方便处理。
- %d day of month: 00
- %f fractional seconds: SS.SSS
- %H hour: 00-24
- %j day of year: 001-366
- %J Julian day number
- %m month: 01-12
- %M minute: 00-59
- %s seconds since 1970-01-01
- %S seconds: 00-59
- %w day of week 0-6 with Sunday==0
- %W week of year: 00-53
- %Y year: 0000-9999
- %% %
- YYYY-MM-DD
- YYYY-MM-DD HH:MM
- YYYY-MM-DD HH:MM:SS
- YYYY-MM-DD HH:MM:SS.SSS
- YYYY-MM-DDTHH:MM //T 就是字母T,用于分开日期和时间
- YYYY-MM-DDTHH:MM:SS
- YYYY-MM-DDTHH:MM:SS.SSS
- HH:MM
- HH:MM:SS
- HH:MM:SS.SSS
- now
- DDDDDDDDDD //is the Julian day number expressed as a floating point value.
ContentValues 不支持直接把datetime('now')之类函数作为值插入数据库。 比如想把当前系统时间插件数据库使用ContentValues:
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- Date date = new Date();
- ContentValues initialValues = new ContentValues();
- initialValues.put("date_created", dateFormat.format(date));
- long rowId = mDb.insert(DATABASE_TABLE, null, initialValues);

SqliteOpenHelper是android框架为我们提供的一个数据库助手类。对于数据库的操作一般都是从这个类继承。它主要负责数据库的创建,打开,更新 等一些操作。Singleton DAO
很多有j2ee背景的开发者都喜欢建立一个单例模式的数据库操作类,专门处理数据库之间的交流。也有很多人把这个习惯带到的Android的开发当中。 而且我们也经常需要在几个Activity,Service同时访问一个数据库文件,所以经常能看到类似于这样的代码:
- public class DbAccess {
- class DbHelper extends SQLiteOpenHelper {
- //此处代码被省略
- }
- private static DB_NAME = "users";
- private mDbHelper = null;
- private static mDbAccess;//to make sure there is only one instance exist;
-
- private DbAccess(Context context){
- //private constructer;
- if(mDbHelper == null){
- mDbHelper = new DbHelper(context,DB_NAME);
- }
- }
-
- public DbAccess getInstance(Context context){
- if(mDbAccess == null){
- mDbAccess = new DbAccess(context);
- }
- return mDbAccess;
- }
-
- //部分代码被省略
- //insert
- //delete
- //update
- //query
- }
- public class ActivityA extends Activity{
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- dao = DbAccess.getInstance(this);
- ////部分代码被省略
- }
- ////部分代码被省略
- }

1,最简单的,不使用单例模式,因为SQLiteOpenHelper保证了数据库的单例,所以实际上我们只是创建了多个SQLiteOpenHelper的对象,数据库 对象本身还是单例的。缺点:会有一些重复的代码,并生成多个SQLiteOpenHelper的子类对象。
2,把Dao对象放入Application当中,在Application的onCreate()中使用Application的Context进行初始化。优点,Application对象的创建在Activity和Service之前 所以保证了,Activity和Service等等使用时数据库已经准备好了。缺点:Application的生命周期是最长的,并且Android会尽量不让程序关闭,也就是尽量不 去销毁Application对象,所以数据库一直保持打开状态,依靠Application的onDestroy()关闭数据库,不确定的因素比较大,并且因为打开数据库的时候直接 影响程序启动时间。
3,先看一个问题,为什么SQLiteOpenHelper需要一个Context对象?查看SQLiteOpenHelper的源码发现如下代码:
- SQLiteDatabase db = null;
- try {
- mIsInitializing = true;
- String path = mContext.getDatabasePath(mName).getPath();
- db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY);
- if (db.getVersion() != mNewVersion) {
- throw new SQLiteException("Can't upgrade read-only database from version " +
- db.getVersion() + " to " + mNewVersion + ": " + path);
- }
- onOpen(db);
- Log.w(TAG, "Opened " + mName + " in read-only mode");
- mDatabase = db;
4,在创—ao对象时,不使用Activity的引用作为Context,而是把Application作为Context传入Dao的构造函数中进行创建。优点,不会影响程序的启动时间。 缺点:对于数据库的关闭还是不确定。
5,在第四种方案的基础上加入计数器。第调用getInstance计数器自增,再加入一个release()方法,计数器自减,当计数器为0时,关闭数据库(或者当计数器为零且 过一段时间没有连接时关闭)。