{"id":3714,"date":"2021-11-02T10:10:54","date_gmt":"2021-11-02T01:10:54","guid":{"rendered":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=3714"},"modified":"2021-11-06T20:26:04","modified_gmt":"2021-11-06T11:26:04","slug":"rxjava-sqlite-with-room","status":"publish","type":"post","link":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=3714","title":{"rendered":"RxJava Sqlite with Room"},"content":{"rendered":"<h1>RxJava Sqlite with Room<\/h1>\n<p><a href=\"https:\/\/huiveloper.tistory.com\/15\">\ucc38\uc870<\/a><\/p>\n<p><a href=\"https:\/\/medium.com\/androiddevelopers\/room-rxjava-acb0cd4f3757\">\ucc38\uc870<\/a><\/p>\n<h2>\uc758\uc874\uc131 \ucd94\uac00<\/h2>\n<p>2021-11-02 \uc77c\uc790 \uae30\uc900\uc73c\ub85c Room \uc740 2.3.0 \uc774 \uc548\uc804\ud654 \ubc84\uc804\uc774\ub2e4.<\/p>\n<pre><code class=\"language-gradle\">dependencies {\n    implementation &#039;io.reactivex.rxjava2:rxjava:2.2.21&#039;\n    implementation &#039;io.reactivex.rxjava2:rxandroid:2.1.1&#039;\n    implementation &quot;androidx.room:room-rxjava2:2.3.0&quot;\n    implementation &quot;androidx.room:room-runtime:2.3.0&quot;\n    annotationProcessor &quot;androidx.room:room-compiler:2.3.0&quot;\n\n    \/\/ LocalDateTime \ubc31\ud3ec\ud2b8 \ubc84\uc804\n    implementation &#039;com.jakewharton.threetenabp:threetenabp:1.3.0&#039;\n}<\/code><\/pre>\n<h2>Entity \uc0dd\uc131<\/h2>\n<p>Room \uc740 String Boot JPA \uc640 \uc720\uc0ac\ud55c \ud615\uc2dd\uc778\ub4ef(?)<\/p>\n<p><code>LocalDateTime<\/code> \uc744 sqlite \uc5d0\uc11c \ucc98\ub9ac\ub97c \ubabb\ud558\uae30\uc5d0, \uc2a4\ud2b8\ub9c1\uc73c\ub85c \ubcc0\ud658\ud574 \uc900\ub2e4.<\/p>\n<p>import \uac00 org.threeten.bp.LocalDateTime \uc774\ub2e4.<br \/>\n(\uc65c \ub72c\uae08\uc5c6\uc774 \uc774\uc0c1\ud55c \ub77c\uc774\ube0c\ub7ec\ub9ac \uc4f8\uae4c \uad81\uae08\ud558\uc2dc\uba74 \uc548\uc4f0\uc2dc\uba74 \uc774\uc720\ub97c \uc54c\uac8c\ub429\ub2c8\ub2e4.)<\/p>\n<pre><code class=\"language-java\">import org.threeten.bp.LocalDateTime;\n\npublic class LocalDateTimeConverter {\n\n    @TypeConverter\n    public static LocalDateTime toDate(String dateString) {\n        if (dateString == null) {\n            return null;\n        } else {\n            return LocalDateTime.parse(dateString);\n        }\n    }\n\n    @TypeConverter\n    public static String toDateString(LocalDateTime date) {\n        if (date == null) {\n            return null;\n        } else {\n            return date.toString();\n        }\n    }\n}<\/code><\/pre>\n<p>import \uac00 org.threeten.bp.LocalDateTime \uc774\ub2e4.<\/p>\n<pre><code class=\"language-java\">@Entity(tableName = &quot;tbl_favorite_folder&quot;, indices = {@Index(value = {&quot;id&quot;}, unique = true)})\npublic class FavoriteFolder {\n\n    @PrimaryKey(autoGenerate = true)\n    int id;\n\n    @ColumnInfo(name = &quot;name&quot;)\n    String name;\n\n    @ColumnInfo(name = &quot;status&quot;)\n    String status;\n\n    @ColumnInfo(name = &quot;display_order&quot;)\n    int displayOrder;\n\n    @ColumnInfo(name = &quot;modify_time&quot;)\n    @TypeConverters({LocalDateTimeConverter.class})\n    LocalDateTime modifyTime;\n\n    @ColumnInfo(name = &quot;insert_time&quot;)\n    @TypeConverters({LocalDateTimeConverter.class})\n    LocalDateTime insertTime;\n\n    public FavoriteFolder(String name, String status, int displayOrder) {\n        this.name = name;\n        this.status = status;\n        this.displayOrder = displayOrder;\n        if (id == 0) {\n            insertTime = LocalDateTime.now();\n        }\n        modifyTime = LocalDateTime.now();\n    }\n\n    \/\/ Getter() and Setter()\n}<\/code><\/pre>\n<h2>Dao \uc0dd\uc131<\/h2>\n<p><code>Flowable<\/code> \uc740 <code>Observable<\/code> \uc758 \ubcc0\ud615\uc73c\ub85c,<br \/>\nDB \uc5d0\uc11c\uc758 \ub370\uc774\ud0c0\uac00 \ub9ce\uc740 \uacbd\uc6b0 \uc77c\uc815\ub7c9\uc529 \uc798\ub77c\uc11c \uc21c\ucc28\uc801\uc73c\ub85c \ubcf4\ub0b4\uc8fc\ub294 \uae30\ub2a5\uc774\ub2e4.<\/p>\n<p>\uad6c\ud604 \ubcf5\uc7a1\ub3c4\uac00 \uc62c\ub77c\uac00\ub2c8 <code>Single&lt;List&lt;FavoriteFolder&gt;&gt;<\/code> \ub85c \ubc14\uafb8\uace0,<br \/>\nDao \ucabd\uc5d0\uc11c \ud398\uc774\uc9d5 \uae30\ub2a5\uc744 \ub123\ub294 \uac83\uc774 \ub0ab\ub2e4.<\/p>\n<p><code>Completable<\/code> \uc740 <code>Observable<\/code> \uc758 \ubcc0\ud615\uc73c\ub85c, Response \uac00 \uc5c6\uc744\ub54c \uc4f0\uc778\ub2e4.<\/p>\n<p><code>Single<\/code> \ub3c4 <code>Observable<\/code> \uc758 \ubcc0\ud615\uc778\ub370, Query \uc758 \uc885\ub958\uc5d0 \ub530\ub77c \ub9ac\ud134\uac12\uc774 \ub2ec\ub77c\uc9c4\ub2e4.<\/p>\n<ul>\n<li>\n<p>Insert<\/p>\n<p><code>Single&lt;Long&gt;<\/code>, <code>Single&lt;List&lt;Long&gt;&gt;<\/code> \uc758 \ud615\ud0dc\ub85c \uc0dd\uc131\ub41c \ub370\uc774\ud0c0\uc758 PK \ub97c \ubc18\ud658\ubc1b\ub294\ub2e4.<\/p>\n<\/li>\n<li>\n<p>Update\/Delete<\/p>\n<p><code>Single&lt;Integer&gt;<\/code> \uc758 \ud615\ud0dc\ub85c rows affected \uac00 \ubc18\ud658\ub41c\ub2e4.<\/p>\n<\/li>\n<li>\n<p>Select<\/p>\n<p><code>Single&lt;User&gt;<\/code>, <code>Single&lt;List&lt;User&gt;&gt;<\/code> \ud615\ud0dc\ub85c \uac80\uc0c9\ub41c \ub370\uc774\ud0c0\uac00 \ubc18\ud658\ub41c\ub2e4.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"language-java\">@Dao\npublic interface FavoriteFolderDao {\n\n    @Query(&quot;SELECT * FROM tbl_favorite_folder ORDER BY display_order, id LIMIT 20 OFFSET (20 * :page)&quot;)\n    Single&lt;List&lt;FavoriteFolder&gt;&gt; getFolderList(Integer page);  \/\/ start from 0\n\n    @Query(&quot;DELETE FROM tbl_favorite_folder &quot;)\n    Completable deleteAllItem();\n\n    @Query(&quot;DELETE FROM tbl_favorite_folder  WHERE id = :id&quot;)\n    Single&lt;Integer&gt; deleteFolder(Integer id);\n\n    @Insert(onConflict = OnConflictStrategy.IGNORE)\n    Single&lt;Long&gt; insertFolder(FavoriteFolder favoriteFolder);\n\n    @Query(&quot;SELECT * FROM tbl_favorite_folder WHERE id = :id&quot;)\n    Single&lt;FavoriteFolder&gt; getFolder(Integer id);\n\n    @Update\n    Single&lt;Integer&gt; modifyFolder(FavoriteFolder favoriteFolder);\n}<\/code><\/pre>\n<h2>\ub370\uc774\ud0c0\ubca0\uc774\uc2a4 \uc0dd\uc131<\/h2>\n<pre><code class=\"language-java\">@Database(entities = { FavoriteFolder.class }, version = 1, exportSchema = false)\npublic abstract class AppDataBase extends RoomDatabase {\n\n    public abstract FavoriteFolderDao RoomDao();\n\n    private static AppDataBase instance = null;\n    private static String DB_NAME = &quot;db_mg&quot;;\n\n    public static AppDataBase getInstance(Context context) {\n        return instance != null ? instance : buildDataBase(context);\n    }\n\n    private static AppDataBase buildDataBase(Context context ) {\n\n        return Room.databaseBuilder(context.getApplicationContext(), AppDataBase.class,DB_NAME)\n                .fallbackToDestructiveMigration()\n                .addCallback(new RoomDatabase.Callback() {\n                    @Override\n                    public void onCreate(@NonNull SupportSQLiteDatabase db) {\n                        super.onCreate(db);\n                    }\n                }).build();\n    }\n}<\/code><\/pre>\n<h2>MainActivity<\/h2>\n<p><code>subscribeOn<\/code> \uc740 \uccab \uc5f0\uc0b0\uc758 \uc2e4\ud589\uc744 \uc5b4\ub290 Thread \uc5d0\uc11c \ud560\uc9c0\ub97c \uacb0\uc815\ud55c\ub2e4.<br \/>\n<code>observeOn<\/code> \uc740 \ub2e4\uc74c \uc5f0\uc0b0\uc774 \uc5b4\ub290 Thread \uc5d0\uc11c \uc2e4\ud589\ud560\uc9c0 \uacb0\uc815\ud55c\ub2e4.<\/p>\n<p><code>.subscribeOn(Schedulers.io())<\/code> \uc740 \uccab \uc5f0\uc0b0(DB \uc5f0\uacb0\ud558\uc5ec \ub370\uc774\ud0c0 \uc2b5\ub4dd) \uc774 IO Thread \uc5d0\uc11c \uc2e4\ud589\ub418\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.<\/p>\n<p><code>.observeOn(AndroidSchedulers.mainThread())<\/code> \uc740 \ub2e4\uc74c \uc5f0\uc0b0(UI \uc5d0 \ub370\uc774\ud0c0 \ud45c\uc2dc)\ub97c Android Main Thread \uc5d0\uc11c \uc2e4\ud589\ub428\uc744 \uc758\ubbf8\ud55c\ub2e4.<\/p>\n<pre><code class=\"language-java\">public class MainActivity extends AppCompatActivity implements View.OnClickListener {\n    \/\/ ......\n    private AppDataBase appDataBase;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        \/\/ ......\n        appDataBase = AppDataBase.getInstance(this);\n        AndroidThreeTen.init(this);\n    }\n\n    @Override\n    public void onClick(View v) {\n        switch (v.getId()) {\n            case R.id.change_value_button:\n                appDataBase.RoomDao().insertFolder(new FavoriteFolder(&quot;name&quot;, &quot;status&quot;, 1))\n                        .subscribeOn(Schedulers.io())\n                        .observeOn(AndroidSchedulers.mainThread())\n                        .doOnSuccess(id -&gt; {\n                            Log.d(&quot;getKeyHash&quot;, &quot;Inserted row id : &quot; + id);\n                        })\n                        .doOnError(throwable -&gt; {\n                            Log.e(&quot;getKeyHash&quot;, &quot;Error : &quot; + throwable.toString());\n                        })\n                        .subscribe();\n\n                appDataBase.RoomDao().getFolder(1)\n                        .subscribeOn(Schedulers.io())\n                        .observeOn(AndroidSchedulers.mainThread())\n                        .doOnSuccess(favoriteFolder -&gt; {\n                            Log.i(&quot;getKeyHash&quot;, &quot;Data Found : &quot; + favoriteFolder.getName());\n                        })\n                        .doOnError(throwable -&gt; {\n                            Log.e(&quot;getKeyHash&quot;, &quot;Error : &quot; + throwable.toString());\n                        })\n                        .subscribe();\n\n                appDataBase.RoomDao().getFolderList(0)\n                        .subscribeOn(Schedulers.io())\n                        .observeOn(AndroidSchedulers.mainThread())\n                        .doOnSuccess(items -&gt; {\n                            Log.d(&quot;getKeyHash&quot;, &quot;Total count : &quot; + items.size());\n                            for (FavoriteFolder item : items) {\n                                Log.d(&quot;getKeyHash&quot;, item.getName());\n                                Log.d(&quot;getKeyHash&quot;, &quot;aaa&quot;);\n                            }\n                        })\n                        .doOnError(throwable -&gt; {\n                            Log.e(&quot;getKeyHash&quot;, &quot;Error : &quot; + throwable.toString());\n                        })\n                        .subscribe();\n\n                break;\n        }\n    }\n}<\/code><\/pre>\n<h2>\uc5ec\ub2f4<\/h2>\n<p>\ucc98\uc74c \uc548\ub4dc\ub85c\uc774\ub4dc \uac1c\ubc1c\ud588\uc744 \ub54c,<br \/>\nsqlite \ub294 \ub0a0\ucffc\ub9ac\ub85c \uc791\uc5c5\ud558\uace0,<br \/>\n\ube44\ub3d9\uae30 \uc2e4\ud589\ub530\uc704 \uc548\uc911\uc5d0\ub3c4 \uc5c6\uc774 Main Thread \uc5d0\uc11c \uc791\uc5c5\ud588\ub358 \uae30\uc5b5\uc774&#8230;. \u314b\u314b\u314b\u314b<\/p>\n","protected":false},"excerpt":{"rendered":"<p>RxJava Sqlite with Room \ucc38\uc870 \ucc38\uc870 \uc758\uc874\uc131 \ucd94\uac00 2021-11-02 \uc77c\uc790 \uae30\uc900\uc73c\ub85c Room \uc740 2.3.0 \uc774 \uc548\uc804\ud654 \ubc84\uc804\uc774\ub2e4. dependencies { implementation &#039;io.reactivex.rxjava2:rxjava:2.2.21&#039; implementation &#039;io.reactivex.rxjava2:rxandroid:2.1.1&#039; implementation &quot;androidx.room:room-rxjava2:2.3.0&quot; implementation &quot;androidx.room:room-runtime:2.3.0&quot; annotationProcessor &quot;androidx.room:room-compiler:2.3.0&quot; \/\/ LocalDateTime \ubc31\ud3ec\ud2b8 \ubc84\uc804 implementation &#039;com.jakewharton.threetenabp:threetenabp:1.3.0&#039; } Entity \uc0dd\uc131 Room \uc740 String Boot JPA \uc640 \uc720\uc0ac\ud55c \ud615\uc2dd\uc778\ub4ef(?) LocalDateTime \uc744 sqlite \uc5d0\uc11c \ucc98\ub9ac\ub97c \ubabb\ud558\uae30\uc5d0, \uc2a4\ud2b8\ub9c1\uc73c\ub85c \ubcc0\ud658\ud574 \uc900\ub2e4.\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=3714\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32,33],"tags":[],"class_list":["post-3714","post","type-post","status-publish","format-standard","hentry","category-android","category-rxjava"],"_links":{"self":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/3714","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3714"}],"version-history":[{"count":32,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/3714\/revisions"}],"predecessor-version":[{"id":3747,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/3714\/revisions\/3747"}],"wp:attachment":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3714"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3714"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3714"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}