我正在开发一款需要从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数据库建立连接只需不到一秒钟)
答案 0 :(得分:2)
是的,我知道,它应该适用于中等大小的数据库。有一个巨大的...
首先,请注意您测量的时间,即VM生命中第一次连接数据库的时间,以下(如果需要)将是即时的。
从未在Android上尝试类似的东西,因为您的实验很有挑战性,但是,如果它符合您的要求,您可以尝试:
- 使用MirrorFolder(或keepMirror)连接参数(有关它的更多详细信息,请参阅ucanaccess网站)。在这种情况下,与db的第一次连接将非常慢,所有以下(即使vm结束)将是瞬时的。但是只能使用ucanaccess和你的android
更新访问数据库或者
- 使用过滤器数据库(在Windows上配置它)链接外部链接表子集中的真实数据库,这是您的应用程序非常需要的(内存使用量可能会下降)。在这种情况下,您必须使用重映射连接参数,因为您使用的是基于Linux的SO。
查看与jackcess(基础I / O库)here相关的其他建议,并使用最新的ucanaccess版本。