3

120MB の巨大な MS Access データベースからデータを取得する必要がある Android アプリを開発しています。

接続を確立し、データベースで単純なクエリを実行するコードを作成しました。ラップトップと Android デバイスで同じ Java コードを実行します。コードは次のとおりです。

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();
        }
    }
}

私のラップトップで実行すると、接続が確立されるまでに約 1 分しかかかりません。しかし、Android デバイスで実行すると、接続に 10 分以上かかり、すべてのヒープ スペースが占有され、デバイスのメモリが不足すると、アプリがクラッシュします。

私は何をすべきか??

注:
このコードを Android で実行するために、デバッグ用に System.out.println の代わりにトーストを追加するなど、若干の変更を加えました。Android の静的なメイン関数を削除し、Environment.getAbsolutePath() を使用してデータベースを検索しました。また、私が Android で実行しているコードは、最初に 9MB のデータベースを使用して動作するかどうかを確認しました。このコードは、問題なく 9MB のデータベースから期待どおりにデータをフェッチします。9MB のデータベースの場合、Android で接続を確立するのに約 10 秒かかります (デスクトップでは、9MB のデータベースとの接続を確立するのに 1 秒もかかりません)。

4

1 に答える 1

2

はい、中規模のデータベースで動作するはずです。でっかいやつで…

まず、測定している時間は、VM ライフの中でデータベースへの最初の接続の時間であることに注意してください。以下は (必要な場合) 瞬時です。

あなたの実験は挑戦的であるため、Androidでそのようなことを試したことはありませんが、要件に適合する場合は、試してみてください:

-MirrorFolder (または keepMirror) 接続パラメーターを使用します (詳細については、ucanaccess Web サイトを参照してください)。この場合、データベースへの最初の接続は非常に遅くなり、その後の接続はすべて (VM が終了しても) 瞬時になります。ただし、アクセスデータベースは、ucanaccess と Android でのみ更新する必要があります

または、代わりに

-アプリに密接に必要な外部リンクテーブルのサブセット内で実際のデータベースをリンクするフィルターデータベースを使用します(Windowsで構成します)(メモリ使用量が低下する可能性があります)。この場合、Linux ベースの SO を使用しているため、remap 接続パラメーターを使用する必要があります。

ここでjackcess (基礎となる I/O ライブラリ) に関連する別の提案を参照し 、最新の ucanaccess リリースを使用してください。

于 2015-05-13T16:17:09.603 に答える