android SQlite 详解

来源:互联网 发布:旁白配音生成软件 编辑:程序博客网 时间:2024/05/19 05:32

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的常用方法 

方法名称
方法表示含义
openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory  factory)
打开或创建数据库
insert(String table,String nullColumnHack,ContentValues  values)
插入一条记录
delete(String table,String whereClause,String[]  whereArgs)
删除一条记录
query(String table,String[] columns,String selection,String[]  selectionArgs,String groupBy,String having,String  orderBy)
查询一条记录
update(String table,ContentValues values,String whereClause,String[]  whereArgs)
修改记录
execSQL(String sql)
执行一条SQL语句
close()
关闭数据库

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        }201202        if (mIsInitializing) {203            throw new IllegalStateException("getDatabase called recursively");204        }205206        SQLiteDatabase db = mDatabase;207        try {208            mIsInitializing = true;209210            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 " + mName232                            + " 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            }238239            onConfigure(db);240241            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                }247248                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            }265266            onOpen(db);267268            if (db.isReadOnly()) {269                Log.w(TAG, "Opened " + mName + " in read-only mode");270            }271272            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();

资源地址点击打开链接

   

0 0
原创粉丝点击