티스토리 뷰
[Android] AAC Room @RawQuery: SimpleSQLiteQuery with SELECT projection, WHERE selection
rhys[기존] SQLite문으로 projection 및 selection을 받아 처리
Button btnSelection = findViewById(R.id.button_selection);
btnSelection.setOnClickListener(v -> {
String projection[] = {"ch.title", "title", "ch._id"};
String selection = "WHERE someType IS 1";
Cursor cursor = getApplicationContext().getContentResolver()
.query(uri, projection, selection, null, null);
String cursorToString = DatabaseUtils.dumpCursorToString(cursor);
textView.setText(cursorToString);
});
기존 앱에서 Room으로 DB를 바꾸며, 타 앱에 지원해 오던 ContentProvider를 구현해야 하는데
SQLite문의 projection과 selection으로 처리해오던 query를 받아낼 방법이 없음.
SQL Injection을 막기 위해서인지? Dao의 @Query에 들어가는 변수는 변수로써만 동작.
그러니까 아래 같은 거 안됨.
[X] @Query("SELECT * FROM " + Cheese.TABLE_NAME + " WHERE :selection")
List<Cheese> getItemBySelection(String selection);
[출처 mfamstory] projection - SELECT / selection - WHERE / sortOrder - ORDER BY
또 projection과 selection에서 오는 variation을 처리할 수 있어야 하는데,
parsing 후 필요한 그 모든 메소드를 Dao에 만들어 내려니 노답. 양이 너무 많음.
구글링해도 내게 적용할 방법이 보이질 않아 일단 아래와 같이 처리.
[룸 적용 후] RawQuery 대신 RoomDatabase의 query를 사용
Roomdatabase에 들어있는 이걸 가져다가,
// Below, there are wrapper methods for SupportSQLiteDatabase. This helps us track which
// methods we are using and also helps unit tests to mock this class without mocking
// all SQLite database methods.
/**
* Convenience method to query the database with arguments.
*
* @param query The sql query
* @param args The bind arguments for the placeholders in the query
*
* @return A Cursor obtained by running the given query in the Room database.
*/
public Cursor query(String query, @Nullable Object[] args) {
return mOpenHelper.getWritableDatabase().query(new SimpleSQLiteQuery(query, args));
}
/**
* Wrapper for {@link SupportSQLiteDatabase#query(SupportSQLiteQuery)}.
*
* @param query The Query which includes the SQL and a bind callback for bind arguments.
* @return Result of the query.
*/
public Cursor query(SupportSQLiteQuery query) {
assertNotMainThread();
return mOpenHelper.getWritableDatabase().query(query);
}
android/arch/persistence/room/RoomDatabase.java
외부의 query를 처리할 프로바이더의 query() 부분에 적용.
String columnList = "*";
if (projection != null) {
columnList = projectionToString(projection);
}
if(selection == null) {
selection = "";
}
RoomDatabase mDb = SampleDatabase.getInstance(getContext());
cursor = mDb.query(new SimpleSQLiteQuery("SELECT " + columnList + " FROM " + Cheese.TABLE_NAME + " " + selection));
기존처럼 DB에 RawQuery를 날리기 위해, 하드코딩을 하는 방식.
또, Room으로 DB를 변경하며 테이블 구조와 column명이 바뀌었기에... 들어온 projection, selection 각 String을 마이그레이션하는 작업도 들어가야 한다. 노답(2)
private String projectionToString(String[] projection) {
return String.join(",", new ArrayList<>(Arrays.asList(projection)));
}
-> "ch.title, title, ch._id"
그래서..
연동된 타 앱에 가이드 됐던대로, 기존에 지원하던 대로
CP query()의 projection과 selection을 새로운 RoomDatabase와 함께 사용할 수 있게 되었으나
'Android' 카테고리의 다른 글
[Git x Dropbox] 드랍박스에 private git 저장소 만들기: Android Studio에서 (0) | 2020.02.07 |
---|---|
[갤럭시 스토어] 바이너리 탭>바이너리 상세 정보’에서 지원하는 Galaxy Specials 정보를 확인할 수 있습니다. § 해결 방법 (0) | 2020.01.05 |
안드로이드 adb Path 설정방법: %ANDROID_HOME%\platform-tools 환경변수 (0) | 2020.01.04 |
Gradle: Could not find method leftShift() for arguments on task ':clean' of type org.gradle.api.DefaultTask. (0) | 2019.11.10 |
안드로이드 노트: 컨텐트 프로바이더(CP), 컨텐트 리졸버(CR), 컨텐트 옵저버(CO), 복수/단수 URI (0) | 2016.11.14 |
안드로이드 노트: 서비스, 생존주기, startService(), bindService(), ANR, AIDL, RPC (0) | 2016.11.13 |
안드로이드 노트: 리스트뷰, 어댑터, 어댑터뷰, 겟뷰, 오버스크롤 (0) | 2016.11.13 |
유료앱 판매를 위한 구글 판매자 계정 등록: GOOGLE 월렛 (0) | 2014.05.13 |
댓글