ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 第八天.SQLite数据库技术 ## ### 8.1 SQLite介绍 ### #### 8.1.1数据库存储 #### + 在某些情况下,文件不是有效的 + 多线程数据访问 + 需要事务处理 + 如果应用程序处理可能变化的复杂数据结构 + 数据库对于创建它们的包套件是私有的 #### 8.1.2 SQLite介绍 #### + SQLite是一个轻量级的数据库,体积大小只用几千字节 + 一些SQL的指令只是部分支持,例如:ALTER、TABLE + 广泛应用在嵌入式移动设备之上。 + 参阅http://www.sqlite.org 获取更多信息 ### 8.2 创建/打开/删除数据库 ### #### 8.2.1 创建数据库 ### ``` Context.createDatabase( String name, // int version, // int mode, // CursorFactory factory // ) ``` + 创建一个新的数据库并返回一个SQLiteDatabase对象 + 数据库不能被创建,则抛出FileNotFoundException异常 #### 8.2.2 其他创建数据库的方法 #### ``` SQLiteDatabase mydataBase=SQLiteDatabase.create(new CursorFactory(){ //创建一个数据库 //工厂类,一个可选工厂类,当查询时调用来实例化一个光标 public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery, String editTable, SQLiteQuery query) { return null; } }); SQLiteDatabase myDataBase=this.openOrCreateDatabase("myDataBase.db", MODE_PRIVATE, new CursorFactory(){ //创建新的数据库,名称myDatabase,模式MODE_PRIVATE,游标工厂 //工厂类,一个可选工厂类,当查询时调用来实例化一个光标 public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver masterQuery, String editTable, SQLiteQuery query) { return null; } }); ``` #### 8.2.3 删除数据库 #### + Context.deleteDatabase(String name) + 删除指定名称的数据库 + 假如数据库成功删除则返回true,失败则为false #### 8.2.4 打开数据库 #### + Context.openDatabase(String file,CursorFactory factory) + 打开一个存在的数据库并返回一个SQLiteDatabase 对象 + 如果数据库不存在则抛出FileNotFoundException 异常 + 如创建一个名为:myDataBase的数据库,后缀为.db ``` SQLiteDatabase my_DataBase= this.openOrCreateDatabase( "myDateBase.db", MODE_PRIVATE, null); my_DataBase.close();//不要忘记关闭数据库 ``` #### 8.2.5 非查询SQL 指令 #### ``` SQLiteDatabase.execSQL(String sql) ``` 可以用来执行非查询SQL指令,这些指令没有结果, 包括:CREATE TABLE / DROP TABLE / INSERT 等等。 ### 8.3 创建/删除表 ### #### 8.3.1 SQLite基础案例 #### ``` private SQLiteDatabase mSQLiteDatabase=null; // 打开已经存在的数据库 mSQLiteDatabase = this.openOrCreateDatabase(DATABASE_NAME, MODE_PRIVATE, null); /* 在数据库mSQLiteDatabase中创建一个表 */ mSQLiteDatabase.execSQL(CREATE_TABLE); /* 删除数据库 */ this.deleteDatabase(DATABASE_NAME); /* 退出时,不要忘记关闭 */ mSQLiteDatabase.close(); /* 删除一个表 */ mSQLiteDatabase.execSQL("DROP TABLE " + TABLE_NAME); /* 更新一条数据 */ ContentValues cv = new ContentValues(); cv.put(TABLE_NUM, miCount); cv.put(TABLE_DATA, "修改后的数据" + miCount); mSQLiteDatabase.update(TABLE_NAME, cv, TABLE_NUM + "=" + Integer.toString(miCount - 1), null); UpdataAdapter(); //更新界面 ``` ``` /* 向表中添加一条数据 */ ContentValues cv = new ContentValues(); cv.put(TABLE_NUM, miCount); cv.put(TABLE_DATA, "测试数据库数据" + miCount); mSQLiteDatabase.insert(TABLE_NAME, null, cv); miCount++; UpdataAdapter(); //更新界面 /* 从表中删除指定的一条数据 */ mSQLiteDatabase.execSQL("DELETE FROM " + TABLE_NAME + " WHERE _id=" + Integer.toString(miCount)); miCount--; if (miCount < 0){ miCount = 0; } UpdataAdapter(); //更新界面 ``` #### 8.3.2 SQLite基础案例:更新视图显示 #### ``` /* 更新视图显示 */ public void UpdataAdapter(){ // 获取数据库Phones的Cursor Cursor cur = mSQLiteDatabase.query(TABLE_NAME, new String[] { TABLE_ID, TABLE_NUM, TABLE_DATA }, null, null, null, null, null); miCount = cur.getCount(); if (cur != null && cur.getCount() >= 0) { // ListAdapter是ListView和后台数据的桥梁 ListAdapter adapter = new SimpleCursorAdapter(this, // 定义List中每一行的显示模板 // 表示每一行包含两个数据项 android.R.layout.simple_list_item_2, // 数据库的Cursor对象 cur, // 从数据库的TABLE_NUM和TABLE_DATA两列中取数据 new String[] { TABLE_NUM, TABLE_DATA }, // 与NAME和NUMBER对应的Views new int[] { android.R.id.text1, android.R.id.text2 }); /* 将adapter添加到m_ListView中 */ m_ListView.setAdapter(adapter); } } ``` 研究案例DatabaseDemo1 ### 8.4 CRUD操作 ### #### 8.4.1 查询SQL 指令-游标Cursors ### + Android 使用游标(Cursors)来导航浏览查询结果 + 游标(Cursors)被android.database.Cursor 对象来描述 + 一个游标(Cursors)是一个简单的指针,它从查询结果的一个元组跳到下一个元组(或前一个或第一个……) + 游标(Cursors)在它定位位置的那一刻返回元组数据 ``` //为创建Cursor(游标),必须执行查询,要么通过SQL使用rawQuery()方法 //或是更精心设计的方法,像query()方法 Cursor cur=my_DataBase.rawQuery("SELECT * FORM test", null); if(cur!=null){//游标不为空 //返回给定名称的列的基于0开始的index,如果该属性列不存在则返回-1 //通过它们的index来检索属性值 int numColumn=cur.getColumnIndex("someNumber"); if(cur.moveToFirst()){ //cur.moveToFirst()让游标指向第一行,如果游标指向第一行,则返回true do { int num=cur.getInt(numColumn);//获得当前行该属性的值 /*Cursor提供了不同的方法来回索不同的数据类型 例如getInt(int index)/getString(int index)等等*/ /*做一些事情*/ } while (cur.moveToNext()); /*游标移动到下一行,如果游标已经通过了结果集中的最后, 即没有行可以移动时,则返回false*/ //其他可能移动的是previous() 和first()方法 } } ``` ### 5.5 事务处理 ### #### 5.5.1 使用事务操作SQLite数据库 #### 使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果为成功则提交事务,否则回滚事务。当应用需要提交事务,必须在程序执行到endTransaction()方法之前使用setTransactionSuccessful() 方法设置事务的标志为成功,如果不调用setTransactionSuccessful() 方法,默认会回滚事务。使用例子如下: ``` SQLiteDatabase db = ....; db.beginTransaction();//开始事务 try { db.execSQL("insert into person(name, age) values(?,?)", new Object[]{“lxt008", 4}); db.execSQL("update person set name=? where personid=?", new Object[]{“lxt008", 1}); db.setTransactionSuccessful();//调用此方法会在执行到endTransaction() 时提交当前事务,如果不调用此方法会回滚事务 } finally { db.endTransaction();//由事务的标志决定是提交事务,还是回滚事务 } db.close(); ``` 上面两条SQL语句在同一个事务中执行。 **其他** + 数据库辅助类 + 研究案例DatabaseDemo2 + 数据库小工具 Sqlitebrowser可以简单管理Sqlite数据库 [示例下载](http://www.apkbus.com/android-83441-1-1.html)