2013-03-18 47 views
0

我有一个库需要在Java中从MySQL创建一个模式。目前,我有一个转储的模式,我只需将其输入mysql命令。这工作不错,但由于它并不理想:创建一个数据库/从Java执行一堆mysql语句

  • 它是脆:在mysql命令需要在路径上:通常不会对OSX或Windows无需额外配置工作。
  • 也很脆弱,因为模式存储为语句,而不是描述
  • Java已经可以访问MySQL数据库,所以依靠外部程序来执行此操作似乎很愚蠢。

有没有人知道更好的方法来做到这一点?也许...

  • 我可以从文件中读取语句并直接从Java中执行它们?有没有办法做到这一点,不涉及解析分号和手动划分语句?
  • 我可以以某种其他方式(作为配置文件或直接在Java中)存储架构,而不是以语句形式存在(以rails的db:schemadatabase.yml的样式),并且有一个库将根据此描述创建架构?

下面是现有的代码,其工作(当mysql是在命令行上)的一个片段:

if(db == null) throw new Exception ("Need database name!"); 
String userStr = user == null ? "" : String.format("-u %s ", user); 
String hostStr = host == null ? "" : String.format("-h %s ", host); 
String pwStr = pw == null ? "" : String.format("-p%s ", pw); 

String cmd = String.format("mysql %s %s %s %s", hostStr, userStr, pwStr, db); 

System.out.println(cmd + " < schema.sql");  

final Process pr = Runtime.getRuntime().exec(cmd); 

new Thread() { 
    public void run() {    
     try (OutputStream stdin = pr.getOutputStream()) { 
      Files.copy(f, stdin); 
     } 
     catch (IOException e) { e.printStackTrace(); }       
    } 
}.start(); 

new Thread() { 
    public void run() {    
     try (InputStream stdout = pr.getInputStream()) { 
      ByteStreams.copy(stdout, System.out); 
     } 
     catch (IOException e) { e.printStackTrace(); } 
    } 
}.start();    

int exitVal = pr.waitFor(); 
if(exitVal == 0) 
    System.out.println("Create db succeeded!"); 
else  
    System.out.println("Exited with error code " + exitVal); 
+0

您是否尝试过使用ant和sql任务,它只需要数据库驱动程序(jar文件)来执行SQL便携式。 (http://ant.apache.org/manual/Tasks/sql.html)您也可以尝试集成到ant的DBDeploy java库,并允许您增量部署SQL(http://dbdeploy.com/) – 2013-03-18 17:39:59

回答

0

退房Yank,并且更具体地链接到该网页上的代码示例。这是一个构建在DBUtils之上的轻量级持久层,并隐藏了处理连接和结果集的所有细节。您也可以轻松加载像您所提到的配置文件。您还可以存储和加载属性文件中的SQL语句和/或在代码中对SQL语句进行硬编码。

+0

我用过使用'DBUtils',但切换到'QueryDSL',因为它更适合我的使用。你是说我应该使用这个库来执行多个语句吗?似乎我仍然不得不从文件中自己解析它们。 – 2013-03-18 17:40:38

+0

如果您在.properties文件中拥有您的语句,则Yank可以读取它们,并且您可以使用属性文件中的相应键引用该语句。这可能会或可能不会为您工作,这取决于您的需求。就执行“创建数据库”语句而言,我从未尝试过使用Yank。道歉,如果这是你的问题的主要观点。 – herrtim 2013-03-18 17:51:11

+0

有很多陈述。我不想将它们全部手动粘贴到'.properties'文件中。模式也可以改变,现在可以很容易地用'mysqldump'来管理,但是如果我在每次更改后都必须去编辑'.properties'文件,那么这种模式并不容易。 – 2013-03-18 17:52:57

1

简短的回答(据我所知)是不。 你将不得不做一些文件解析成单独的语句。

我面临同样的情况,你可以在这里找到关于这个话题的许多问题。 一些like here将显示一个解析器。其他人可以指向Apache的工具Like this post,该工具可以将模式转换为xml格式,然后将其读回。

我写这个答案的主要目的是告诉我最终选择使用命令行。

  • 额外的配置:也许这是一个额外的工作,但你可以通过配置或在运行时根据您所内运行的系统上做到这一点。你做了一次努力,你就完成了
  • 取决于外部工具:它没有看起来那么糟糕。你也有一些好处。

    1-您不需要编写额外的代码或引入额外的库来分析模式命令。

    2-该工具由供应商提供。它可能比任何其他将执行解析的代码更多地进行调试和测试。

    3-从长远来看更安全。 “可能”打破语法分析器的转储格式的任何增加或更改将最有可能由数据库发行版附带的工具支持。你不需要在你的代码中做任何改变。

    4-您将要使用该工具(创建模式)的行为的性质不建议频繁使用,将其成为性能瓶颈的风险降至最低。

我希望你能找到最适合你需求的解决方案。

+0

+1感谢您分享您的体验。支持使用命令行的论点看起来非常合理。当我实现它时,我只是认为这有点破解。 – 2013-03-21 15:32:34

+0

我同意。它看起来像一个黑客,因为每个需要访问命令行工具的代码:) – 2013-03-21 15:49:24

相关问题