哎,当失眠成为一种习惯,那就无所谓啦!!!
今天主要学习了SQLite数据库以及内容提供器的相关知识
一、SQLite数据库
SQLite数据库是安卓自带的数据库,不仅支持标准的SQL数据,还支持ACID事务。
为了让我们更加方便的管理数据库,专门提供了一个SQLiteOpenHelper帮助类,借助这个类我们可以
很轻松的对数据库进行创建和升级。
由于SQLiteOpenHelper是一个抽象类,我们要使用它只能继承它,并且重写它的onCreate()和
onUpdate()方法。
SQLiteOpenHelper中还有getReadableDatabase()和getWritableDatabase(),这两个方法都可以用于创建或者打开一个现有的数据库,
返回一个可对数据库进行读写操作的对象。
SQLiteOpenHelper中的两个构造函数可供重写。一般使用参数少的构造方法,共有四个参数,第一个是Context,上下文,为程序运行提供环境
第二个参数是数据库名,第三个参数是返回一个自定义的cursor,最后一个参数是当前数据库的版本号。
构造出SQLiteOpenHelper的实例后,便可以调用它的两个get方法去创建数据库了,此时,重写的onCreate方法也会得到执行,所以一般在onCreate()方法中处理建表的逻辑。
1.创建一个SQLite数据库的代码如下:
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = "create table BOOK ("
+ "id integer 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,
CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
//Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}
2.升级数据库只要是用到onUpdate()方法
代码如下:
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists Book");//如果表存在就删除
db.execSQL("drop table if exists Category");
onCreate(db);//重新构造数据库
这只是完成了第一步,还有重要的一步就是要将构造函数中第四个参数版本号变大。
3.对数据库进行增删改查操作,主要是依靠系统提供的insert()、delete()、update()、put()等方法
添加数据代码:
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
// 开始组装第一组数据
values.put("name", "The Da Vinci Code");
values.put("author", "Dan Brown");
values.put("pages", 454);
values.put("price", 16.96);
db.insert("Book", null, values);
values.clear();
// 开始第二组数据
values.put("name", "The Lost Sysbol");
values.put("author", "Dan Brown");
values.put("pages", 510);
values.put("price", 19.95);
db.insert("Book", null, values);
删除数据代码:
SQLiteDatabase db=dbHelper.getWritableDatabase();
//这条命令的意思就是删除Book表中页数大于500的数据
db.delete("Book", "pages > ?",new String[]{"10"});
更新数据代码:
SQLiteDatabase db = dbHelper.getWritableDatabase();
// 用于暂时性存放数据
ContentValues values = new ContentValues();
values.put("price", 10.99);
//这条语句中的第三、四个参数的作用相当于where语句,第四个参数给第三个参数赋值
//参数类型均为字符串类型
db.update("Book", values, "name=?",
new String[] { "The Da Vinci Code" });
查找数据代码:
SQLiteDatabase db=dbHelper.getWritableDatabase();
//查询Book中的所有数据,数据都存储在cursor对象中
Cursor cursor=db.query("Book", null, null, null, null, null, null);
if(cursor.moveToFirst())
{
do{
//遍历Cursor对象,取出数据并打印
//先获取索引在获取索引对应的值
String name=cursor.getString(cursor.getColumnIndex("name"));
String anthor=cursor.getString(cursor.getColumnIndex("author"));
int pages=cursor.getInt(cursor.getColumnIndex("pages"));
double price=cursor.getDouble(cursor.getColumnIndex("price"));
Log.d("MainActivity", "book name is "+name);
Log.d("MainActivity", "book author is "+anthor);
Log.d("MainActivity", "book price is "+price);
Log.d("MainActivity", "book pages is "+pages);
}while(cursor.moveToNext());
}
}
4.使用事务保证数据的可靠性
事务的特性就是保证一系列的操作要么全部完成,要么一个都不完成。
SQLiteDatabase db=dbHelper.getWritableDatabase();
/**
* 使用事务的好处就在于能够一次性完成一性完成一系列的操作
* 使用事务首先要开启事务(beginTransaction),使用SQLiteDataBase的对象
* 操作完成之后调用(setTransactionSuccessful),表示事务执行成功
* 最后要将事务结束(endTransation())
* 由于事务要么全做,要么不做,在begin与end之间一旦有异常,ze会回滚到begin之前
* 保证了数据的安全性
*/
//开启事务
db.beginTransaction();
try{
//删除表中的素所有数据,而不是删除表
db.delete("Book", null, null);
//在这里手动抛出异常,让事务失败
// if(true)
// {
// throw new NullPointerException();
// }
ContentValues values=new ContentValues();
values.put("name", "Game of Thrones");
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();
}
}
二、内容提供者
主要适用于在不同程序之间实现数据的共享功能,允许一个程序访问另外一个程序的数据,并且保证安全性。
在这里主要学习使用现有的内容提供器,自定义的由于用处较少,所以不做讲解
要访问内容提供器中的数据,就要借助于ContentResolver类,可以通过Context中的getContentResolver()方法来获取该类的实例,
不同于SQLiteDatabase的是,ContentReslover中的增删改查是不接收表名的,而是用一个Uri参数代替,它由权限和路径组成。由于系统内容提供者
早已经封装好,所以就不赘述。
下面是一个获取系统联系人的代码,使用了系统封装好的URI
public class MainActivity extends ActionBarActivity {
ListView contactsView;
ArrayAdapter<String> adapter;
List <String> contactsList=new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contactsView=(ListView)findViewById(R.id.contacts_view);
//使用系统默认的子项布局
adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,contactsList);
contactsView.setAdapter(adapter);
readContacts();
}
private void readContacts()
{
Cursor cursor=null;
cursor=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
//从cursor中读取数据,默认在第一行
while(cursor.moveToNext())
{
//获取系统联系人的姓名
String displayName=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
//获取系统怜惜人的手机号码
String number=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//将数据添加到集合中
contactsList.add(displayName+"\n"+number);
}
}
明天将进行通知相关的学习,加油,晚安!!!
寄语:我可以输一阵子,但不能输一辈子!!!