Android中SQLite使用方法

上传人:bei****lei 文档编号:203897154 上传时间:2023-04-25 格式:DOCX 页数:23 大小:165.34KB
收藏 版权申诉 举报 下载
Android中SQLite使用方法_第1页
第1页 / 共23页
Android中SQLite使用方法_第2页
第2页 / 共23页
Android中SQLite使用方法_第3页
第3页 / 共23页
资源描述:

《Android中SQLite使用方法》由会员分享,可在线阅读,更多相关《Android中SQLite使用方法(23页珍藏版)》请在装配图网上搜索。

1、Android中SQLite使用方法 分享一下在Android中如何使用SQLite。现在的主流移动设备像Android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储我们大量的数据,所以我们就需要掌握移动设备上的SQLite开发技巧。对于Android平台来说,系统内置了丰富的API来供开发人员操作SQLite,我们可以轻松的完成对数据的存取。下面就向大家介绍一下SQLite常用的操作方法,为了方便,我将代码写在了Activity的onCreate中:java view plaincopyprint?1. Overri

2、de 2. protected void onCreate(Bundle savedInstanceState) 3. super.onCreate(savedInstanceState); 4.5. /打开或创建test.db数据库 6. SQLiteDatabase db = openOrCreateDatabase(test.db, Context.MODE_PRIVATE, null); 7. db.execSQL(DROP TABLE IF EXISTS person); 8. /创建person表 9. db.execSQL(CREATE TABLE person (_id INT

3、EGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age SMALLINT); 10. Person person = new Person(); 11. person.name = john; 12. person.age = 30; 13. /插入数据 14. db.execSQL(INSERT INTO person VALUES (NULL, ?, ?), new Objectperson.name, person.age); 15.16. person.name = david; 17. person.age = 33; 18. /Conte

4、ntValues以键值对的形式存放数据 19. ContentValues cv = new ContentValues(); 20. cv.put(name, person.name); 21. cv.put(age, person.age); 22. /插入ContentValues中的数据 23. db.insert(person, null, cv); 24.25. cv = new ContentValues(); 26. cv.put(age, 35); 27. /更新数据 28. db.update(person, cv, name = ?, new Stringjohn); 2

5、9.30. Cursor c = db.rawQuery(SELECT * FROM person WHERE age = ?, new String33); 31. while (c.moveToNext() 32. int _id = c.getInt(c.getColumnIndex(_id); 33. String name = c.getString(c.getColumnIndex(name); 34. int age = c.getInt(c.getColumnIndex(age); 35. Log.i(db, _id= + _id + , name= + name + , ag

6、e= + age); 36. 37. c.close(); 38.39. /删除数据 40. db.delete(person, age = ?, new String33);while (c.moveToNext() int _id = c.getInt(c.getColumnIndex(_id);String name = c.getString(c.getColumnIndex(name);int age = c.getInt(c.getColumnIndex(age);Log.i(db, _id= + _id + , name= + name + , age= + age);c.clo

7、se();/删除数据db.delete(person, age ? and age ?”等,最后的whereArgs参数是占位符的实际参数值;delete方法的参数也是一样。下面来说说查询操作。查询操作相对于上面的几种操作要复杂些,因为我们经常要面对着各种各样的查询条件,所以系统也考虑到这种复杂性,为我们提供了较为丰富的查询形式:java view plaincopyprint?1. db.rawQuery(String sql, String selectionArgs); 2. db.query(String table, String columns, String selection,

8、 String selectionArgs, String groupBy, String having, String orderBy); 3. db.query(String table, String columns, String selection, String selectionArgs, String groupBy, String having, String orderBy, String limit); 4. db.query(String distinct, String table, String columns, String selection, String s

9、electionArgs, String groupBy, String having, String orderBy, String limit); db.rawQuery(String sql, String selectionArgs);db.query(String table, String columns, String selection, String selectionArgs, String groupBy, String having, String orderBy);db.query(String table, String columns, String select

10、ion, String selectionArgs, String groupBy, String having, String orderBy, String limit);db.query(String distinct, String table, String columns, String selection, String selectionArgs, String groupBy, String having, String orderBy, String limit);上面几种都是常用的查询方法,第一种最为简单,将所有的SQL语句都组织到一个字符串中,使用占位符代替实际参数,s

11、electionArgs就是占位符实际参数集;下面的几种参数都很类似,columns表示要查询的列所有名称集,selection表示WHERE之后的条件语句,可以使用占位符,groupBy指定分组的列名,having指定分组条件,配合groupBy使用,orderBy指定排序的列名,limit指定分页参数,distinct可以指定“true”或“false”表示要不要过滤重复值。需要注意的是,selection、groupBy、having、orderBy、limit这几个参数中不包括“WHERE”、“GROUP BY”、“HAVING”、“ORDER BY”、“LIMIT”等SQL关键字。最

12、后,他们同时返回一个Cursor对象,代表数据集的游标,有点类似于JavaSE中的ResultSet。下面是Cursor对象的常用方法:java view plaincopyprint?1. c.move(int offset); /以当前位置为参考,移动到指定行 2. c.moveToFirst(); /移动到第一行 3. c.moveToLast(); /移动到最后一行 4. c.moveToPosition(int position); /移动到指定行 5. c.moveToPrevious(); /移动到前一行 6. c.moveToNext(); /移动到下一行 7. c.isFir

13、st(); /是否指向第一条 8. c.isLast(); /是否指向最后一条 9. c.isBeforeFirst(); /是否指向第一条之前 10. c.isAfterLast(); /是否指向最后一条之后 11. c.isNull(int columnIndex); /指定列是否为空(列基数为0) 12. c.isClosed(); /游标是否已关闭 13. c.getCount(); /总数据项数 14. c.getPosition(); /返回当前游标所指向的行数 15. c.getColumnIndex(String columnName);/返回某列名对应的列索引值 16. c.

14、getString(int columnIndex); /返回当前行指定列的值 c.move(int offset);/以当前位置为参考,移动到指定行c.moveToFirst();/移动到第一行c.moveToLast();/移动到最后一行c.moveToPosition(int position);/移动到指定行c.moveToPrevious();/移动到前一行c.moveToNext();/移动到下一行c.isFirst();/是否指向第一条c.isLast();/是否指向最后一条c.isBeforeFirst();/是否指向第一条之前c.isAfterLast();/是否指向最后一条

15、之后c.isNull(int columnIndex);/指定列是否为空(列基数为0)c.isClosed();/游标是否已关闭c.getCount();/总数据项数c.getPosition();/返回当前游标所指向的行数c.getColumnIndex(String columnName);/返回某列名对应的列索引值c.getString(int columnIndex);/返回当前行指定列的值在上面的代码示例中,已经用到了这几个常用方法中的一些,关于更多的信息,大家可以参考官方文档中的说明。最后当我们完成了对数据库的操作后,记得调用SQLiteDatabase的close()方法释放数据

16、库连接,否则容易出现SQLiteException。上面就是SQLite的基本应用,但在实际开发中,为了能够更好的管理和维护数据库,我们会封装一个继承自SQLiteOpenHelper类的数据库操作类,然后以这个类为基础,再封装我们的业务逻辑方法。下面,我们就以一个实例来讲解具体的用法,我们新建一个名为db的项目,结构如下:其中DBHelper继承了SQLiteOpenHelper,作为维护和管理数据库的基类,DBManager是建立在DBHelper之上,封装了常用的业务方法,Person是我们的person表对应的JavaBean,MainActivity就是我们显示的界面。下面我们先来看

17、一下DBHelper:java view plaincopyprint?1. package com.scott.db; 2.3. import android.content.Context; 4. import android.database.sqlite.SQLiteDatabase; 5. import android.database.sqlite.SQLiteOpenHelper; 6.7. public class DBHelper extends SQLiteOpenHelper 8.9. private static final String DATABASE_NAME =

18、 test.db; 10. private static final int DATABASE_VERSION = 1; 11.12. public DBHelper(Context context) 13. /CursorFactory设置为null,使用默认值 14. super(context, DATABASE_NAME, null, DATABASE_VERSION); 15. 16.17. /数据库第一次被创建时onCreate会被调用 18. Override 19. public void onCreate(SQLiteDatabase db) 20. db.execSQL(C

19、REATE TABLE IF NOT EXISTS person + 21. (_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, info TEXT); 22. 23.24. /如果DATABASE_VERSION值被改为2,系统发现现有数据库版本不同,即会调用onUpgrade 25. Override 26. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 27. db.execSQL(ALTER TABLE p

20、erson ADD COLUMN other STRING); 28. 29. package com.scott.db;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;public class DBHelper extends SQLiteOpenHelper private static final String DATABASE_NAME = test.db;private static

21、final int DATABASE_VERSION = 1;public DBHelper(Context context) /CursorFactory设置为null,使用默认值super(context, DATABASE_NAME, null, DATABASE_VERSION);/数据库第一次被创建时onCreate会被调用Overridepublic void onCreate(SQLiteDatabase db) db.execSQL(CREATE TABLE IF NOT EXISTS person +(_id INTEGER PRIMARY KEY AUTOINCREMENT

22、, name VARCHAR, age INTEGER, info TEXT);/如果DATABASE_VERSION值被改为2,系统发现现有数据库版本不同,即会调用onUpgradeOverridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) db.execSQL(ALTER TABLE person ADD COLUMN other STRING);正如上面所述,数据库第一次创建时onCreate方法会被调用,我们可以执行创建表的语句,当系统发现版本变化之后,会调用onUpgrade方法,我

23、们可以执行修改表结构等语句。为了方便我们面向对象的使用数据,我们建一个Person类,对应person表中的字段,如下:java view plaincopyprint?1. package com.scott.db; 2.3. public class Person 4. public int _id; 5. public String name; 6. public int age; 7. public String info; 8.9. public Person() 10. 11.12. public Person(String name, int age, String info)

24、13. this.name = name; 14. this.age = age; 15. this.info = info; 16. 17. package com.scott.db;public class Person public int _id;public String name;public int age;public String info;public Person() public Person(String name, int age, String info) this.name = name;this.age = age;this.info = info;然后,我们

25、需要一个DBManager,来封装我们所有的业务方法,代码如下:java view plaincopyprint?1. package com.scott.db; 2.3. import java.util.ArrayList; 4. import java.util.List; 5.6. import android.content.ContentValues; 7. import android.content.Context; 8. import android.database.Cursor; 9. import android.database.sqlite.SQLiteDataba

26、se; 10.11. public class DBManager 12. private DBHelper helper; 13. private SQLiteDatabase db; 14.15. public DBManager(Context context) 16. helper = new DBHelper(context); 17. /因为getWritableDatabase内部调用了mContext.openOrCreateDatabase(mName, 0, mFactory); 18. /所以要确保context已初始化,我们可以把实例化DBManager的步骤放在Act

27、ivity的onCreate里 19. db = helper.getWritableDatabase(); 20. 21.22. /* 23. * add persons 24. * param persons 25. */ 26. public void add(List persons) 27. db.beginTransaction(); /开始事务 28. try 29. for (Person person : persons) 30. db.execSQL(INSERT INTO person VALUES(null, ?, ?, ?), new Objectperson.nam

28、e, person.age, person.info); 31. 32. db.setTransactionSuccessful(); /设置事务成功完成 33. finally 34. db.endTransaction(); /结束事务 35. 36. 37.38. /* 39. * update persons age 40. * param person 41. */ 42. public void updateAge(Person person) 43. ContentValues cv = new ContentValues(); 44. cv.put(age, person.ag

29、e); 45. db.update(person, cv, name = ?, new Stringperson.name); 46. 47.48. /* 49. * delete old person 50. * param person 51. */ 52. public void deleteOldPerson(Person person) 53. db.delete(person, age = ?, new StringString.valueOf(person.age); 54. 55.56. /* 57. * query all persons, return list 58. *

30、 return List 59. */ 60. public List query() 61. ArrayList persons = new ArrayList(); 62. Cursor c = queryTheCursor(); 63. while (c.moveToNext() 64. Person person = new Person(); 65. person._id = c.getInt(c.getColumnIndex(_id); 66. person.name = c.getString(c.getColumnIndex(name); 67. person.age = c.

31、getInt(c.getColumnIndex(age); 68. person.info = c.getString(c.getColumnIndex(info); 69. persons.add(person); 70. 71. c.close(); 72. return persons; 73. 74.75. /* 76. * query all persons, return cursor 77. * return Cursor 78. */ 79. public Cursor queryTheCursor() 80. Cursor c = db.rawQuery(SELECT * F

32、ROM person, null); 81. return c; 82. 83.84. /* 85. * close database 86. */ 87. public void closeDB() 88. db.close(); 89. 90. package com.scott.db;import java.util.ArrayList;import java.util.List;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import

33、 android.database.sqlite.SQLiteDatabase;public class DBManager private DBHelper helper;private SQLiteDatabase db;public DBManager(Context context) helper = new DBHelper(context);/因为getWritableDatabase内部调用了mContext.openOrCreateDatabase(mName, 0, mFactory);/所以要确保context已初始化,我们可以把实例化DBManager的步骤放在Activ

34、ity的onCreate里db = helper.getWritableDatabase();/* * add persons * param persons */public void add(List persons) db.beginTransaction();/开始事务 try for (Person person : persons) db.execSQL(INSERT INTO person VALUES(null, ?, ?, ?), new Objectperson.name, person.age, person.info); db.setTransactionSuccess

35、ful();/设置事务成功完成 finally db.endTransaction();/结束事务 /* * update persons age * param person */public void updateAge(Person person) ContentValues cv = new ContentValues();cv.put(age, person.age);db.update(person, cv, name = ?, new Stringperson.name);/* * delete old person * param person */public void de

36、leteOldPerson(Person person) db.delete(person, age = ?, new StringString.valueOf(person.age);/* * query all persons, return list * return List */public List query() ArrayList persons = new ArrayList();Cursor c = queryTheCursor(); while (c.moveToNext() Person person = new Person(); person._id = c.get

37、Int(c.getColumnIndex(_id); person.name = c.getString(c.getColumnIndex(name); person.age = c.getInt(c.getColumnIndex(age); person.info = c.getString(c.getColumnIndex(info); persons.add(person); c.close(); return persons;/* * query all persons, return cursor * returnCursor */public Cursor queryTheCurs

38、or() Cursor c = db.rawQuery(SELECT * FROM person, null); return c;/* * close database */public void closeDB() db.close();我们在DBManager构造方法中实例化DBHelper并获取一个SQLiteDatabase对象,作为整个应用的数据库实例;在添加多个Person信息时,我们采用了事务处理,确保数据完整性;最后我们提供了一个closeDB方法,释放数据库资源,这一个步骤在我们整个应用关闭时执行,这个环节容易被忘记,所以朋友们要注意。我们获取数据库实例时使用了getWri

39、tableDatabase()方法,也许朋友们会有疑问,在getWritableDatabase()和getReadableDatabase()中,你为什么选择前者作为整个应用的数据库实例呢?在这里我想和大家着重分析一下这一点。我们来看一下SQLiteOpenHelper中的getReadableDatabase()方法:java view plaincopyprint?1. public synchronized SQLiteDatabase getReadableDatabase() 2. if (mDatabase != null & mDatabase.isOpen() 3. / 如果

40、发现mDatabase不为空并且已经打开则直接返回 4. return mDatabase; 5. 6.7. if (mIsInitializing) 8. / 如果正在初始化则抛出异常 9. throw new IllegalStateException(getReadableDatabase called recursively); 10. 11.12. / 开始实例化数据库mDatabase 13.14. try 15. / 注意这里是调用了getWritableDatabase()方法 16. return getWritableDatabase(); 17. catch (SQLit

41、eException e) 18. if (mName = null) 19. throw e; / Cant open a temp database read-only! 20. Log.e(TAG, Couldnt open + mName + for writing (will try read-only):, e); 21. 22.23. / 如果无法以可读写模式打开数据库 则以只读方式打开 24.25. SQLiteDatabase db = null; 26. try 27. mIsInitializing = true; 28. String path = mContext.g

42、etDatabasePath(mName).getPath();/ 获取数据库路径 29. / 以只读方式打开数据库 30. db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY); 31. if (db.getVersion() != mNewVersion) 32. throw new SQLiteException(Cant upgrade read-only database from version + db.getVersion() + to 33. + mNewVersion +

43、 : + path); 34. 35.36. onOpen(db); 37. Log.w(TAG, Opened + mName + in read-only mode); 38. mDatabase = db;/ 为mDatabase指定新打开的数据库 39. return mDatabase;/ 返回打开的数据库 40. finally 41. mIsInitializing = false; 42. if (db != null & db != mDatabase) 43. db.close(); 44. 45. public synchronized SQLiteDatabase ge

44、tReadableDatabase() if (mDatabase != null & mDatabase.isOpen() / 如果发现mDatabase不为空并且已经打开则直接返回return mDatabase;if (mIsInitializing) / 如果正在初始化则抛出异常throw new IllegalStateException(getReadableDatabase called recursively);/ 开始实例化数据库mDatabasetry / 注意这里是调用了getWritableDatabase()方法return getWritableDatabase()

45、; catch (SQLiteException e) if (mName = null)throw e; / Cant open a temp database read-only!Log.e(TAG, Couldnt open + mName + for writing (will try read-only):, e);/ 如果无法以可读写模式打开数据库 则以只读方式打开SQLiteDatabase db = null;try mIsInitializing = true;String path = mContext.getDatabasePath(mName).getPath();/

46、获取数据库路径/ 以只读方式打开数据库db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY);if (db.getVersion() != mNewVersion) throw new SQLiteException(Cant upgrade read-only database from version + db.getVersion() + to + mNewVersion + : + path);onOpen(db);Log.w(TAG, Opened + mName + in read

47、-only mode);mDatabase = db;/ 为mDatabase指定新打开的数据库return mDatabase;/ 返回打开的数据库 finally mIsInitializing = false;if (db != null & db != mDatabase)db.close();在getReadableDatabase()方法中,首先判断是否已存在数据库实例并且是打开状态,如果是,则直接返回该实例,否则试图获取一个可读写模式的数据库实例,如果遇到磁盘空间已满等情况获取失败的话,再以只读模式打开数据库,获取数据库实例并返回,然后为mDatabase赋值为最新打开的数据库实

48、例。既然有可能调用到getWritableDatabase()方法,我们就要看一下了:java view plaincopyprint?1. public synchronized SQLiteDatabase getWritableDatabase() 2. if (mDatabase != null & mDatabase.isOpen() & !mDatabase.isReadOnly() 3. / 如果mDatabase不为空已打开并且不是只读模式 则返回该实例 4. return mDatabase; 5. 6.7. if (mIsInitializing) 8. throw new

49、 IllegalStateException(getWritableDatabase called recursively); 9. 10.11. / If we have a read-only database open, someone could be using it 12. / (though they shouldnt), which would cause a lock to be held on 13. / the file, and our attempts to open the database read-write would 14. / fail waiting f

50、or the file lock. To prevent that, we acquire the 15. / lock on the read-only database, which shuts out other users. 16.17. boolean success = false; 18. SQLiteDatabase db = null; 19. / 如果mDatabase不为空则加锁 阻止其他的操作 20. if (mDatabase != null) 21. mDatabase.lock(); 22. try 23. mIsInitializing = true; 24.

51、if (mName = null) 25. db = SQLiteDatabase.create(null); 26. else 27. / 打开或创建数据库 28. db = mContext.openOrCreateDatabase(mName, 0, mFactory); 29. 30. / 获取数据库版本(如果刚创建的数据库,版本为0) 31. int version = db.getVersion(); 32. / 比较版本(我们代码中的版本mNewVersion为1) 33. if (version != mNewVersion) 34. db.beginTransaction();/ 开始事务 35. try 36. if (version = 0) 37. / 执行我们的onCreate方法 38. onCreate(db); 39. else 40. / 如果我们应用升级了mNewVersion为2,而原版本为1则执行onUpgrade方法 41. onUpgrade

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!