如何使用 Gluon 在 Android 平台上将 H2 数据库连接为嵌入式模式?

Posted

技术标签:

【中文标题】如何使用 Gluon 在 Android 平台上将 H2 数据库连接为嵌入式模式?【英文标题】:How can I connect H2 database as embedded mode on Android platform by using Gluon? 【发布时间】:2018-07-10 09:49:16 【问题描述】:

我想使用 H2 数据库在我的 Gluon Mobile 应用程序上存储数据库。我试过 JDBC 它在桌面版本上运行良好。但我在 android 上失败了(org.h2.jdbc.JdbcSQLException:创建文件时出错)。

我已经更改连接,如下面的 url,但不是运气 http://www.h2database.com/html/tutorial.html#android

已编辑以添加 gradle

我的代码

try 
            Connection connection=null;

            lbError.setText("");
            lbError.setVisible(false);
            System.out.println("Label="+ label.getText());
            //step1 load the driver class
            Class.forName(DB_DRIVER).newInstance();
            //step2 create  the connection object

             if(Platform.isDesktop())
                 connection=DriverManager.getConnection(DB_CONNECTION,DB_USER,DB_PASSWORD);
             if(Platform.isAndroid())
                connection = DriverManager.getConnection(DB_CONNECTION_ANDROID,DB_USER,DB_PASSWORD);

            System.out.print("DATABASE Create");
            //step3 create the statement object
            Statement statement = connection.createStatement();
            String sql="DROP TABLE IF EXISTS contact;\n" +
                        "CREATE TABLE contact(\n" +
                        "        Id INT NOT NULL AUTO_INCREMENT,\n" +
                        "        Name VARCHAR(255) NOT NULL,\n" +
                        "        Email VARCHAR(255) NOT NULL UNIQUE,\n" +
                        "        PRIMARY KEY (ID)\n" +
                        ");";
            System.out.println("SQL="+"\n"+sql);

            //step4 execute query
            statement.executeUpdate(sql);
            System.out.println("Table Created");
         catch (Exception e) 

            System.out.println("Error Line is here");
            lbError.setText(e.toString());
            lbError.setVisible(true);
            e.printStackTrace();
        

堆栈跟踪:

