2

dbunit xml を使用して、複数のデータベースで実行されるテスト スイートの作成に取り組んでいます。残念ながら、昨日、スキーマ内の一部のテーブル名が 30 文字を超えており、Oracle では切り捨てられていることがわかりました。たとえばunusually_long_table_name_error、mysql で名前が付けられたテーブルはunusually_long_table_name_erro、Oracle で名前が付けられます。これは、私の dbunit ファイルに<unusually_long_table_name_error col1="value1" col2="value2 />. NoSuchTableExceptionこれらの行は、Oracle でテストを実行するとa をスローします。

これに対するプログラムによる回避策はありますか? Oracle 用の特別な xml ファイルの生成を避けたいと思っています。カスタムを調べましたが、インターセプト/スプーフィングの方法がわからないMetadataHandler多くのデータ型が返されます。java.sql自分で xml を読み取り、各テーブル名を 30 文字に切り捨て、それを一時ファイルに書き出すかStringBufferInputStream、それを DataSetBuilder への入力として使用することはできますが、それを達成するには非常に多くの手順が必要なようです。たぶん、シノニムやストアドプロシージャ、またはその他の良さを知っている忍者オラクルのトリックが役立つかもしれません。これらのアイデアの 1 つは、他のアイデアよりも明らかに優れていますか? そのシンプルさと優雅さで私を圧倒する他のアプローチはありますか? ありがとう!

4

1 に答える 1

2

答えがないことを考慮して、私は自分で提案したアプローチに行き着きました。

  1. .xml ファイルを読み取ります
  2. 正規表現のテーブル名
  3. テーブル名が 30 文字を超える場合は切り捨てます
  4. (潜在的に変更された) 行を StringBuilder に追加します。
  5. その StringBuilder を ByteArrayInputStream にフィードします。DataSetBuilder に渡すのに適しています。

public InputStream oracleWorkaroundStream(String fileName) throws IOException
{
  String ls = System.getProperty("line.separator");

  // This pattern isolates the table name from the rest of the line
  Pattern pattern = Pattern.compile("(\\s*<)(\\w+)(.*/>)");

  FileInputStream fis = new FileInputStream(fileName);
  // Use a StringBuidler for better performance over repeated concatenation
  StringBuilder sb = new StringBuilder(fis.available()*2);

  InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
  BufferedReader buff = new BufferedReader(isr);
  while (buff.ready())
  {
    // Read a line from the source xml file
    String line = buff.readLine();
    Matcher matcher = pattern.matcher(line);

    // See if the line contains a table name
    if (matcher.matches())
    {
      String tableName = matcher.group(2);
      if (tableName.length() > 30)
      {
        tableName = tableName.substring(0, 30);
      }

      // Append the (potentially modified) line
      sb.append(matcher.group(1));
      sb.append(tableName);
      sb.append(matcher.group(3));
    }
    else
    {
      // Some lines don't have tables names (<dataset>, <?xml?>, etc.)
      sb.append(line);
    }
    sb.append(ls);
  }

  return new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
}

EDIT:繰り返される文字列連結からStringBuilderに切り替えられ、パフォーマンスが大幅に向上します

于 2012-07-16T21:02:34.590 に答える