3

我正在开发一个需要从 120MB 大小的巨大 MS Access 数据库中获取数据的 Android 应用程序。

我编写了代码来建立连接并在数据库上执行一个简单的查询。我在笔记本电脑和 Android 设备上运行相同的 java 代码。代码如下:p

ackage practiceDB;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;


import java.util.Scanner;

import net.ucanaccess.converters.TypesMap.AccessType;
import net.ucanaccess.ext.FunctionType;
import net.ucanaccess.jdbc.UcanaccessConnection;
import net.ucanaccess.jdbc.UcanaccessDriver;

public class Example {
    private Connection ucaConn;
    public Example() {
        try {
            this.ucaConn = getUcanaccessConnection("VehicleDatabase2.mdb");
        } catch (SQLException e) {
            e.printStackTrace();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        System.out.println("Please enter an int");
        new Scanner(System.in).nextInt();

        try {
            Example example = new Example();

            example.executeQuery();
        } catch (Exception ex) {
            System.out.println("An exception : " + ex.getMessage());
        }
    }

    private void executeQuery() throws SQLException {
        Statement st = null;
        try {
            System.out.println("Please enter an int");
            new Scanner(System.in).nextInt();
            st = this.ucaConn.createStatement();
            System.out.println("Please enter an int");
            new Scanner(System.in).nextInt();
            ResultSet rs = st.executeQuery("Select * from PersonData where EngNo = '1544256'");
            System.out.println(" result:");
            dump (rs, "executeQuery");
        } catch(Exception ex) {
            System.out.println("Sarah exception: " + ex.getMessage());
        } finally {
            if ( st != null ) {
                st.close();
            }
        }
    }

    private Connection getUcanaccessConnection(String pathNewDB) throws SQLException, IOException {
        String url  = UcanaccessDriver.URL_PREFIX + "VehicleDatabase2.mdb;newDatabaseVersion=V2003";

        return DriverManager.getConnection(url);
    }

    private void dump(ResultSet rs, String exName) 
            throws SQLException {
        System.out.println("-------------------------------------------------");
        System.out.println();

        System.out.println();
        int jk = 0;
        while (rs.next()) {

            System.out.print("| ");
            int j=rs.getMetaData().getColumnCount();
            for (int i = 1; i <=j ; ++i) {
                Object o = rs.getObject(i);
                System.out.print(o + " | ");
            }
        System.out.println();
        System.out.println();
        }
    }
}

当它在我的笔记本电脑上运行时,建立连接只需大约一分钟。但是在我的Android设备上运行时,连接需要10多分钟,并且占用了所有的堆空间,并且当设备内存不足时,应用程序崩溃了

我应该怎么办??

注意:
我对这段代码进行了一些细微的修改以在 android 上运行它,比如添加 toast 而不是 System.out.println 进行调试,我删除了 android 的静态 main 函数,使用 Environment.getAbsolutePath() 来定位数据库等.另外,我在Android上运行的代码,我先用了一个9MB的数据库来检查它是否有效。该代码按预期从 9MB 数据库中获取数据,没有任何问题。9MB 数据库在 Android 中建立连接大约需要 10 秒(在桌面,与 9MB 数据库建立连接只需不到 1 秒)

4

1 回答 1

2

是的,我知道,它应该适用于中型数据库。带着一个巨大的...

首先,请注意您正在测量的时间,它是虚拟机生命周期中第一次连接到数据库的时间,以下(如果需要)将是瞬时的。

从未在 Android 上尝试过类似的操作,因为您的实验具有挑战性,但是,如果它符合您的要求,您可以尝试:

- 使用 MirrorFolder(或 keepMirror)连接参数(有关它的更多详细信息,请参见 ucanaccess 网站)。在这种情况下,与数据库的第一次连接将非常慢,所有以下(即使虚拟机结束)都将是瞬时的。但是访问数据库应该只用 ucanaccess 和你的 android 更新

或者,或者,

- 使用过滤器数据库(在 Windows 上配置),将真实数据库链接到您的应用程序急需的外部链接表的子集中(内存使用量可能会下降)。在这种情况下,您必须使用 remap 连接参数,因为您使用的是基于 linux 的 SO。

在此处查看与 jackcess(底层 I/O 库)相关的另一个建议 并使用最新的 ucanaccess 版本。

于 2015-05-13T16:17:09.603 回答