android系统内置了数据库,SQLite做为一种轻量级的关系型数据库,它的运算速度很是快。占用资源不多,一般只须要几百k的内存就足够了,以前多介绍的两种方式只适合去存储一些简单的数据和键值对,当蓄呀存储大量的复杂的关系型数据的时候,就会发现以上两种存储方式很难应付。下面开始介绍在android中如何使用SQLite数据库。java
1 建立数据库android
android为了让咱们更加方便的管理数据库,专门为咱们提供了一个SQLiteOpenHelper帮助类,借助这个类就能够很是简单的对数据库尽享建立和升级,下面我主要介绍一下这个类的一些基本用法。sql
SQLiteOpenHelper类是一个抽象类,主要有两个抽象方法,分别是onCreate和onUpgrade(),咱们必须在本身的帮助类中去重写这两个方法,分别在这两个类中去实现建立和升级数据库的逻辑。数据库
SQLiterOpenHelper中还有两个很是重要的实力方法,getReadableDatabase()和getWritablebase(),这两个方法均可以建立或打开一个现有的数据库并返回一个能够对数据库进行读写操做的对象,须要注意的是,当数据库不可写入的时候,getReadableDatabase()方法返回的对象将以只读的方式去打开数据库,而getWiterableDatabase()方法则将会出现异常。app
SQLiteOpenHelper中有两个构造方法可供重写,通常使用参数少点的那个,这个构造方法接受四个参数,第一个参数Context,这个没什么好说的,第二个参数是数据库名,第三个参数容许咱们在查询数据的时候返回一个自定义的Cursor,通常都是传入null,第四个参数表示当前数据库的版本号。构建出SQLiteOpenHelper的实例以后,再调用他的getReadableDatabase()或getwritableDatabase()方法就可以建立数据库了,重写的onCreate()方法也会获得执行。ide
接下来根据一个例子,建立一个BookStrore.db的数据库,并对其进行添加(insert),更新(update),删除(delete),查询(quary).
this
建立SQLiteOpenHelper类的实例代码:spa
package com.example.apple.servicetest; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.widget.Toast; /** * Created by apple on 16/3/22. */ public class MyDatabaseHelper extends SQLiteOpenHelper { public static final String CREATE_BOOK="create table Book(" + "id interger primary key autoincrement" + "author text" + "price real" + "pages integer" + "name text)"; public static final String CREATE_CATEGORY="create table Category(" + "id integer primary key autoincrement" + "category_name text," + "category_code integer)"; private Context mContext; public MyDatabaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version){ super(context,name,factory,version); mContext=context; } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK); db.execSQL(CREATE_CATEGORY); Toast.makeText(mContext,"successed",Toast.LENGTH_LONG).show(); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table if exists Book"); db.execSQL("drop table if exist Category"); onCreate(db); } }
对数据库进行操做:code
package com.example.apple.servicetest; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Message; import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class MainActivity extends AppCompatActivity { private Button createbtn; private Button adddatabtn; private Button updatabtn; private Button deletebtn; private Button quarybtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); createbtn=(Button)findViewById(R.id.create_btn); final MyDatabaseHelper databaseHelper=new MyDatabaseHelper(this,"BookStore.db",null,2); createbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { databaseHelper.getWritableDatabase(); } }); //更新数据 updatabtn=(Button)findViewById(R.id.updata_btn); updatabtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase db=databaseHelper.getWritableDatabase(); ContentValues values=new ContentValues(); values.put("price", 10.99); db.update("Book", values, "name=?", new String[]{"love is good"}); } }); //删除数据 deletebtn=(Button)findViewById(R.id.delete_data); deletebtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase db=databaseHelper.getWritableDatabase(); db.delete("Book", "pages>?", new String[]{"500"}); } }); //查询数据 quarybtn=(Button)findViewById(R.id.quary_btn); quarybtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase db=databaseHelper.getWritableDatabase(); Cursor cursor=db.query("Book",null,null,null,null,null,null); if (cursor.moveToFirst()){ do { String name=cursor.getString(cursor.getColumnIndex("name")); String author=cursor.getString(cursor.getColumnIndex("author")); Log.d("lallalala",name); Log.d("youyouyouyou",author); }while (cursor.moveToNext()); } cursor.close(); } }); //添加数据 adddatabtn=(Button)findViewById(R.id.add_btn); adddatabtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SQLiteDatabase db=databaseHelper.getWritableDatabase(); ContentValues values=new ContentValues(); values.put("name","love is good"); values.put("author","dan brown"); values.put("pages",454); values.put("price",16.96); db.insert("Book", null, values); values.clear(); values.put("name","love is bad"); values.put("author","dan "); values.put("pages",400); values.put("price", 19.00); db.insert("Book", null, values); } }); } }
这是其中一种方法来操做数据库,还有一种是使用SQL来操做数据库,具体代码实现以下:sqlite
更新数据库
删除数据库
db.execSQL("delete from Book where pages>?",new String[]{"500"});
更新数据库 db.execSQL("update Book set price =? where name=?",new String[] {"10.99","the name"});
添加数据库
db.execSQL("insert into Book(name,author,pages,price) values(?,?,?,?)", new String[] {"the name","the author","454","19.69"});
查找数据库
db.rawQuery("select * from Book",null);
SQLite数据库的最佳实践
1 使用事务
咱们已经知道了SQLite数据库是支持事务的,事务的特性能够保证让某一系列的操做要么所有完成,要么一个都不会完成,那么在什么状况下才须要使用事务,据个例子,在尽享一次转帐操做的时候,银行会将转帐的金额先从帐户中扣除,而后再向收款房的帐户中添加等量的金额,可是若是当刚刚从 帐户将钱扣除了以后,因为一些异常致使了对方收款失败了,那么这部分的钱就会凭空消失了,这时候就必须使用事务。
接下来将会在这个例子中使用事务,目的是将删除旧数据和添加新数据的操做一块儿完成,不然就必须还原成原来的旧数据。
SQLiteDatabase db=databaseHelper.getWritableDatabase(); db.beginTransaction(); try { db.delete("Book",null,null); if (true){ throw new NullPointerException(); } ContentValues values=new ContentValues(); values.put("name","Game of Throns"); values.put("author","George Martin"); values.put("pages",720); values.put("price",20.85); db.insert("Book", null, values); db.setTransactionSuccessful(); }catch (Exception e){ e.printStackTrace(); }finally { db.endTransaction(); } }
如今能够运行一下程序,发现表中的数据仍是原先的那些,如今将手动抛出的异常删除掉,再运行议席,便发现表中的数据已经更新成新的数据了。
升级数据库的最佳写法:
再以前的写法中咱们简单粗暴的直接删掉了全部当前的表而后强制从新执行一遍onCreate()方法。咱们须要进行一些合理的控制,让咱们保证在升级数据库的时候数据不会丢失,在初版的时候建立两个,在第二版的时候在book表中添加category_id键。代码以下:
package com.example.apple.servicetest; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.widget.Toast; /** * Created by apple on 16/3/22. */ public class MyDatabaseHelper extends SQLiteOpenHelper { public static final String CREATE_BOOK="create table Book(" + "id interger primary key autoincrement" + "author text" + "price real" + "pages integer" + "name text" + "category_id integer)"; public static final String CREATE_CATEGORY="create table Category(" + "id integer primary key autoincrement" + "category_name text," + "category_code integer)"; private Context mContext; public MyDatabaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version){ super(context,name,factory,version); mContext=context; } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK); db.execSQL(CREATE_CATEGORY); Toast.makeText(mContext,"successed",Toast.LENGTH_LONG).show(); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //db.execSQL("drop table if exists Book"); //db.execSQL("drop table if exist Category"); //onCreate(db); switch (oldVersion){ case 1: db.execSQL(CREATE_CATEGORY);case 2: db.execSQL("alter table Book add column category_id integer");//在第二版中添加的数据 default: } } }
请注意一个很是重要的细节,switch中的每个case的最后都没有使用break的缘由,是为了保证在跨版本升级的时候,每一次的数据库修改都能被所有执行到,好比从当前的第二版升级到第三版的时候,case2中的逻辑就会执行,若是用户从初版程序升级到第三版程序的时候,case1和case2也会被执行。使用这种方式来维护数据库的升级,无论版本怎样更新,均可以保证数据库的表结构是最新的,并且表中的数据也彻底不会丢失了。