07-10 10:30:38.770 30397 30435 W System.err: org.h2.jdbc.JdbcSQLException: Error while creating file "/data/data/com.khmerdev.views" [90062-196]
07-10 10:30:38.771 30397 30435 W System.err:    at org.h2.store.fs.FilePathDisk.createDirectory(FilePathDisk.java:274)
07-10 10:30:38.772 30397 30435 W System.err:    at org.h2.store.fs.FileUtils.createDirectory(FileUtils.java:42)
07-10 10:30:38.772 30397 30435 W System.err:    at org.h2.store.fs.FileUtils.createDirectories(FileUtils.java:309)
07-10 10:30:38.772 30397 30435 W System.err:    at org.h2.store.fs.FileUtils.createDirectories(FileUtils.java:308)
07-10 10:30:38.772 30397 30435 W System.err:    at org.h2.mvstore.db.MVTableEngine.init(MVTableEngine.java:74)
07-10 10:30:38.772 30397 30435 W System.err:    at org.h2.engine.Database.getPageStore(Database.java:2476)
07-10 10:30:38.772 30397 30435 W System.err:    at org.h2.engine.Database.open(Database.java:697)
07-10 10:30:38.772 30397 30435 W System.err:    at org.h2.engine.Database.openDatabase(Database.java:276)
07-10 10:30:38.772 30397 30435 W System.err:    at org.h2.engine.Database.<init>(Database.java:270)
07-10 10:30:38.772 30397 30435 W System.err:    at org.h2.engine.Engine.openSession(Engine.java:64)
07-10 10:30:38.773 30397 30435 W System.err:    at org.h2.engine.Engine.openSession(Engine.java:176)
07-10 10:30:38.773 30397 30435 W System.err:    at org.h2.engine.Engine.createSessionAndValidate(Engine.java:154)
07-10 10:30:38.773 30397 30435 W System.err:    at org.h2.engine.Engine.createSession(Engine.java:137)
07-10 10:30:38.773 30397 30435 W System.err:    at org.h2.engine.Engine.createSession(Engine.java:27)
07-10 10:30:38.773 30397 30435 W System.err:    at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:354)
07-10 10:30:38.773 30397 30435 W System.err:    at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:116)
07-10 10:30:38.773 30397 30435 W System.err:    at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:100)
07-10 10:30:38.773 30397 30435 W System.err:    at org.h2.Driver.connect(Driver.java:69)
07-10 10:30:38.773 30397 30435 W System.err:    at java.sql.DriverManager.getConnection(DriverManager.java:569)
07-10 10:30:38.773 30397 30435 W System.err:    at java.sql.DriverManager.getConnection(DriverManager.java:219)
07-10 10:30:38.773 30397 30435 W System.err:    at com.khmerdev.views.ContactPresenter.initDB(ContactPresenter.java:75)
07-10 10:30:38.773 30397 30435 W System.err:    at com.khmerdev.views.ContactPresenter.initialize(ContactPresenter.java:53)
07-10 10:30:38.774 30397 30435 W System.err:    at java.lang.reflect.Method.invoke(Native Method)
07-10 10:30:38.774 30397 30435 W System.err:    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
07-10 10:30:38.774 30397 30435 W System.err:    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:277)
07-10 10:30:38.774 30397 30435 W System.err:    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2566)
07-10 10:30:38.774 30397 30435 W System.err:    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
07-10 10:30:38.774 30397 30435 W System.err:    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
07-10 10:30:38.774 30397 30435 W System.err:    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
07-10 10:30:38.774 30397 30435 W System.err:    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
07-10 10:30:38.774 30397 30435 W System.err:    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
07-10 10:30:38.774 30397 30435 W System.err:    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
07-10 10:30:38.774 30397 30435 W System.err:    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
07-10 10:30:38.774 30397 30435 W System.err:    at com.khmerdev.views.ContactView.getView(ContactView.java:11)
07-10 10:30:38.774 30397 30435 W System.err:    at com.khmerdev.GluonApplication.lambda$init$0(GluonApplication.java:19)
07-10 10:30:38.775 30397 30435 W System.err:    at com.khmerdev.GluonApplication$$Lambda$1.get(GluonApplication.java)
07-10 10:30:38.775 30397 30435 W System.err:    at com.gluonhq.impl.charm.a.a.a.a(SourceFile:1032)
07-10 10:30:38.775 30397 30435 W System.err:    at com.gluonhq.charm.glisten.application.MobileApplication.a(SourceFile:721)
07-10 10:30:38.775 30397 30435 W System.err:    at com.gluonhq.charm.glisten.application.MobileApplication.switchView(SourceFile:475)
07-10 10:30:38.775 30397 30435 W System.err:    at com.gluonhq.charm.glisten.application.MobileApplication.switchView(SourceFile:450)
07-10 10:30:38.775 30397 30435 W System.err:    at com.gluonhq.charm.glisten.application.MobileApplication.a(SourceFile:266)
07-10 10:30:38.775 30397 30435 W System.err:    at com.gluonhq.charm.glisten.application.MobileApplication.start(SourceFile:232)
07-10 10:30:38.775 30397 30435 W System.err:    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$145(LauncherImpl.java:863)
07-10 10:30:38.775 30397 30435 W System.err:    at com.sun.javafx.application.LauncherImpl.access$lambda$8(LauncherImpl.java)
07-10 10:30:38.775 30397 30435 W System.err:    at com.sun.javafx.application.LauncherImpl$$Lambda$9.run(Unknown Source)
07-10 10:30:38.775 30397 30435 W System.err:    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$158(PlatformImpl.java:326)
07-10 10:30:38.775 30397 30435 W System.err:    at com.sun.javafx.application.PlatformImpl.access$lambda$6(PlatformImpl.java)
07-10 10:30:38.775 30397 30435 W System.err:    at com.sun.javafx.application.PlatformImpl$$Lambda$7.run(Unknown Source)
07-10 10:30:38.775 30397 30435 W System.err:    at com.sun.javafx.application.PlatformImpl.lambda$null$156(PlatformImpl.java:295)
07-10 10:30:38.776 30397 30435 W System.err:    at com.sun.javafx.application.PlatformImpl.access$lambda$18(PlatformImpl.java)
07-10 10:30:38.776 30397 30435 W System.err:    at com.sun.javafx.application.PlatformImpl$$Lambda$19.run(Unknown Source)
07-10 10:30:38.777 30397 30435 W System.err:    at java.security.AccessController.doPrivileged(AccessController.java:57)
07-10 10:30:38.777 30397 30435 W System.err:    at com.sun.javafx.application.PlatformImpl.lambda$runLater$157(PlatformImpl.java:294)
07-10 10:30:38.777 30397 30435 W System.err:    at com.sun.javafx.application.PlatformImpl.access$lambda$5(PlatformImpl.java)
07-10 10:30:38.778 30397 30435 W System.err:    at com.sun.javafx.application.PlatformImpl$$Lambda$6.run(Unknown Source)
07-10 10:30:38.778 30397 30435 W System.err:    at com.sun.glass.ui.monocle.RunnableProcessor.runLoop(RunnableProcessor.java:93)
07-10 10:30:38.778 30397 30435 W System.err:    at com.sun.glass.ui.monocle.RunnableProcessor.run(RunnableProcessor.java:52)
07-10 10:30:38.778 30397 30435 W System.err:    at java.lang.Thread.run(Thread.java:762)

