用Java编写数据库迁移器,内存问题(代码结构?)

用Java编写数据库迁移器,内存问题(代码结构?),java,mysql,migration,structure,filemaker,Java,Mysql,Migration,Structure,Filemaker,我目前正在尝试使用JDBC将数据从filemaker pro 11传输到MySQL 我已经处理了建立到每个数据库的连接,并进行了有效的查询,并将数据安全地插入MySQL try { results = query.executeQuery("SELECT \"field one\", \"field two\" from table"); Connection con = DriverManager.getConnection("jdbc:mysql://website.

我目前正在尝试使用JDBC将数据从filemaker pro 11传输到MySQL

我已经处理了建立到每个数据库的连接,并进行了有效的查询,并将数据安全地插入MySQL

  try {
  results =
    query.executeQuery("SELECT \"field one\", \"field two\" from table");


  Connection con = DriverManager.getConnection("jdbc:mysql://website.com/database","user","password");

 // Iterate through the results and print them to standard output

  while (results.next()) {
    String fname = results.getString("field one");
    String lname = results.getString("field two");
  System.out.println("Found user \"" + fname + " " + lname + "\"");
  stmt = con.prepareStatement("INSERT ignore INTO table (idtable, name) values (?, ?)");

  // some of the data I've been provided with is pretty horrific,
  // so inserting safely is of large concern.

  stmt.setString(1, fname);
  stmt.setString(2, lname);
  stmt.executeUpdate();

  }
}
catch (SQLException e) {
  System.out.println("Error retrieving data from database.");
   e.printStackTrace();
  //System.exit(1);
}
这适用于较小的表(4分钟内约100000条记录),但其中一些非常非常大,会导致应用程序崩溃:(

这需要能够运行至少一次来完成一个完整的填充,但在那之后,我可以限制输出,以获取上周所做的更改

我以前在VB.net中写过这篇文章,并构建了大型插入,但我做了一个切换——我真的需要那个prepare语句,因为当前数据库中有各种各样的疯狂字符

谢谢,保罗S

 Error: 
 Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:151)
at java.lang.StringCoding.decode(StringCoding.java:191)
at java.lang.String.<init>(String.java:451)
at java.util.jar.Attributes.read(Attributes.java:401)
at java.util.jar.Manifest.read(Manifest.java:199)
at java.util.jar.Manifest.<init>(Manifest.java:69)
at java.util.jar.JarFile.getManifestFromReference(JarFile.java:182)
at java.util.jar.JarFile.getManifest(JarFile.java:163)
at sun.misc.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:710)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:238)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:435)
at com.mysql.jdbc.PreparedStatement.getInstance(PreparedStatement.java:872)
at com.mysql.jdbc.ConnectionImpl.clientPrepareStatement(ConnectionImpl.java:1491)
at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4250)
at com.mysql.jdbc.ConnectionImpl.prepareStatement(ConnectionImpl.java:4149)
at datasync2.FMProConnection.companyQuoteInsert(FMProConnection.java:686)
at datasync2.DataSync2View.jButton1ActionPerformed(DataSync2View.java:220)
at datasync2.DataSync2View.access$800(DataSync2View.java:22)
at datasync2.DataSync2View$4.actionPerformed(DataSync2View.java:124)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2012)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2335)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:404)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at         javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:253)
at java.awt.Component.processMouseEvent(Component.java:6268)
错误:
线程“AWT-EventQueue-0”java.lang.OutOfMemoryError中出现异常:java堆空间
在java.lang.StringCoding$StringDecoder.decode(StringCoding.java:151)
在java.lang.StringCoding.decode(StringCoding.java:191)
位于java.lang.String。(String.java:451)
位于java.util.jar.Attributes.read(Attributes.java:401)
位于java.util.jar.Manifest.read(Manifest.java:199)
位于java.util.jar.Manifest。(Manifest.java:69)
位于java.util.jar.JarFile.getManifestFromReference(JarFile.java:182)
位于java.util.jar.JarFile.getManifest(JarFile.java:163)
位于sun.misc.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:710)
位于java.net.URLClassLoader.defineClass(URLClassLoader.java:238)
在java.net.URLClassLoader.access$000(URLClassLoader.java:73)
在java.net.URLClassLoader$1.run(URLClassLoader.java:212)
位于java.security.AccessController.doPrivileged(本机方法)
位于java.net.URLClassLoader.findClass(URLClassLoader.java:205)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:321)
位于sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:266)
位于com.mysql.jdbc.Util.HandleneInstance(Util.java:435)
位于com.mysql.jdbc.PreparedStatement.getInstance(PreparedStatement.java:872)
位于com.mysql.jdbc.ConnectionImpl.clientPrepareStatement(ConnectionImpl.java:1491)
在com.mysql.jdbc.ConnectionImpl.prepareStatement上(ConnectionImpl.java:4250)
在com.mysql.jdbc.ConnectionImpl.prepareStatement上(ConnectionImpl.java:4149)
位于datasync2.FMProConnection.companyQuoteInsert(FMProConnection.java:686)
在datasync2.DataSync2View.jButton1ActionPerformed处(DataSync2View.java:220)
datasync2.DataSync2View.access$800(DataSync2View.java:22)
在datasync2.DataSync2View$4.actionPerformed(DataSync2View.java:124)
在javax.swing.AbstractButton.fireActionPerformed上(AbstractButton.java:2012)
位于javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2335)
在javax.swing.DefaultButtonModel.fireActionPerformed上(DefaultButtonModel.java:404)
在javax.swing.DefaultButtonModel.setPressed中(DefaultButtonModel.java:259)
在javax.swing.plaf.basic.BasicButtonListener.mouseRelease(BasicButtonListener.java:253)
位于java.awt.Component.ProcessMouseeEvent(Component.java:6268)

