前言:勤奋的男人和爱笑的女人一般运气都不会太差
感觉好久没写博客了,这段时间一直在摸搜自己写个数据库框架,还是写到了一点点,肯定是要等到年后才能写完,今天就写个sqlite入门以及ORM概念以及底层使用了什么技术!
android上自带了一个数据库sqlite,而不像做后台那样需要使用到什么mysql,oracle,牛逼的谷歌工程师已经帮我们内置了一个轻量级的sqlite数据库,并给我们提供了api去操作,关于更多的介绍我就不说了,用了都说好,哈哈,好像ios中数据库也是这么弄的.
今天的知识图:
现在创建一个android项目叫sqlite,来演示数据库基本的操作:
数据库怎么产生的
要想在android创建一个数据库比如xxx.db,在android给我们提供了一个类SQLiteOpenHelper,这个类就是帮助我们来创建一个数据库文件的,如下:
package com.sqlite; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * Created by admin on 2017/1/22. */ public class DBHelper extends SQLiteOpenHelper { public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } /** * @param context 上下文 * @param name 数据库名称 * @param version 数据库版本号 */ public DBHelper(Context context, String name, int version){ this(context, name, null, version); } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }使用:
package com.sqlite; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DBHelper dbHelper = new DBHelper(this,"user.db",1); } }我们运行后去data/data/包名/数据库文件 去这个目录下查找你刚才创建的数据库.在studio中怎么去查找创建的数据库文件名:
点击Android Device Monitor后,
查找创建的数据库文件名:
你会发现数据库并没有创建成功,哦,哪可能是我没有在Oncreate()方法中创建表了,于是我在onCreate()把创建表的数据语句写好了,
@Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS user(personid integer primary key autoincrement, name varchar(20), age INTEGER)"); }于是我又运行下,发现数据库文件还是没创建成功,后来又插入数据到数据库中,发现数据库终于创建成功了!
/** * @param values */ public synchronized void insert(ContentValues values){ //获取SQLiteDatabase实例 SQLiteDatabase db = getWritableDatabase(); //插入数据库中 db.insert("user", null, values); db.close();//记得一定要关闭 }上层调用:
package com.sqlite; import android.content.ContentValues; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DBHelper dbHelper = new DBHelper(this,"user.db",2); ContentValues contentValues = new ContentValues(); contentValues.put("name","zhouguizhi"); contentValues.put("age",18); dbHelper.insert(contentValues); } }在DDMS中去查看数据库文件是否成功!
总结:
不是写一个类去继承SQLiteOpenHelper或者在其onCreate()方法中创建表就代表数据库文件创建成功了,必须要对数据库进行增删改的操作,数据库文件才能创建成功.
现在看下SQLiteOpenHelper帮助类有哪些方法:
方法不多,把主要的方法介绍下:
public String getDatabaseName() 获取数据库的名字
public abstract void onCreate(SQLiteDatabase db)创建数据库时调用,如果数据库已经创建了则不在调用,这点和Activity的OnCreate()方法类似,一般用于创建表的逻辑在onCreate()方法
public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)数据库升级的时候调用,
参数说明:
db:底层操作数据库的具体类
oldVersion:数据库的久版本
newVersion:数据库的新版本 (升级的根据就是和上面的数据进行对比来判断数据库是否升级)
下面2个重要的方法:
public SQLiteDatabase getReadableDatabase()
public SQLiteDatabase getWritableDatabase()
进入这个2个方法的源码:
public SQLiteDatabase getWritableDatabase() { synchronized (this) { return getDatabaseLocked(true); } }
public SQLiteDatabase getReadableDatabase() { synchronized (this) { return getDatabaseLocked(false); } }你会发现都是调用了getDatabaseLocked()方法只是传递的boolean值不一样,看下getDatabaseLocked()方法的源码如下
private SQLiteDatabase getDatabaseLocked(boolean writable) { if (mDatabase != null) { //判断SQLiteDatabase实例对象是否为null if (!mDatabase.isOpen()) {//判断对象是否打开 // Darn! The user closed the database by calling mDatabase.close(). mDatabase = null;//没有被打开这时候SQLiteDatabase就赋值为null了 } else if (!writable || !mDatabase.isReadOnly()) {//writable是上面方法的形参表示是否可写 // The database is already open for business. return mDatabase; } } if (mIsInitializing) { throw new IllegalStateException("getDatabase called recursively"); } SQLiteDatabase db = mDatabase; try { mIsInitializing = true;//走到这里表示已经初始化了 if (db != null) { if (writable && db.isReadOnly()) { db.reopenReadWrite(); } } else if (mName == null) { db = SQLiteDatabase.create(null); } else { try { if (DEBUG_STRICT_READONLY && !writable) {// 可写 final String path = mContext.getDatabasePath(mName).getPath();获取数据库的路径 db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY, mErrorHandler);打开数据库 } else { //可读
//在已创建的数据库路径下进行数据库读操作 db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ? Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0, mFactory, mErrorHandler); } } catch (SQLiteException ex) {//当在可读时发生错误还是会在data/data/文件下创建数据库对象 if (writable) { throw ex; } Log.e(TAG, "Couldn't open " + mName + " for writing (will try read-only):", ex); final String path = mContext.getDatabasePath(mName).getPath(); db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY, mErrorHandler); } } onConfigure(db); final int version = db.getVersion(); if (version != mNewVersion) {//数据库版本号对比 if (db.isReadOnly()) { throw new SQLiteException("Can't upgrade read-only database from version " + db.getVersion() + " to " + mNewVersion + ": " + mName); } db.beginTransaction();//开启事务 try { if (version == 0) { onCreate(db); } else { if (version > mNewVersion) { onDowngrade(db, version, mNewVersion); } else { onUpgrade(db, version, mNewVersion); } } db.setVersion(mNewVersion); db.setTransactionSuccessful(); } finally { db.endTransaction();//关闭事务 } } onOpen(db); if (db.isReadOnly()) { Log.w(TAG, "Opened " + mName + " in read-only mode"); } mDatabase = db; return db; } finally { mIsInitializing = false; if (db != null && db != mDatabase) { db.close(); } } }
public SQLiteDatabase getWritableDatabase() 以只写的方式返回或者创建一个操作数据库类SQLiteDatabase
public SQLiteDatabase getReadableDatabase() 以只读的方式返回或者创建一个操作数据库类SQLiteDatabase
同时通过上面的代码我们也观察到sqlite数据库也是支持事务的
如何改变数据库创建存放的路径