Build.gradle

buildscript 
    repositories 
        jcenter()
    
    dependencies 
        classpath 'org.javafxports:jfxmobile-plugin:1.3.12'
    


apply plugin: 'org.javafxports.jfxmobile'

repositories 
    jcenter()
    maven 
        url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
    


mainClassName = 'com.khmerdev.GluonApplication'

dependencies 
    compile 'com.gluonhq:charm:5.0.0'
    compile files('libs/h2-1.4.196.jar')


jfxmobile 
    downConfig 
        version = '3.8.0'
        // Do not edit the line below. Use Gluon Mobile Settings in your project context menu instead
        plugins 'display', 'lifecycle', 'statusbar', 'storage'
    
    android 
        manifest = 'src/android/AndroidManifest.xml'

    
    ios 
        infoPList = file('src/ios/Default-Info.plist')
        forceLinkClasses = [
                'com.khmerdev.**.*',
                'com.gluonhq.**.*',
                'javax.annotations.**.*',
                'javax.inject.**.*',
                'javax.json.**.*',
                'org.glassfish.json.**.*'
        ]
    

请帮帮我。

【问题讨论】:

您可以编辑您的问题并发布带有项目依赖项的 build.gradle 吗? 好的,我会的 您尝试过Gluon-sqlite 示例吗?如果您将驱动程序替换为 org.h2.Driver 并连接到 jdbc:h2: 它应该可以工作(当然使用正确的 h2 语法)。 @JoséPereda:所以你的意思是我必须按照 Gluon-sqlite 的示例代码,只需更改驱动程序和连接? 我试试,结果告诉你 【参考方案1】:

感谢 José Pereda 给了我一些想法,现在我找到了上述问题的解决方案。我们需要先通过以下代码获取正确的私有存储:

File dir = Services.get(StorageService.class)
                    .map(s -> s.getPrivateStorage().get())
                    .orElseThrow(() -> new IOException("Error: PrivateStorage not available"));

上面代码的输出应该是/data/user/0/com.khmerdev/files。然后我们需要使用这个目录与 dbUrl 连接。请参见下面的示例:

String url = "jdbc:h2:/data/user/0/com.khmerdev/files" +
    "/test" +
    ";FILE_LOCK=FS" +
    ";PAGE_SIZE=1024" +
    ";CACHE_SIZE=8192";

在上面的示例中,“test”是示例数据库名称。所以我们需要在 JDBC 中使用这个字符串 url 来进行数据库事务。

【讨论】:

以上是关于如何使用 Gluon 在 Android 平台上将 H2 数据库连接为嵌入式模式?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 上将“选择操作”更改为“使用完成操作”?

如何在Android上将图像字符串转换为整数?

如何在android上将kotlin转换为java? [复制]

Firebase Firestore:如何在 Android 上将文档对象转换为 POJO

如何在 Android 上将 Javascript 注入 GeckoView

如何在linux平台上将控制台输出重定向到qt中的GUI