1.前言
Sqlite是一款轻量级的关系型数据库,占用资源少,预算速度快,跨平台(支持android,IOS,window系统),弱类型(同一列中的数据可以是不同字段),非常适合资源较少的移动端开发。
2.数据库的创建
(1)android提供了SQLiteOpenHelper这个帮助类实现数据库的创建和升级,SQLiteOpenHelpe是一个抽象类,必需实现这个类.
public class DbOpenHelper1 extends SQLiteOpenHelper {
public DbOpenHelper1(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
}
}
SQLiteOpenHelper的构造方法的第二个参数(name)表示数据库名称,第四个参数(version)表示当前数据库的版本号。
SQLiteOpenHelper有两个重要方法onCreate和onUpgrade。
onCreate方法只有在创建数据库的时候会执行,所以一般在方法里实现表的创建。
onUpgrade方法实现数据库的升级。第二个oldVersion表示之前的数据库版本,newVersion表示当前版本。通过版本的不同可以实现数据库的升级
(2)在SQLiteOpenHelper的构造方法中传入的数据库名,其实数据库不是在这里创建。SQLiteOpenHelper提供了两个重要的方法getReadableDatabase和getWritableDatabase。
调用SQLiteOpenHelper的这两个方法才会创建或者打开(已有)一个数据库,并返回SQLiteDatabase对象(数据库操作类,实现了操作数据库的一些方法)。
下面是SQLiteDatabase的常用方法
SQLiteDatabase的常用方法
SQLiteDatabse是数据库操作的核心类。可以看到openOrCreateDatabase(path,factory)实现了打开或创建数据库。当调用SQLiteOpenHelper的getReadableDatabase和getWritableDatabase方法时,这两个方法的内部是通过调用SQLiteDatabase的openDatabase方法实现数据库的创建或打开的。看下这两个方法的源码。
SQLiteOpenHelper的源码:
185 public SQLiteDatabase More ...getReadableDatabase() {
186 synchronized (this) {
187 return getDatabaseLocked(false);
188 }
189 }
161 public SQLiteDatabase More ...getWritableDatabase() {
162 synchronized (this) {
163 return getDatabaseLocked(true);
164 }
165 }
他们都调用了getDatabaseLoced(boolen),看下这个方法的源码:
191 private SQLiteDatabase More ...getDatabaseLocked(boolean writable) {
192 if (mDatabase != null) {
193 if (!mDatabase.isOpen()) {
194 // Darn! The user closed the database by calling mDatabase.close().
195 mDatabase = null;
196 } else if (!writable || !mDatabase.isReadOnly()) {
197 // The database is already open for business.
198 return mDatabase;
199 }
200 }
201
202 if (mIsInitializing) {
203 throw new IllegalStateException("getDatabase called recursively");
204 }
205
206 SQLiteDatabase db = mDatabase;
207 try {
208 mIsInitializing = true;
209
210 if (db != null) {
211 if (writable && db.isReadOnly()) {
212 db.reopenReadWrite();
213 }
214 } else if (mName == null) {
215 db = SQLiteDatabase.create(null);
216 } else {
217 try {
218 if (DEBUG_STRICT_READONLY && !writable) {
219 final String path = mContext.getDatabasePath(mName).getPath();
220 db = SQLiteDatabase.openDatabase(path, mFactory,
221 SQLiteDatabase.OPEN_READONLY, mErrorHandler);
222 } else {
223 db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
224 Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
225 mFactory, mErrorHandler);
226 }
227 } catch (SQLiteException ex) {
228 if (writable) {
229 throw ex;
230 }
231 Log.e(TAG, "Couldn't open " + mName
232 + " for writing (will try read-only):", ex);
233 final String path = mContext.getDatabasePath(mName).getPath();
234 db = SQLiteDatabase.openDatabase(path, mFactory,
235 SQLiteDatabase.OPEN_READONLY, mErrorHandler);
236 }
237 }
238
239 onConfigure(db);
240
241 final int version = db.getVersion();
242 if (version != mNewVersion) {
243 if (db.isReadOnly()) {
244 throw new SQLiteException("Can't upgrade read-only database from version " +
245 db.getVersion() + " to " + mNewVersion + ": " + mName);
246 }
247
248 db.beginTransaction();
249 try {
250 if (version == 0) {
251 onCreate(db);
252 } else {
253 if (version > mNewVersion) {
254 onDowngrade(db, version, mNewVersion);
255 } else {
256 onUpgrade(db, version, mNewVersion);
257 }
258 }
259 db.setVersion(mNewVersion);
260 db.setTransactionSuccessful();
261 } finally {
262 db.endTransaction();
263 }
264 }
265
266 onOpen(db);
267
268 if (db.isReadOnly()) {
269 Log.w(TAG, "Opened " + mName + " in read-only mode");
270 }
271
272 mDatabase = db;
273 return db;
274 } finally {
275 mIsInitializing = false;
276 if (db != null && db != mDatabase) {
277 db.close();
278 }
279 }
280 }
代码的218—225行,当数据库是可读状态时,调用了SQLiteDatabase.openDatabase)方法创建一个SQLiteDatabse。可写时通过Context的openOrCreateDatabase方法创建了SQLitedatabase,而该方法调用了SQLiteDatabase的openOrCreateDatabase。代码中的mName就是SQLiteOpenHelper传入的数据库名称。
看下SQLiteDatabase的源码:
714
715 public static SQLiteDatabase More ...openOrCreateDatabase(String path, CursorFactory factory,
716 DatabaseErrorHandler errorHandler) {
717 return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler);
718 }
可以看到openOrCreateDatabase其实也是调用了openDatabase这个方法。
691 public static SQLiteDatabase More ...openDatabase(String path, CursorFactory factory, int flags,
692 DatabaseErrorHandler errorHandler) {
693 SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler);
694 db.open();
695 return db;
696 }
在openDatabase方法中调用了SQLiteDatanase的构造函数,在SQLIteDatabse实现了数据库的创建,并返回SQLitedatabse这个数据库管理类。所以是通过SQLiteDatabase的openDatabase方法实现了数据库的创建,而openOrCreateDatabase调用了这个方法,也可以通过openOrCreateDatabase创建并打开一个数据库。
在看下SQLiteOpenHelper代码的第241—264行。version = db.getVersion()返回了当前数据库的版本,而mNewVersion) 这是在SQLiteOPenHelper传入的版本。当version 为0时,即创建数据库时调用onCreate(db);方法,而当version > mNewVersion时,当前版本大于新的版本时,调用了 onDowngrade(db, version, mNewVersion);这个可以实现数据库的回溯。当mNewVersion> Version调用了 onUpgrade(db, version, mNewVersion);实现数据库的升级。db.setVersion(mNewVersion);方法记入了新的版本号。
SQLiteDatabase不仅可以创建数据库,还实现了增删改查的基本SQL操作。提供了两种对数据的操作,一种是通过封装的方法insert,delete,query,update实现增删改查,还有一种通过execSQL执行sql语句。
3.封装
(1)可以看到不管是getReadableDatabase和getWritableDatabase方法调用getDatabaseLocked时都通过synchronized实现了数据库操作的锁,当创建SQLiteOpenHelper对象时可以通过单例模式实现数据库操作的同步。
SQLiteOpenHelper继承类。
public class DbOpenHelper extends SQLiteOpenHelper {
private static DbOpenHelper instance;
private static final String DATABSE_NAME = "student_manager"; //数据库名称
// private static final int DATABASE_VERSION = 1;
private static final int DATABASE_VERSION = 2;
public static DbOpenHelper getInstance(Context context){
if(instance == null){
synchronized (DbOpenHelper.class){
if(instance == null){
instance = new DbOpenHelper(context);
}
}
}
return instance;
}
/*
学生表
*/
private static final String STUDENT = "CREATE TABLE student"+
"(student_id INTEGER PRIMARY KEY AUTOINCREMENT," +
"name VARCHAR," +
"sex VARCHAR)";
/*
成绩表
*/
private static final String SUBJECT = "CREATE TABLE subject"+
"(subject_id INTEGER PRIMARY KEY AUTOINCREMENT," +
"sub_name VARCHAR," +
"score FLOAT)";
public DbOpenHelper(Context context) {
super(context, DATABSE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) { //创建数据库
sqLiteDatabase.execSQL(STUDENT); //创建学生表
sqLiteDatabase.execSQL(SUBJECT); //成績表
}
/*
数据库表更新创建成绩表
*/
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) { //数据库表更新
if(oldVersion < 2){
sqLiteDatabase.execSQL(SUBJECT);
}
}
}
在onCreate方法中可以创建数据库时要创建的表,在onUpgrade方法中,当数据库要升级,可以创建新的表。
创建了一个student_manager数据库,有两个表student和subject表。当数据库版本是1时创建了student(在onCreate)执行。当数据库版本为2时,增加了subject表(在onUpgrade)执行。
(2)表的操作
public class SqliteManager {
private DbOpenHelper mOpenHelper;
private SQLiteDatabase sqLiteDatabase;
public void open(Context context){
mOpenHelper = DbOpenHelper.getInstance(context);
sqLiteDatabase = mOpenHelper.getWritableDatabase();
}
public void close(){
mOpenHelper.close();
}
//---------------------------------学生表操作-------------------------------------
public synchronized long insertStudent(String name,String sex){
ContentValues contentValues = new ContentValues();
contentValues.put("name",name);
contentValues.put("sex",sex);
return sqLiteDatabase.insert(SqliteUtil.student_table,null,contentValues);
}
public Cursor selectStudent(String name){
Cursor cursor = sqLiteDatabase.rawQuery("select * from student where name=?",new String[]{name});
return cursor;
}
public void updateStudent(String id,String name,String sex){
ContentValues contentValues = new ContentValues();
contentValues.put("name",name);
contentValues.put("sex",sex);
sqLiteDatabase.update(SqliteUtil.student_table,contentValues,"student_id=?",new String[]{id});
}
}
(3)方法调用
Student表中插入一条数据
SqliteManager sqliteManager = new SqliteManager();
sqliteManager.open(getApplicationContext());
sqliteManager.insertStudent("张三","男");
sqliteManager.close();
资源地址点击打开链接