AndroidでContent Providersを使用して複数のテーブルを公開するその他の方法
AndroidでContent Providersを使用して複数のテーブルを公開するためのベストプラクティス
各テーブルには、独自のContent Uriが必要です。これは、Content ProvidersがURIを使用して特定のデータにアクセスするためです。
例えば、users
と products
という2つのテーブルがあるとします。この場合、それぞれのテーブル用に次のようなContent Uriを定義できます。
content://com.example.app/users
content://com.example.app/products
テーブル構造を公開する
Content Providersは、テーブル構造を公開する必要があります。これは、クライアントアプリがデータを読み書きできるようにするためです。
テーブル構造を公開するには、onCreate()
メソッドで SQLiteOpenHelper
クラスを使用します。
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE users (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT)");
db.execSQL("CREATE TABLE products (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price REAL)");
}
適切な権限を設定する
Content Providersは、データへのアクセスを制御する必要があります。
権限を設定するには、query()
、insert()
、update()
、delete()
などのメソッドで UriMatcher
クラスを使用します。
@Override
public UriMatcher getMatcher() {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI("com.example.app", "users", USERS);
matcher.addURI("com.example.app", "products", PRODUCTS);
return matcher;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
int match = matcher.match(uri);
switch (match) {
case USERS:
return db.query("users", projection, selection, selectionArgs, null, null, sortOrder);
case PRODUCTS:
return db.query("products", projection, selection, selectionArgs, null, null, sortOrder);
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
データ変更を通知する
データ変更を通知するには、ContentResolver.notifyChange()
メソッドを使用します。
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int match = matcher.match(uri);
switch (match) {
case USERS:
int count = db.update("users", values, selection, selectionArgs);
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
case PRODUCTS:
int count = db.update("products", values, selection, selectionArgs);
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
テストを行う
テストを行うには、androidTestImplementation
依存関係に androidx.test.runner.AndroidJUnitRunner
と androidx.test.espresso:espresso-core
を追加します。
androidTestImplementation 'androidx.test.runner.AndroidJUnitRunner'
androidTestImplementation 'androidx.test.espresso:espresso-core'
サンプルコードを参照する
Content Providers の使用方法については、次のサンプルコードを参照してください。
これらのベストプラクティスに従うことで、AndroidでContent Providersを使用して複数のテーブルを安全かつ効率的に公開することができます。
public class MyContentProvider extends ContentProvider {
private static final String AUTHORITY = "com.example.app";
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
static {
MATCHER.addURI(AUTHORITY, "users", USERS);
MATCHER.addURI(AUTHORITY, "products", PRODUCTS);
}
private SQLiteDatabase db;
@Override
public boolean onCreate() {
Context context = getContext();
db = new SQLiteOpenHelper(context, "database.db", null, 1) {
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE users (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT)");
db.execSQL("CREATE TABLE products (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price REAL)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Implement schema upgrades here.
}
}.getWritableDatabase();
return true;
}
@Override
public UriMatcher getMatcher() {
return MATCHER;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
int match = MATCHER.match(uri);
switch (match) {
case USERS:
return db.query("users", projection, selection, selectionArgs, null, null, sortOrder);
case PRODUCTS:
return db.query("products", projection, selection, selectionArgs, null, null, sortOrder);
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
@Override
public String getType(Uri uri) {
int match = MATCHER.match(uri);
switch (match) {
case USERS:
return "vnd.android.cursor.dir/vnd.com.example.app.users";
case PRODUCTS:
return "vnd.android.cursor.dir/vnd.com.example.app.products";
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int match = MATCHER.match(uri);
switch (match) {
case USERS:
long id = db.insert("users", null, values);
return Uri.withAppendedPath(uri, String.valueOf(id));
case PRODUCTS:
long id = db.insert("products", null, values);
return Uri.withAppendedPath(uri, String.valueOf(id));
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int match = MATCHER.match(uri);
switch (match) {
case USERS:
int count = db.update("users", values, selection, selectionArgs);
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
case PRODUCTS:
int count = db.update("products", values, selection, selectionArgs);
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int match = MATCHER.match(uri);
switch (match) {
case USERS:
int count = db.delete("users", selection, selectionArgs);
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
case PRODUCTS:
int count = db.delete("products", selection, selectionArgs);
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return count;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
}
このコードは、`
AndroidでContent Providersを使用して複数のテーブルを公開する他の方法
複数 Content Providers を使用する
最も簡単な方法は、各テーブルごとに個別のContent Providerを作成することです。
例えば、users
と products
という2つのテーブルがあるとします。この場合、UsersContentProvider
と ProductsContentProvider
という2つのContent Providerを作成できます。
この方法は、シンプルで理解しやすいですが、Content Providerの数が増えると管理が煩雑になる可能性があります。
1つのContent Providerで複数のテーブルを公開することもできます。
これを行うには、UriMatcher
クラスを使用して、URIに基づいて特定のテーブルを識別する必要があります。
@Override
public UriMatcher getMatcher() {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI("com.example.app", "users", USERS);
matcher.addURI("com.example.app", "products", PRODUCTS);
return matcher;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
int match = matcher.match(uri);
switch (match) {
case USERS:
return db.query("users", projection, selection, selectionArgs, null, null, sortOrder);
case PRODUCTS:
return db.query("products", projection, selection, selectionArgs, null, null, sortOrder);
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
}
この方法は、Content Providerの数
android sqlite android-contentprovider