DbUnit NoSuchTableException - Oracle中长表名的解决方法

时间:2012-07-10 15:55:06

标签: java sql oracle dbunit

我正在创建一个使用dbunit xml在多个数据库上运行的测试套件。不幸的是,昨天我发现我们架构中的一些表名超过30个字符,并且被截断为Oracle。例如,mysql中名为unusually_long_table_name_error的表在Oracle中名为unusually_long_table_name_erro。这意味着我的dbunit文件包含<unusually_long_table_name_error col1="value1" col2="value2 />之类的行。在Oracle中运行测试时,这些行会抛出NoSuchTableException

是否有针对此的程序化解决方法?我真的想避免为Oracle生成特殊的xml文件。我查看了一个自定义MetadataHandler,但它返回了许多我不知道如何拦截/欺骗的java.sql数据类型。我自己可以读取xml,将每个表名截断为30个字符,将其写入临时文件或StringBufferInputStream,然后将其用作我的DataSetBuilder的输入,但这似乎要完成很多步骤小。也许有一些忍者Oracle技巧与同义词或存储过程或善良 - 知道什么 - 其他可以帮助我。这些想法中的一个明显优于其他想法吗?是否还有其他一些方法会以简洁和优雅的方式让我失望?谢谢!

1 个答案:

答案 0 :(得分:2)

鉴于缺乏答案,我最终采用了我自己建议的方法,

  1. 读取.xml文件
  2. 正则表达式中的表名
  3. 如果表名超过30个字符
  4. ,则截断表名
  5. 将(可能已修改的)行附加到StringBuilder
  6. 将StringBuilder导入ByteArrayInputStream,适合传入DataSetBuilder

  7. 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"));
    }
    

    编辑:从重复的字符串连接中交换到StringBuilder,这会带来巨大的性能提升