ContentProvider与sqlit的搭配使⽤
上⼀篇⽂章已经讲诉了Android开发中⽂件存储、⽹络存储和SharedPreferences这三种持久化存储的⽅式,以及⼤致讲了什么是ContentProvider和它的使⽤场景。那么这篇⽂章我们就来具体讲诉⼀下如何使⽤ContentProvider与sqlit搭配,实现与⼀个APP对另⼀
个APP的数据增删改查。
⾸先我们使⽤SQLiteOpenHelper这个类来创建⼀个数据库,并创建⼀个储存个⼈信息的People_Message的表。
public class MyDatabaHelper extends SQLiteOpenHelper {
//sql语句,⽤来创建表。
public static final String People_Message="create table people("
+"num integer primary key autoincrement,"
+"name text,"
+"x text)";
Context mContext;
public MyDatabaHelper(Context context, String name, SQLiteDataba.CursorFactory factory, int version) {
//调⽤⽗类构造⽅法,创建数据库。第⼀个参数是context。第⼆个参数是数据库的名字,第三个参CursorFactory指定在执⾏查询时获得⼀个游标实例的⼯⼚super(context, name, factory, version);
mContext=context;
}
toeic官网
@Override
public void onCreate(SQLiteDataba db) {
//创建表,执⾏sql语句
}
@Override
public void onUpgrade(SQLiteDataba db, int oldVersion, int newVersion) {
//如果需要升级数据库,会调⽤该⽅法。可以⽤来删除表或者添加表。
}
}
上⾯是⼀个继承了SQLiteOpenHelper类的类。在构造⽅法中会调⽤⽗类构造⽅法,创建⼀个数据库。然后在onCreate中使⽤
然后我们需要在主线程中创建⼀个MyDatabaHelper对象,这样就创建好了数据库和表(如果数据库和表已经存在,将不会创建)。
mMyDatabaHelper=new MyDatabaHelper(getApplicationContext(),"people_message",null,1);
制片人
然后我们需要得到⼀个SQLiteDataba 对象,这个对象可以⽤来操作数据库。
//得到可以读写数据库的SQLiteDataba
WritableDataba();
//得到只读数据库的SQLiteDataba
//ReadableDataba();
上⾯代码可以,我们可以通过刚才创造的SQLiteOpenHelper对象来获取SQLiteDataba。其中有两种获取⽅式,⼀个可以对数据库进⾏写⼊,另⼀个只读。
SQLiteDataba这个对象中有⼏个⽅法,是对修改数据库的⼏种⽅式进⾏了包装。
从数据库中查询数据
db.query(String table,String[] columns,String lection,String[] lectionArgs,String groupBy,String having,String
orderBy,String limit)
参数意义:
table:表名
columns:需要得到的列名数组
lection:条件字句,相当于where
lectionArgs:条件字句,条件的数组
groupBy:分组列名
having:分组条件
orderBy:排序列名
limit:查询限制
往数据库中插⼊数据
db.inrt(String table,String nullColumnHack,ContentValues values)
参数意义:
table:表名
nullColumnHack:空列的默认值
values:插⼊的数据,key-value类型的集合
把数据库中指定的数据删除
db.delete(String table,String whereClau,String[] whereArgs)
参数意义:
table:表名
whereClau:删除条件
whereArgs:删除条件值数组
换性
修改数据库中指定的数据
db.update(String table,ContentValues values,String whereClau, String[] whereArgs)
参数意义:
table:表名
values:修改的数据,key-value类型的集合
whereClau:修改条件
whereArgs:修改条件值数组
执⾏具体的sql语句
db.XXXX的⽅法还有许多,如果上⾯的不能满⾜你的要求,你可以看看源码,选择⾃⼰需要的⽅法。
上述⽅法中都有很多参数,除了db.execSQL()中的参数是你需要执⾏的sql语句外,其他的参数都有很多,这⾥不细讲,使⽤的时候⼤家可以再学习。
上⾯我们已经建⽴了⼀个数据库并且创建了⼀个表。下⾯就是需要对表进⾏操作了。这⾥我们使⽤ContentProvider来对表进⾏操作。
我们创建⼀个类继承与ContentProvider,并在AndroidManifast中进⾏注册。
public class MyContentProvider extends ContentProvider
{
public MyContentProvider()
{
}
@Override
public int delete(Uri uri, String lection, String[] lectionArgs)
{
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri)
{
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri inrt(Uri uri, ContentValues values)
{
// TODO: Implement this to handle requests to inrt a new row.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public boolean onCreate()
{
// TODO: Implement this to initialize your content provider on startup.
return fal;
}
@Override
public Cursor query(Uri uri, String[] projection, String lection,
String[] lectionArgs, String sortOrder)
{
// TODO: Implement this to handle query requests from clients.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
餐饮服务提供者
public int update(Uri uri, ContentValues values, String lection,
String[] lectionArgs)
{
// TODO: Implement this to handle requests to update one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
}
上⾯代码可以看见,除了⽆参构造函数之外,还会⾃动⽣成⼏个重写⽅法,这⼏个⽅法就是上⾯我们所说的增删改查⼏个⽅法,我们可以在对应函数中就可以⾃⼰编写对数据库的操作了。
我们发现上⾯的⼏个⽅法中第⼀个参数类型都是Uri,这个参数代表要操作的数据。我们先来简单说⼀下Uri的构造,理解⼀下Uri具体的⽤法。
四年级下册生字表Uri 通⽤资源标志符(Universal Resource Identifier)
上⾯就是Uri的具体结构,我们通过具体的Uri就可以访问我们需要访问的数据了,对于ContentProvider来说,⽤来访问它的Uri有具体的格式。
[scheme:]=content
[//authority]=主机名,在AndroidManifest⽂件中可以对具体ContentProvider的authorities属性进⾏修改和查看,这⾥我们上⾯定义ContentProvider的authorities为”test_contentProvider”。
<provider
android:name=".contentProvider.MyContentProvider"
android:authorities="test_contentProvider"
android:enabled="true"
android:exported="true">
</provider>
[path]就是我们表的名字,在这个事例程序中就是”people”。
所以这个ContentProvider的指定Uri就是
Uri PEO=Uri.par("content://test_contentProvider/people");
那么我们来看看完整的MyContentProvider类应该是怎样的
public class MyContentProvider extends ContentProvider
{
MyDatabaHelper mMyDatabaHelper;
SQLiteDataba db;
UriMatcher sMatcher;
Uri PEO=Uri.par("content://test_contentProvider/people");
public MyContentProvider()
{
}
//⽤于匹配传⼊的URI,如果不匹配返回-1
public int getUriMatcher(Uri uri){
return sMatcher.match(uri);
}
@Override
public int delete(Uri uri, String lection, String[] lectionArgs)
{
//删除数据
if(getUriMatcher(uri)==1){
db.delete("people",lection,lectionArgs);
getContext().getContentResolver().notifyChange(PEO,null);
return1;
}
return0;
}
@Override
public String getType(Uri uri)
{
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri inrt(Uri uri, ContentValues values)
{
/
/判断传⼊的URI是否匹配,匹配的话将数据插⼊数据库
if (getUriMatcher(uri)==1){
db.inrt("people",null,values);
getContext().getContentResolver().notifyChange(PEO,null);
}
return null;
}
}
@Override
public boolean onCreate()
{
/
/打开数据库,得到dbcad特性
mMyDatabaHelper=new MyDatabaHelper(getContext(),"data",null,1);
//得到可以读写数据库的SQLiteDataba
WritableDataba();
//UriMatcher.NO_MATCH表⽰不匹配任何Uri的返回码-1
sMatcher=new UriMatcher(UriMatcher.NO_MATCH);
//添加⼀个匹配规则:第⼀个参数contentProvider的authority值,第⼆个参数数据表名,第三个参数匹配后返回值
sMatcher.addURI("test_contentProvider","people",1);
return fal;
}
无法改变@Override
public Cursor query(Uri uri, String[] projection, String lection,
String[] lectionArgs, String sortOrder)
{
//查询数据
if (getUriMatcher(uri)==1){
Cursor cursor=db.query("people",null,lection,lectionArgs,null,null,sortOrder);
return cursor;
}
return null;
}
园博会@Override
public int update(Uri uri, ContentValues values, String lection,
String[] lectionArgs)
{
//更新数据
if (getUriMatcher(uri)==1){
db.update("people",values,lection,lectionArgs);
getContext().getContentResolver().notifyChange(PEO,null);
return1;
}
return0;
}
1.⾸先我们在onCreate构造函数中,创建或打开要操作的数据库,得到⽤来操作数据库的db。
2.接着我们为new出⼀个UriMatcher对象,给这个对象添加⼀个URi(可以同时添加多个,只要返回码不⼀样),这个Uri就是⽤来访问当前MyContentProvider的指定Uri,通过对ContentProvider时传⼊的URI进⾏校验,判断是否可以能够匹配,根据匹配的返回码,得知具体需要操作的数据。
3.在增删改查的四个⽅法中,进⾏具体的数据操作,这篇⽂章主要是对数据库的增删改查操作,所以直接使⽤db.xxxx()⽅法来进⾏操作。
4.在增删改完成之后,如果对数据进⾏了修改,使⽤getContext().getContentResolver().notifyChange(PEO,null)这段代码,对指定的URI添加⼀个通知,通知当前URI的数据有修改,便于ContentObrver进⾏监听。
上⾯就构造出了⼀个⾃定义的ContentProvider。它的指定Uri”content://test_contentProvider/people”。
我们初始化数据库,向数据库中插⼊⼗条数据,便于显⽰和查询。