{"id":2385,"date":"2016-09-13T15:00:01","date_gmt":"2016-09-13T15:00:01","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2385"},"modified":"2025-06-13T19:56:31","modified_gmt":"2025-06-14T02:56:31","slug":"using-couchbase-in-a-javafx-desktop-application","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/ko\/using-couchbase-in-a-javafx-desktop-application\/","title":{"rendered":"JavaFX \ub370\uc2a4\ud06c\ud1b1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c Couchbase \uc0ac\uc6a9"},"content":{"rendered":"<p>\uc800\ub294 \uba4b\uc9c4 Java SDK\ub97c \uc0ac\uc6a9\ud574 Couchbase\uc640 \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uaf64 \uc624\ub7ab\ub3d9\uc548 \ub2e4\ub904\uc654\uc9c0\ub9cc, Couchbase\ub97c \uc0ac\uc6a9\ud574 \ub370\uc774\ud130\ub97c \uc800\uc7a5\ud558\ub294 \ub370\uc2a4\ud06c\ud1b1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\ub3c4 \ub9cc\ub4e4 \uc218 \uc788\ub2e4\ub294 \uc0ac\uc2e4\uc744 \uc54c\uace0 \uacc4\uc168\ub098\uc694? JavaFX\uc640 \uac19\uc740 Java \ub370\uc2a4\ud06c\ud1b1 \ud504\ub808\uc784\uc6cc\ud06c\ub294 Couchbase Java SDK\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc9c0\ub9cc, \ud074\ub77c\uc774\uc5b8\ud2b8 \ub300\uba74 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uc11c\ubc84\uc6a9 SDK\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc88b\uc740 \uc0dd\uac01\uc774 \uc544\ub2d0 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \ub300\uc2e0 Couchbase\uc758 \ubaa8\ubc14\uc77c \uc194\ub8e8\uc158\uc744 \uc0ac\uc6a9\ud558\uc5ec \ud074\ub77c\uc774\uc5b8\ud2b8\ub97c \ub300\uc0c1\uc73c\ub85c \ud558\ub294 \ub370\uc2a4\ud06c\ud1b1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \uc194\ub8e8\uc158\uc740 Android\uc640 \ub3d9\uc77c\ud55c API\ub97c \uc0ac\uc6a9\ud558\uc9c0\ub9cc \ub370\uc2a4\ud06c\ud1b1\uc744 \uc5fc\ub450\uc5d0 \ub450\uace0 \uc124\uacc4\ub418\uc5c8\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uc774 \ub370\uc774\ud130\ub97c \ucef4\ud4e8\ud130 \uac04\uc5d0 \ub3d9\uae30\ud654\ud558\uae30 \uc704\ud574 JavaFX, Couchbase Lite, \uc2ec\uc9c0\uc5b4 Couchbase Sync Gateway\ub97c \uc0ac\uc6a9\ud558\uc5ec \uac04\ub2e8\ud55c \ub370\uc2a4\ud06c\ud1b1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\ub294 \ubc29\ubc95\uc744 \uc0b4\ud3b4 \ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<h2>\uc694\uad6c \uc0ac\ud56d<\/h2>\n<p>\uc774 \ud504\ub85c\uc81d\ud2b8\ub97c \uc131\uacf5\uc801\uc73c\ub85c \uc218\ud589\ud558\ub824\uba74 \uba87 \uac00\uc9c0 \uc694\uad6c \uc0ac\ud56d\uc744 \ucda9\uc871\ud574\uc57c \ud569\ub2c8\ub2e4.<\/p>\n<ul>\n<li>JDK 1.7+<\/li>\n<li>Maven<\/li>\n<li>\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ub3d9\uae30\ud654 \uac8c\uc774\ud2b8\uc6e8\uc774<\/li>\n<\/ul>\n<p>\uc774 \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c\ub294 Maven\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc885\uc18d\uc131\uc744 \uc218\uc9d1\ud558\uace0 JAR \ud30c\uc77c\uc744 \ube4c\ub4dc\ud569\ub2c8\ub2e4. \ub3d9\uae30\ud654 \uac8c\uc774\ud2b8\uc6e8\uc774\uac00 \ubc18\ub4dc\uc2dc \ud544\uc694\ud55c \uac83\uc740 \uc544\ub2c8\uc9c0\ub9cc \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0 \ub3d9\uae30\ud654 \uc9c0\uc6d0\uc744 \ucd94\uac00\ud558\ub824\ub294 \uacbd\uc6b0\uc5d0\ub294 \ud544\uc694\ud569\ub2c8\ub2e4.<\/p>\n<h2>Maven\uc73c\ub85c \uc0c8\ub85c\uc6b4 JavaFX \ud504\ub85c\uc81d\ud2b8 \ub9cc\ub4e4\uae30<\/h2>\n<p>\uae30\ubcf8\uc801\uc778 Maven \ud504\ub85c\uc81d\ud2b8\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud569\ub2c8\ub2e4. \uc774 \uc791\uc5c5\uc740 \uc6d0\ud558\ub294 IDE\uc5d0\uc11c \uc218\ud589\ud558\uac70\ub098 \uc218\ub3d9\uc73c\ub85c \uc218\ud589\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uae30\ubcf8\uc801\uc73c\ub85c \ud544\uc694\ud55c \uac83\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ud30c\uc77c \ubc0f \ub514\ub809\ud1a0\ub9ac \uad6c\uc870\uc785\ub2c8\ub2e4:<\/p>\n<pre><code>\r\nsrc\r\n    main\r\n        java\r\n            com\r\n                couchbase\r\n                    CouchbaseSingleton.java\r\n                    Main.java\r\n                    Todo.java\r\n                    TodoFXController.java\r\n    resources\r\n        TodoFX.fxml\r\npom.xml\r\n<\/code><\/pre>\n<p>\uac1c\ubc1c\uc744 \uc2dc\uc791\ud558\uba74 \uac01 \ud30c\uc77c\uc5d0 \ud3ec\ud568\ub41c \ub0b4\uc6a9\uc5d0 \ub300\ud574 \uc790\uc138\ud788 \uc54c\uc544\ubcf4\uaca0\uc2b5\ub2c8\ub2e4. \uc9c0\uae08\uc740 Maven\uc744 \uc124\uc815\ud574\uc57c \ud569\ub2c8\ub2e4. <strong>pom.xml<\/strong> \ud30c\uc77c\uc5d0 \ud544\uc694\ud55c \uc885\uc18d\uc131\uc744 \uac00\uc838\uc62c \uc218 \uc788\ub3c4\ub85d \ud569\ub2c8\ub2e4.<\/p>\n<p>\ud504\ub85c\uc81d\ud2b8\uc758 <strong>pom.xml<\/strong> \ud30c\uc77c\uc744 \uc5f4\uace0 \ub2e4\uc74c\uc744 \ud3ec\ud568\ud558\uc138\uc694:<\/p>\n<pre><code>\r\n\r\n    com.couchbase\r\n    couchbase-javafx-example\r\n    4.0.0\r\n    Couchbase JavaFX Example\r\n    jar\r\n    1.0\r\n    \r\n        \r\n            com.couchbase.lite\r\n            couchbase-lite-java\r\n            1.3.0\r\n        \r\n        \r\n            com.couchbase.lite\r\n            couchbase-lite-java-sqlcipher\r\n            1.3.0\r\n        \r\n        \r\n            junit\r\n            junit\r\n            4.12\r\n            test\r\n        \r\n    \r\n    \r\n        \r\n            \r\n                com.zenjava\r\n                javafx-maven-plugin\r\n                8.5.0\r\n                \r\n                    com.couchbase.Main\r\n                \r\n            \r\n            \r\n                org.apache.maven.plugins\r\n                maven-compiler-plugin\r\n                3.3\r\n                \r\n                    1.7\r\n                    1.7\r\n                \r\n            \r\n            \r\n                maven-assembly-plugin\r\n                2.2.1\r\n                \r\n                    \r\n                        jar-with-dependencies\r\n                    \r\n                    \r\n                        \r\n                            true\r\n                            lib\/\r\n                            com.couchbase.Main\r\n                        \r\n                    \r\n                \r\n                \r\n                    \r\n                        make-assembly\r\n                        package\r\n                        \r\n                            single\r\n                        \r\n                    \r\n                \r\n            \r\n        \r\n    \r\n\r\n<\/code><\/pre>\n<p>\uc704\uc758 Maven \ud30c\uc77c\uc5d0\uc11c \ubd88\ud544\uc694\ud55c \uc138\ubd80 \uc0ac\ud56d\uc744 \ub108\ubb34 \ub9ce\uc774 \ub2e4\ub8e8\uc9c0 \uc54a\uace0, \ud2b9\ud788 \uba87 \uac00\uc9c0 \uc0ac\ud56d\uc5d0 \uc8fc\ubaa9\ud558\uace0\uc790 \ud569\ub2c8\ub2e4.<\/p>\n<pre><code>\r\n\r\n    com.couchbase.lite\r\n    couchbase-lite-java\r\n    1.3.0\r\n\r\n<\/code><\/pre>\n<p>\uc704\uc758 \uc885\uc18d\uc131\uc5d0\uc11c Couchbase Lite\ub97c \ud504\ub85c\uc81d\ud2b8\uc5d0 \ud3ec\ud568\ud558\uace0 \uc788\uc74c\uc744 \uc54c \uc218 \uc788\uc2b5\ub2c8\ub2e4. Couchbase Lite\ub294 \uc11c\ubc84 \uc5b4\ub518\uac00\uc5d0 \uc788\uc9c0 \uc54a\uc740 \ub85c\uceec \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub77c\ub294 \uc810\uc744 \uae30\uc5b5\ud558\uc138\uc694. \ub370\uc774\ud130\ub294 \ub85c\uceec\uc5d0 \uc800\uc7a5\ub418\uba70 \ucef4\ud3ec\ub10c\ud2b8\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub0b4\uc5d0 \ubc88\ub4e4\ub85c \uc81c\uacf5\ub429\ub2c8\ub2e4.<\/p>\n<p>\ub2e4\uc74c \ud50c\ub7ec\uadf8\uc778\ub3c4 \uc8fc\ubaa9\ud560 \ud544\uc694\uac00 \uc788\uc2b5\ub2c8\ub2e4:<\/p>\n<pre><code>\r\n\r\n    com.zenjava\r\n    javafx-maven-plugin\r\n    8.5.0\r\n    \r\n        com.couchbase.Main\r\n    \r\n\r\n<\/code><\/pre>\n<p>\uc704\uc758 \ud50c\ub7ec\uadf8\uc778\uc740 JavaFX \ud504\ub85c\uc81d\ud2b8\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud55c \uac83\uc785\ub2c8\ub2e4. \ubb3c\ub860 \uc774 \ud504\ub85c\uc81d\ud2b8 \uc0dd\uc131\uc740 IntelliJ\uc640 \uac19\uc740 IDE\ub97c \uc0ac\uc6a9\ud558\uba74 \ud544\uc218\ub294 \uc544\ub2c8\uc9c0\ub9cc \ud6e8\uc52c \ub354 \uc27d\uc2b5\ub2c8\ub2e4.<\/p>\n<h2>\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \uc2f1\uae00\ud1a4 \ud074\ub798\uc2a4 \uc0dd\uc131\ud558\uae30<\/h2>\n<p>JavaFX \ud504\ub85c\uc81d\ud2b8\uc758 UI\uc640 \ucee8\ud2b8\ub864\ub7ec\ub97c \ub9cc\ub4dc\ub294 \ub370 \ud22c\uc790\ud558\uae30 \uc804\uc5d0 \ub370\uc774\ud130\ub97c \uc5b4\ub5bb\uac8c \ucc98\ub9ac\ud560\uc9c0 \uace0\ubbfc\ud574 \ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uac04\uc18c\ud654\ub97c \uc704\ud574 \ud504\ub85c\uc81d\ud2b8 \uc804\uccb4\uc5d0\uc11c \ub370\uc774\ud130\ub97c \uad00\ub9ac\ud558\uae30 \uc704\ud55c \uc2f1\uae00\ud1a4 \ud074\ub798\uc2a4\ub97c \ub9cc\ub4dc\ub294 \uac83\uc774 \uc88b\uc2b5\ub2c8\ub2e4. \ub610\ud55c \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubaa8\ub4e0 \uacf3\uc5d0\uc11c \ucffc\ub9ac\ub97c \uc791\uc131\ud560 \ud544\uc694\uac00 \uc5c6\ub3c4\ub85d \ub370\uc774\ud130 \ub9ac\uc2a4\ub108\ub97c \uc124\uc815\ud560 \ub54c \ub9e4\uc6b0 \ud6a8\uacfc\uc801\uc785\ub2c8\ub2e4. \uc774\uc81c \ud504\ub85c\uc81d\ud2b8\uc758 <strong>src\/main\/java\/com\/couchbase\/CouchbaseSingleton.java<\/strong> \ud30c\uc77c\uc744 \uc5f4\uace0 \ub2e4\uc74c \ucf54\ub4dc\ub97c \ud3ec\ud568\ud558\uc138\uc694. \ub098\uc911\uc5d0 \uc790\uc138\ud788 \uc124\uba85\ud558\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code>\r\npackage com.couchbase;\r\n\r\nimport com.couchbase.lite.*;\r\nimport com.couchbase.lite.replicator.Replication;\r\n\r\nimport java.net.URL;\r\nimport java.util.ArrayList;\r\nimport java.util.HashMap;\r\nimport java.util.Iterator;\r\nimport java.util.Map;\r\n\r\npublic class CouchbaseSingleton {\r\n\r\n    private Manager manager;\r\n    private Database database;\r\n    private Replication pushReplication;\r\n    private Replication pullReplication;\r\n\r\n    private static CouchbaseSingleton instance = null;\r\n\r\n    private CouchbaseSingleton() {\r\n        try {\r\n            this.manager = new Manager(new JavaContext(\"data\"), Manager.DEFAULT_OPTIONS);\r\n            this.database = this.manager.getDatabase(\"fx-project\");\r\n            View todoView = database.getView(\"todos\");\r\n            todoView.setMap(new Mapper() {\r\n                @Override\r\n                public void map(Map&lt;String, Object&gt; document, Emitter emitter) {\r\n                    emitter.emit(document.get(\"_id\"), document);\r\n                }\r\n            }, \"1\");\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n    public static CouchbaseSingleton getInstance() {\r\n        if(instance == null) {\r\n            instance = new CouchbaseSingleton();\r\n        }\r\n        return instance;\r\n    }\r\n\r\n    public Database getDatabase() {\r\n        return this.database;\r\n    }\r\n\r\n    public void startReplication(URL gateway, boolean continuous) {\r\n        this.pushReplication = this.database.createPushReplication(gateway);\r\n        this.pullReplication = this.database.createPullReplication(gateway);\r\n        this.pushReplication.setContinuous(continuous);\r\n        this.pullReplication.setContinuous(continuous);\r\n        this.pushReplication.start();\r\n        this.pullReplication.start();\r\n    }\r\n\r\n    public void stopReplication() {\r\n        this.pushReplication.stop();\r\n        this.pullReplication.stop();\r\n    }\r\n\r\n    public Todo save(Todo todo) {\r\n        Map&lt;String, Object&gt; properties = new HashMap&lt;String, Object&gt;();\r\n        Document document = this.database.createDocument();\r\n        properties.put(\"type\", \"todo\");\r\n        properties.put(\"title\", todo.getTitle());\r\n        properties.put(\"description\", todo.getDescription());\r\n        try {\r\n            todo.setDocumentId(document.putProperties(properties).getDocument().getId());\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n        return todo;\r\n    }\r\n\r\n    public ArrayList query() {\r\n        ArrayList results = new ArrayList();\r\n        try {\r\n            View todoView = this.database.getView(\"todos\");\r\n            Query query = todoView.createQuery();\r\n            QueryEnumerator result = query.run();\r\n            Document document = null;\r\n            for (Iterator it = result; it.hasNext(); ) {\r\n                QueryRow row = it.next();\r\n                document = row.getDocument();\r\n                results.add(new Todo(document.getId(), (String) document.getProperty(\"title\"), (String) document.getProperty(\"description\")));\r\n            }\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n        return results;\r\n    }\r\n\r\n}\r\n<\/code><\/pre>\n<p>\uc704\uc758 \ub0b4\uc6a9\uc740 \uc774\ud574\ud558\uae30 \uc5b4\ub824\uc6b4 \ub0b4\uc6a9\uc774\uc9c0\ub9cc \ud63c\ub780\uc744 \ud53c\ud558\uae30 \uc704\ud574 \uaf2d \ud544\uc694\ud55c \ub0b4\uc6a9\uc785\ub2c8\ub2e4.<\/p>\n<p>\ub0b4\ubd80 <code>\uce74\uc6b0\uce58\ubca0\uc774\uc2a4\uc2f1\uae00\ud134<\/code> \ud074\ub798\uc2a4\uc5d0\ub294 4\uac1c\uc758 \uac1c\uc778 \ubcc0\uc218\uac00 \uc788\uc2b5\ub2c8\ub2e4. \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uad00\ub9ac\uc790\ub97c \uc0ac\uc6a9\ud558\uba74 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub97c \uc5f4 \uc218 \uc788\uc744 \ubfd0\ub9cc \uc544\ub2c8\ub77c \uc0dd\uc131\ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \ubcf5\uc81c \uac1d\uccb4\ub294 \uc5b4\ub290 \ubc29\ud5a5\uc73c\ub85c\ub4e0 \ub3d9\uae30\ud654\ub97c \ub2f4\ub2f9\ud569\ub2c8\ub2e4.<\/p>\n<p>\uc5d0\uc11c <code>\uc0dd\uc131\uc790<\/code> \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub2e4\uc74c\uacfc \uac19\uc740 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub97c \uc0dd\uc131\ud558\uace0 \uc5fd\ub2c8\ub2e4. <strong>fx-project<\/strong> \ub97c \ud074\ub9ad\ud558\uace0 \ub370\uc774\ud130 \ucffc\ub9ac \uc2dc \uc0ac\uc6a9\ud560 \ubdf0\ub97c \uad6c\uc131\ud569\ub2c8\ub2e4. \uc774 \ubdf0\ub294 <code>\ud1a0\ub3c4\uc2a4<\/code> \ub294 \ub85c\uceec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ub41c \ubaa8\ub4e0 \ubb38\uc11c\uc5d0 \ub300\ud574 \ubb38\uc11c ID\uc640 \ubb38\uc11c\uc758 \ud0a4-\uac12 \uc30d\uc744 \uc0dd\uc131\ud569\ub2c8\ub2e4. \ub85c\uceec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ub41c \ubaa8\ub4e0 \ubb38\uc11c\uc758 <code>\uc0dd\uc131\uc790<\/code> \uba54\uc11c\ub4dc\ub294 \uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \uc778\uc2a4\ud134\uc2a4\ud654\ud558\uae30 \ub54c\ubb38\uc5d0 \ube44\uacf5\uac1c\uc785\ub2c8\ub2e4. <code>getInstance<\/code>.<\/p>\n<p>\uc774 \uac00\uc774\ub4dc\uc758 \ud6c4\ubc18\ubd80\uae4c\uc9c0 \ub3d9\uae30\ud654\uc5d0 \ub300\ud574 \uc0b4\ud3b4\ubcf4\uc9c0\ub294 \uc54a\uaca0\uc9c0\ub9cc, \uae30\ucd08\ub97c \ub2e4\uc9c0\ub294 \uac83\uc740 \uc88b\uc740 \uc0dd\uac01\uc785\ub2c8\ub2e4. \uae30\ubcf8\uc801\uc73c\ub85c \ud2b9\uc815 \ub3d9\uae30\ud654 \uac8c\uc774\ud2b8\uc6e8\uc774 URL\uc5d0 \ub300\ud55c \uc9c0\uc18d\uc801\uc778 \ubcf5\uc81c\ub97c \uc815\uc758\ud558\uace0 \uc2f6\uc744 \ubfd0\uc785\ub2c8\ub2e4. \ub610\ud55c \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \uc885\ub8cc\ub420 \ub54c \ubcf5\uc81c\ub97c \uc911\uc9c0\ud560 \uc218 \uc788\uae30\ub97c \uc6d0\ud569\ub2c8\ub2e4. \uc774\uc81c \ub370\uc774\ud130\ub97c \uc800\uc7a5\ud558\uace0 \ub85c\ub4dc\ud558\ub294 \ubc29\ubc95\uc744 \uc0b4\ud3b4\ubd05\uc2dc\ub2e4.<\/p>\n<pre><code>\r\npublic Todo save(Todo todo) {\r\n    Map&lt;String, Object&gt; properties = new HashMap&lt;String, Object&gt;();\r\n    Document document = this.database.createDocument();\r\n    properties.put(\"type\", \"todo\");\r\n    properties.put(\"title\", todo.getTitle());\r\n    properties.put(\"description\", todo.getDescription());\r\n    try {\r\n        todo.setDocumentId(document.putProperties(properties).getDocument().getId());\r\n    } catch (Exception e) {\r\n        e.printStackTrace();\r\n    }\r\n    return todo;\r\n}\r\n<\/code><\/pre>\n<p>\uc6b0\ub9ac\uc758 <code>\uc800\uc7a5<\/code> \uba54\uc11c\ub4dc\ub294 <code>Todo<\/code> \uac1d\uccb4\ub97c \uc0dd\uc131\ud558\uace0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud569\ub2c8\ub2e4. \uadf8 \uacb0\uacfc\ub294 <code>Todo<\/code> \ud638\ucd9c \uba54\uc11c\ub4dc\uc5d0 \ubc18\ud658\ub418\ub294 \ubb38\uc11c ID\uac00 \ud3ec\ud568\ub41c \uac1d\uccb4\uc785\ub2c8\ub2e4. \uc774 <code>Todo<\/code> \ud074\ub798\uc2a4\ub294 \uac04\ub2e8\ud569\ub2c8\ub2e4. \uc544\uc774\ub514, \uc81c\ubaa9, \uc124\uba85\uacfc \uac19\uc740 \uae30\ubcf8 \uc815\ubcf4\ub97c \ubc1b\uc544\ub4e4\uc774\uace0 \uadf8\uc5d0 \ub9de\ub294 \uc801\uc808\ud55c \uac9f\ud130\uc640 \uc138\ud130 \uba54\uc11c\ub4dc\uac00 \uc788\uc2b5\ub2c8\ub2e4. \ucc38\uace0\ub85c \ub2e4\uc74c\uacfc \uac19\uc740 \ubaa8\uc591\uc774\uba70 \ud504\ub85c\uc81d\ud2b8\uc758 <strong>src\/main\/java\/com\/couchbase\/Todo.java<\/strong> \ud30c\uc77c\uc744 \ub9cc\ub4ed\ub2c8\ub2e4.<\/p>\n<pre><code>\r\npackage com.couchbase;\r\n\r\nimport java.util.*;\r\n\r\npublic class Todo {\r\n\r\n    private String documentId;\r\n    private String title;\r\n    private String description;\r\n\r\n    Todo(String documentId, String title, String description) {\r\n        this.documentId = documentId;\r\n        this.title = title;\r\n        this.description = description;\r\n    }\r\n\r\n    Todo(String title, String description) {\r\n        this.documentId = UUID.randomUUID().toString();\r\n        this.title = title;\r\n        this.description = description;\r\n    }\r\n\r\n    public void setDocumentId(String documentId) {\r\n        this.documentId = documentId;\r\n    }\r\n\r\n    public String getDocumentId() {\r\n        return this.documentId;\r\n    }\r\n\r\n    public String getTitle() {\r\n        return this.title;\r\n    }\r\n\r\n    public String getDescription() {\r\n        return this.description;\r\n    }\r\n\r\n}\r\n<\/code><\/pre>\n<p>\uc774\uc81c \ub9c8\uc9c0\ub9c9 \ub370\uc774\ud130 \uad00\ub828 \ud568\uc218\uc778 <code>\ucffc\ub9ac<\/code> \ud568\uc218\uc785\ub2c8\ub2e4.<\/p>\n<pre><code>\r\npublic ArrayList query() {\r\n    ArrayList results = new ArrayList();\r\n    try {\r\n        View todoView = this.database.getView(\"todos\");\r\n        Query query = todoView.createQuery();\r\n        QueryEnumerator result = query.run();\r\n        Document document = null;\r\n        for (Iterator it = result; it.hasNext(); ) {\r\n            QueryRow row = it.next();\r\n            document = row.getDocument();\r\n            results.add(new Todo(document.getId(), (String) document.getProperty(\"title\"), (String) document.getProperty(\"description\")));\r\n        }\r\n    } catch (Exception e) {\r\n        e.printStackTrace();\r\n    }\r\n    return results;\r\n}\r\n<\/code><\/pre>\n<p>\uc6b0\ub9ac\uac00 \ub9cc\ub4e0 \ubdf0\ub97c \uae30\uc5b5\ud558\uc2dc\ub098\uc694? \uc774\ubc88\uc5d0\ub294 \uc774\ub97c \ucffc\ub9ac\ud574 \ubcf4\uaca0\uc2b5\ub2c8\ub2e4. \uacb0\uacfc \uc9d1\ud569\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ubc30\uc5f4\ub85c \ub85c\ub4dc\ub429\ub2c8\ub2e4. <code>Todo<\/code> \uac1d\uccb4\uc785\ub2c8\ub2e4. \uc774\ub807\uac8c \ud558\uba74 <a href=\"https:\/\/www.couchbase.com\/blog\/ko\/resources\/concepts\/data-platforms\/\">\ub370\uc774\ud130 \uacc4\uce35<\/a> \ub97c \ub9c8\ubb34\ub9ac\ud558\uace0 \uc2e4\uc81c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uac1c\ubc1c\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\uac8c \ub418\uc5c8\uc2b5\ub2c8\ub2e4.<\/p>\n<h2>\ub370\uc2a4\ud06c\ud1b1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub514\uc790\uc778<\/h2>\n<p>\ud544\uc218\ub294 \uc544\ub2c8\uc9c0\ub9cc JavaFX \uc560\ud50c\ub9ac\ucf00\uc774\uc158, <strong>\uc52c \ube4c\ub354<\/strong>\ub97c \uc0ac\uc6a9\ud558\uba74 \uadf8\ub798\ud53d UI\uc640 \ud574\ub2f9 \ucee8\ud2b8\ub864\ub7ec \ud074\ub798\uc2a4\ub97c \ub9e4\uc6b0 \uac04\ub2e8\ud558\uac8c \ub9cc\ub4e4 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc73c\ub824\uba74 \ud504\ub85c\uc81d\ud2b8\uc758 <strong>src\/main\/resources\/TodoFX.fxml<\/strong> \ub97c \uc5f4\uace0 \ub2e4\uc74c XML \ub9c8\ud06c\uc5c5\uc744 \ud3ec\ud568\ud569\ub2c8\ub2e4:<\/p>\n<pre><code>\r\n<!--?xml version=\"1.0\" encoding=\"UTF-8\"?-->\r\n\r\n<!--?import javafx.scene.control.*?-->\r\n<!--?import java.lang.*?-->\r\n<!--?import javafx.scene.layout.*?-->\r\n\r\n\r\n   \r\n      \r\n      \r\n      <textarea>      &lt;Button fx:id=\"fxSave\" layoutX=\"530.0\" layoutY=\"365.0\" mnemonicParsing=\"false\" prefHeight=\"25.0\" prefWidth=\"60.0\" text=\"Save\" \/&gt;\r\n   &lt;\/children&gt;\r\n&lt;\/Pane&gt;\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;The above markup will give us a UI that looks like the following:&lt;\/p&gt;\r\n&lt;p&gt;&lt;img src=\"\/wp-content\/original-assets\/2016\/september\/using-couchbase-in-a-javafx-desktop-application\/todo-javafx-example.png\" \/&gt;&lt;\/p&gt;\r\n&lt;p&gt;Nothing too fancy in the above, correct?&lt;\/p&gt;\r\n&lt;p&gt;We have a simple UI with a list, two input fields, and a save button, as described in the XML markup. In the markup we also reference &lt;code&gt;com.couchbase.TodoFXController&lt;\/code&gt;. This is the logic that will be bound to the particular FX view. Open the project's &lt;strong&gt;src\/main\/java\/com\/couchbase\/TodoFXController.java&lt;\/strong&gt; and include the following:&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\npackage com.couchbase;\r\n\r\nimport com.couchbase.lite.*;\r\nimport com.couchbase.lite.Database.ChangeListener;\r\nimport javafx.application.Platform;\r\nimport javafx.collections.ObservableList;\r\nimport javafx.event.ActionEvent;\r\nimport javafx.event.EventHandler;\r\nimport javafx.fxml.FXML;\r\nimport javafx.fxml.Initializable;\r\nimport javafx.scene.control.*;\r\nimport javafx.util.Callback;\r\n\r\nimport java.net.URL;\r\nimport java.util.*;\r\n\r\npublic class TodoFXController implements Initializable {\r\n\r\n    private CouchbaseSingleton couchbase;\r\n\r\n    @FXML\r\n    private TextField fxTitle;\r\n\r\n    @FXML\r\n    private TextArea fxDescription;\r\n\r\n    @FXML\r\n    private ListView fxListView;\r\n\r\n    @FXML\r\n    private Button fxSave;\r\n\r\n    @Override\r\n    public void initialize(URL fxmlFileLocation, ResourceBundle resources) {\r\n        try {\r\n            this.couchbase = CouchbaseSingleton.getInstance();\r\n            fxListView.getItems().addAll(this.couchbase.query());\r\n            this.couchbase.getDatabase().addChangeListener(new ChangeListener() {\r\n                @Override\r\n                public void changed(Database.ChangeEvent event) {\r\n                    for(int i = 0; i &lt; event.getChanges().size(); i++) {\r\n                        final Document retrievedDocument = couchbase.getDatabase().getDocument(event.getChanges().get(i).getDocumentId());\r\n                        Platform.runLater(new Runnable() {\r\n                            @Override\r\n                            public void run() {\r\n                                int documentIndex = indexOfByDocumentId(retrievedDocument.getId(), fxListView.getItems());\r\n                                for(int j = 0; j &lt; fxListView.getItems().size(); j++) { if(((Todo)fxListView.getItems().get(j)).getDocumentId().equals(retrievedDocument.getId())) { documentIndex = j; break; } } if (retrievedDocument.isDeleted()) { if (documentIndex &gt; -1) {\r\n                                        fxListView.getItems().remove(documentIndex);\r\n                                    }\r\n                                } else {\r\n                                    if (documentIndex == -1) {\r\n                                        fxListView.getItems().add(new Todo(retrievedDocument.getId(), (String) retrievedDocument.getProperty(\"title\"), (String) retrievedDocument.getProperty(\"description\")));\r\n                                    } else {\r\n                                        fxListView.getItems().remove(documentIndex);\r\n                                        fxListView.getItems().add(new Todo(retrievedDocument.getId(), (String) retrievedDocument.getProperty(\"title\"), (String) retrievedDocument.getProperty(\"description\")));\r\n                                    }\r\n                                }\r\n                            }\r\n                        });\r\n                    }\r\n                }\r\n            });\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n        fxListView.setCellFactory(new Callback&lt;ListView&lt;Todo&gt;, ListCell&lt;Todo&gt;&gt;(){\r\n            @Override\r\n            public ListCell&lt;Todo&gt; call(ListView&lt;Todo&gt; p) {\r\n                ListCell&lt;Todo&gt; cell = new ListCell&lt;Todo&gt;(){\r\n                    @Override\r\n                    protected void updateItem(Todo t, boolean bln) {\r\n                        super.updateItem(t, bln);\r\n                        if (t != null) {\r\n                            setText(t.getTitle());\r\n                        }\r\n                    }\r\n                };\r\n                return cell;\r\n            }\r\n        });\r\n        fxSave.setOnAction(new EventHandler&lt;ActionEvent&gt;() {\r\n            @Override public void handle(ActionEvent e) {\r\n                if(!fxTitle.getText().equals(\"\") &amp;&amp; !fxDescription.getText().equals(\"\")) {\r\n                    fxListView.getItems().add(couchbase.save(new Todo(fxTitle.getText(), fxDescription.getText())));\r\n                    fxTitle.setText(\"\");\r\n                    fxDescription.setText(\"\");\r\n                } else {\r\n                    Alert alert = new Alert(Alert.AlertType.INFORMATION);\r\n                    alert.setTitle(\"Missing Information\");\r\n                    alert.setHeaderText(null);\r\n                    alert.setContentText(\"Both a title and description are required for this example.\");\r\n                    alert.showAndWait();\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    private int indexOfByDocumentId(String needle, ObservableList&lt;Todo&gt; haystack) {\r\n        int result = -1;\r\n        for(int i = 0; i &lt; haystack.size(); i++) {\r\n            if(haystack.get(i).getDocumentId().equals(needle)) {\r\n                result = i;\r\n                break;\r\n            }\r\n        }\r\n        return result;\r\n    }\r\n\r\n}\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;There is a lot to take in when it comes to the above code, so we're going to break it down.&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\n@FXML\r\nprivate TextField fxTitle;\r\n\r\n@FXML\r\nprivate TextArea fxDescription;\r\n\r\n@FXML\r\nprivate ListView fxListView;\r\n\r\n@FXML\r\nprivate Button fxSave;\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;Remember the FXML file? Each of the above variables are mapped to the components of that file. However, what we really care about is the use of the &lt;code&gt;Initializable&lt;\/code&gt; interface that we're implementing. This requires an &lt;code&gt;initialize&lt;\/code&gt; function where we'll setup our component and database listeners.&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\nfxListView.setCellFactory(new Callback&lt;ListView&lt;Todo&gt;, ListCell&lt;Todo&gt;&gt;(){\r\n    @Override\r\n    public ListCell&lt;Todo&gt; call(ListView&lt;Todo&gt; p) {\r\n        ListCell&lt;Todo&gt; cell = new ListCell&lt;Todo&gt;(){\r\n            @Override\r\n            protected void updateItem(Todo t, boolean bln) {\r\n                super.updateItem(t, bln);\r\n                if (t != null) {\r\n                    setText(t.getTitle());\r\n                }\r\n            }\r\n        };\r\n        return cell;\r\n    }\r\n});\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;Because we're using a custom &lt;code&gt;Todo&lt;\/code&gt; class in our list, we need to configure how the list rows show data. By default they are strings, but we actually want to extract the title of any of our data elements and show that instead.&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\nthis.couchbase = CouchbaseSingleton.getInstance();\r\nfxListView.getItems().addAll(this.couchbase.query());\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;In the above we are obtaining the open database instance, performing a query, and adding all the data to the FX list that is on the screen. This is a one time thing that is done when the application loads. All future data loads are done through a data listener.&lt;\/p&gt;\r\n&lt;p&gt;The database change listener will listen for all changes in data for as long as the application is open. The changes can happen in bulk, so we loop through the changes and retrieve the documents. If the document is new, add it to the list. If the document has a deleted indicator, remove it from the list. If the document is a change to an existing document, remove the old and add the new one to the list. This is all done in a &lt;code&gt;Platform.runLater&lt;\/code&gt; because the Couchbase change listener happens on a background thread. The changes to the UI must be done on the main thread.&lt;\/p&gt;\r\n&lt;p&gt;Finally we have our save button that has its own click event. If clicked, and the input elements are populated, save the data to the database.&lt;\/p&gt;\r\n&lt;p&gt;As of right now, we have an offline desktop application that saves data in Couchbase Lite. Now we can worry about data synchronization \/ replication.&lt;\/p&gt;\r\n&lt;h2&gt;Synchronizing Data Between Desktop and Server&lt;\/h2&gt;\r\n&lt;p&gt;The next part is easy thanks to Couchbase Mobile. You will need Couchbase Sync Gateway up and running before we start messing with the desktop application code. With Sync Gateway installed, create the following basic configuration file:&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\n{\r\n    \"log\":[\"CRUD+\", \"REST+\", \"Changes+\", \"Attach+\"],\r\n    \"databases\": {\r\n        \"fx-example\": {\r\n            \"server\":\"walrus:\",\r\n            \"sync\":`\r\n                function (doc) {\r\n                    channel (doc.channels);\r\n                }\r\n            `,\r\n            \"users\": {\r\n                \"GUEST\": {\r\n                    \"disabled\": false,\r\n                    \"admin_channels\": [\"*\"]\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;The above configuration file is pretty much as basic as you can get. Create an &lt;code&gt;fx-project&lt;\/code&gt; partition with no read \/ write rules using the in-memory database. Note we're not using Couchbase Server here, but we could. Run this configuration file with Sync Gateway.&lt;\/p&gt;\r\n&lt;p&gt;Bouncing back into the JavaFX application. Open the project's &lt;strong&gt;src\/main\/java\/com\/couchbase\/Main.java&lt;\/strong&gt; file and include the following:&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\nthis.couchbase = CouchbaseSingleton.getInstance();\r\nthis.couchbase.startReplication(new URL(\"https:\/\/localhost:4984\/fx-example\/\"), true);\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;The above should be included in the &lt;code&gt;start&lt;\/code&gt; method. It will start the bi-directional replication process to our now running Sync Gateway instance.&lt;\/p&gt;\r\n&lt;h2&gt;Conclusion&lt;\/h2&gt;\r\n&lt;p&gt;You just saw how to create a simple JavaFX application that stores data in Couchbase Lite and synchronizes the data. To run this application using Maven and the command line, execute the following:&lt;\/p&gt;\r\n&lt;pre&gt;\r\n&lt;code&gt;\r\nmvn jfx:run\r\n&lt;\/code&gt;\r\n&lt;\/pre&gt;\r\n&lt;p&gt;Because Couchbase is so flexible, this same application can be extended to mobile with very few changes to the application code. If you'd like to download the full project in this guide, it can be found on GitHub &lt;a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-lite-javafx-example\"&gt;here&lt;\/a&gt;.&lt;\/p&gt;\r\n<\/textarea><\/code><\/pre>","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve spent quite a bit of time dabbling with Couchbase and web applications using the awesome Java SDK, but did you know you can create desktop applications that use Couchbase to store data as well? Java desktop frameworks like JavaFX [&hellip;]<\/p>","protected":false},"author":63,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1810,1818,2366],"tags":[1575],"ppma_author":[9032],"class_list":["post-2385","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-mobile","category-java","category-sync-gateway","tag-desktop"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.5 (Yoast SEO v26.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using Couchbase in a JavaFX Desktop Application - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/ko\/using-couchbase-in-a-javafx-desktop-application\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using Couchbase in a JavaFX Desktop Application\" \/>\n<meta property=\"og:description\" content=\"I&#8217;ve spent quite a bit of time dabbling with Couchbase and web applications using the awesome Java SDK, but did you know you can create desktop applications that use Couchbase to store data as well? Java desktop frameworks like JavaFX [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/ko\/using-couchbase-in-a-javafx-desktop-application\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/thepolyglotdeveloper\" \/>\n<meta property=\"article:published_time\" content=\"2016-09-13T15:00:01+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T02:56:31+00:00\" \/>\n<meta name=\"author\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4\ubd84\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Using Couchbase in a JavaFX Desktop Application\",\"datePublished\":\"2016-09-13T15:00:01+00:00\",\"dateModified\":\"2025-06-14T02:56:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/\"},\"wordCount\":828,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"desktop\"],\"articleSection\":[\"Couchbase Mobile\",\"Java\",\"Sync Gateway\"],\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/\",\"name\":\"Using Couchbase in a JavaFX Desktop Application - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2016-09-13T15:00:01+00:00\",\"dateModified\":\"2025-06-14T02:56:31+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using Couchbase in a JavaFX Desktop Application\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ko-KR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\",\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy, Developer Advocate, Couchbase\"},\"description\":\"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.\",\"sameAs\":[\"https:\/\/www.thepolyglotdeveloper.com\",\"https:\/\/www.facebook.com\/thepolyglotdeveloper\",\"https:\/\/x.com\/nraboy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/ko\/author\/nic-raboy-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Using Couchbase in a JavaFX Desktop Application - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/ko\/using-couchbase-in-a-javafx-desktop-application\/","og_locale":"ko_KR","og_type":"article","og_title":"Using Couchbase in a JavaFX Desktop Application","og_description":"I&#8217;ve spent quite a bit of time dabbling with Couchbase and web applications using the awesome Java SDK, but did you know you can create desktop applications that use Couchbase to store data as well? Java desktop frameworks like JavaFX [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/ko\/using-couchbase-in-a-javafx-desktop-application\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2016-09-13T15:00:01+00:00","article_modified_time":"2025-06-14T02:56:31+00:00","author":"Nic Raboy, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_misc":{"Written by":"Nic Raboy, Developer Advocate, Couchbase","Est. reading time":"4\ubd84"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Using Couchbase in a JavaFX Desktop Application","datePublished":"2016-09-13T15:00:01+00:00","dateModified":"2025-06-14T02:56:31+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/"},"wordCount":828,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["desktop"],"articleSection":["Couchbase Mobile","Java","Sync Gateway"],"inLanguage":"ko-KR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/","url":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/","name":"Using Couchbase in a JavaFX Desktop Application - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2016-09-13T15:00:01+00:00","dateModified":"2025-06-14T02:56:31+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/"]}]},{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-a-javafx-desktop-application\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using Couchbase in a JavaFX Desktop Application"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","description":"NoSQL \ub370\uc774\ud130\ubca0\uc774\uc2a4, Couchbase","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ko-KR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1","name":"Nic Raboy, \uac1c\ubc1c\uc790 \uc639\ud638\uc790, Couchbase","image":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354","url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","caption":"Nic Raboy, Developer Advocate, Couchbase"},"description":"\ub2c9 \ub77c\ubcf4\uc774\ub294 \ucd5c\uc2e0 \uc6f9 \ubc0f \ubaa8\ubc14\uc77c \uac1c\ubc1c \uae30\uc220\uc744 \uc639\ud638\ud558\ub294 \uc0ac\ub78c\uc785\ub2c8\ub2e4. \uadf8\ub294 Java, JavaScript, Golang \ubc0f Angular, NativeScript, Apache Cordova\uc640 \uac19\uc740 \ub2e4\uc591\ud55c \ud504\ub808\uc784\uc6cc\ud06c\uc5d0 \ub300\ud55c \uacbd\ud5d8\uc774 \uc788\uc2b5\ub2c8\ub2e4. Nic\uc740 \uc6f9 \ubc0f \ubaa8\ubc14\uc77c \uac1c\ubc1c\uc744 \ubcf4\ub2e4 \uc27d\uac8c \uc774\ud574\ud560 \uc218 \uc788\ub3c4\ub85d \uc790\uc2e0\uc758 \uac1c\ubc1c \uacbd\ud5d8\uc5d0 \ub300\ud574 \uae00\uc744 \uc4f0\uace0 \uc788\uc2b5\ub2c8\ub2e4.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/ko\/author\/nic-raboy-2\/"}]}},"authors":[{"term_id":9032,"user_id":63,"is_guest":0,"slug":"nic-raboy-2","display_name":"Nic Raboy, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","author_category":"","last_name":"Raboy","first_name":"Nic","job_title":"","user_url":"https:\/\/www.thepolyglotdeveloper.com","description":"\ub2c9 \ub77c\ubcf4\uc774\ub294 \ucd5c\uc2e0 \uc6f9 \ubc0f \ubaa8\ubc14\uc77c \uac1c\ubc1c \uae30\uc220\uc744 \uc639\ud638\ud558\ub294 \uc0ac\ub78c\uc785\ub2c8\ub2e4. \uadf8\ub294 Java, JavaScript, Golang \ubc0f Angular, NativeScript, Apache Cordova\uc640 \uac19\uc740 \ub2e4\uc591\ud55c \ud504\ub808\uc784\uc6cc\ud06c\uc5d0 \ub300\ud55c \uacbd\ud5d8\uc774 \uc788\uc2b5\ub2c8\ub2e4. Nic\uc740 \uc6f9 \ubc0f \ubaa8\ubc14\uc77c \uac1c\ubc1c\uc744 \ubcf4\ub2e4 \uc27d\uac8c \uc774\ud574\ud560 \uc218 \uc788\ub3c4\ub85d \uc790\uc2e0\uc758 \uac1c\ubc1c \uacbd\ud5d8\uc5d0 \ub300\ud574 \uae00\uc744 \uc4f0\uace0 \uc788\uc2b5\ub2c8\ub2e4."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts\/2385","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/comments?post=2385"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts\/2385\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/media?parent=2385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/categories?post=2385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/tags?post=2385"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/ppma_author?post=2385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}