PreparedStatement是一条路,不用担心


我必须查看描述崩溃的异常才能知道根本原因是什么,但我的猜测是您试图一次插入太多的记录。我会将它分成更小的块,并在执行单个事务时提交每个块。您的事务日志不必以这种方式包含每一次插入。

PreparedStatement不是这样的他走得很快,不用担心


我必须查看描述崩溃的异常才能知道根本原因是什么,但我的猜测是您试图一次插入太多记录。我会将其分成更小的数据块,并在执行单个事务时提交每个数据块。您的事务日志不必以这种方式包含每一次插入。

可能无法解决此问题他说:

//...
stmt.executeUpdate();
stmt.close();
//...

(明确地发布该语句,而不是等待GC为您执行该语句)

这可能会解决问题:

//...
stmt.executeUpdate();
stmt.close();
//...

(显式释放语句,而不是等待GC为您执行此操作)

您可能需要使用不同的FileMaker JDBC驱动程序。我认为FileMaker提供的JDBC驱动程序不支持流式处理结果集,这意味着它会将所有数据加载到内存中


如果您愿意,您可以在上尝试我们的FileMaker JDBC驱动程序。它比FileMaker提供的驱动程序慢一点,因为它运行在(慢速)上XML Web发布接口,但它流式传输结果,因此不会耗尽内存。

您可能需要使用不同的FileMaker JDBC驱动程序。我认为FileMaker提供的JDBC驱动程序不支持流式传输结果集,这意味着它会将所有数据加载到内存中


如果您愿意,您可以在尝试我们的FileMaker JDBC驱动程序。它比FileMaker提供的驱动程序慢一点,因为它在(慢速)XML Web发布界面上运行,但它会流式处理结果,因此不会耗尽内存。

分批执行。 您可以从100K的批处理大小开始,然后将其增加,直到性能下降

  • 1) 尝试从源表的未处理行中选择数量有限的行
  • 2) 进行批量插入
:

像这里

  • 3) 此外,请跟踪哪些记录已成功处理。 (更新源行上的标志或按特定顺序处理它们并保存最后一个标志)
  • 4) 处理错误、向数据库提交更改、释放资源(关闭语句等)

循环1-4,直到成功处理源表中的所有记录。

分批执行。 您可以从100K的批处理大小开始,然后将其增加,直到性能下降

  • 1) 尝试从源表的未处理行中选择数量有限的行
  • 2) 进行批量插入
:

像这里

  • 3) 此外,请记录哪些记录已被删除