【问题标题】:Spring + ibatis + String matchingSpring + ibatis + 字符串匹配
【发布时间】:2015-09-12 04:02:52
【问题描述】:

我有一个与 ibatis 集成的 Spring 应用程序。

我正在调用某个第三方应用程序,从中获取字符串消息(消息是消息的组合,字符串与 \ 分隔符连接以连接来自第三方的不同消息)作为输出。 我必须根据字符串匹配过滤这个输出。还有大约 150 个其他字符串。如果输出消息包含 150 条消息中的任何字符串,我必须添加一些功能。

我需要建议来实施它。我正在考虑将 150 个字符串放在表中,因为将来计数可能会增加。输出可能不包含这 150 条消息中的任何消息,或者包含这 150 条消息的任意数量的组合。

我是 Spring 新手。请告诉我如何从数据库中获取这些消息,因为我没有 id 来获取它们,或者我应该将它们全部作为列表获取,然后比较第三方的输出字符串。另外请告诉我将这些消息保存在数据库中是否明智,或者我也可以将它们保存在某个属性文件中,哪一个在性能上会更好。

提前致谢。

【问题讨论】:

  • 霍夫经常需要添加新消息吗?它们是必须在运行时添加还是仅在软件的新版本中添加?消息多长时间(最小/平均/最大)?是否存在可能的差异(例如,大写/小写)或字符串是否始终完全相同?
  • 哦,作为一个想法:你确实有一个 id,因为字符串的哈希码很可能符合这个条件。
  • 另外,还有一个问题:你必须采取的行动是始终相同还是对某些字符串有不同的行动?
  • 实际上消息来自第三方系统,这是一个遗留系统。所以我不确定他们总共有多少条消息。当测试将进行时,他们希望我添加消息。此外,解决方案应该独立于消息,这样一旦开发结束,消息也可以作为配置添加。
  • 能否请您告诉我有关哈希码的信息,我该如何使用它。关于第三条评论,动作基本上是,每条输出消息都是警告和错误的组合,我有 150 条错误消息,我只需要从最终消息中删除其他警告消息,只需要保留错误消息.例如。如果我从第三方收到一条消息为“ABCDEF”,我在数据库中有实际错误列表,比如说(只有 B 和 EF 是错误),那么我需要将整个“ABCDEF”与 B 和 EF 进行比较并返回“B|E|F”以及与 B、E 和 F 相关的其他一些细节。

标签: string spring pattern-matching string-matching ibatis


【解决方案1】:

好的,让我们从一些可能性开始:

如果您将来只添加一些消息并且只在新版本中这样做,那么将消息存储在枚举中将是一个可行的选择:

enum ErrorMessage {

    SOME_MESSAGE("something, bla bla"),
    SOME_OTHER_MESSAGE("something_else"),
    ...;

    private String message;
    private ErrorMessage(String message) {
        this.message = message;
    }

    public static ErrorMessage getByErrorMessage(String message) {
        for(ErrorMessage errorMessage: message) {
            if (errorMessage.message.equals(message)) {
                return errorMessage;
            }
        }
        return null;
    }

    public static boolean exists(String message) {           
        return getByErrorMessage(message) != null;
    }
}

请注意,这个版本非常原始,可以通过将所有消息添加到静态 Set 中来改进:

static Set<String> messagesCache = new Hashset<String>();

//in constructor:
messagesCache.add( message );

// better exists() method:
public static boolean exists(String message) {
    return messagesCache.contains(message);
}

或者,与其他解决方案一样,您只能存储字符串的实际哈希码。哈希码是您的字符串的简单数字表示,并且足够独特,您可以识别它。与上述相同的解决方案:

static Set<String> messagesHashCodes = new Hashset<String>();

//in constructor:
messagesHashCodes .add( message.hashCode() );

// better exists() method:
public static boolean exists(String message) {
    return messagesHashCodes .contains(message.hashCode());
}

(当然,检查空值等是个好主意)

枚举版本有一个很大的优势,如果你想对某些动作采取不同的动作,你可以将它们编码到枚举中,例如...

SOME_MESSAGE_REQUIRING_AN_ACTION("...") {

    @Override
    public void doAction(StringBuilder finalString) {
        ...doSomething.
    }
}


...

public void doAction(StringBuilder finalString) {
    finalString.append( this.message );
    finalString.append( SOME_SEPERATOR );
}

public void static doAction(StringBuilder builder, String errorMessage) {
    if (exists(errorMessage)) {
    }
}

在此示例中,您可以覆盖每个枚举值中的 doAction 方法,如果它应该执行更多/其他操作而不是将消息附加到 StringBuilder。在枚举列表中添加一些“NULL_MESSAGE”也是一个不错的选择,它什么都不做,只是为了便于处理:

UNKNOWN_MESSAGE(null) {

    @Override
    public void doAction(StringBuilder finalString) {
        // do nothing here
    }
}

public static ErrorMessage getByErrorMessage(String message) {
    for(ErrorMessage errorMessage: message) {
        if (errorMessage.message != null && errorMessage.message.equals(message)) {
            return errorMessage;
        }
    }
    return UNKNOWN_MESSAGE;
}

这样,您可以简单地将每个字符串放入您的枚举方法 doAction(StringBuilder, String) 并获得结果:如果一条消息适合,则添加它(并采取其他一些操作),如果不适合,它将是忽略,包括空检查。

另一方面,如果您的消息经常更改,那么您可能不会发布此类更改,而是将值保存在数据库中。在这种情况下,我将使用消息的 hashCode() 作为 id(正如我所说,通常足够独特)并在应用程序启动时将整个内容加载到内存中,例如,允许您再次构建一个 Set哈希码来比较你的errorMessages的哈希码。

protected void init() {
    // load all error Messages from the database
    // put them into a Map<String, String> (hashCode -> Value) or even just a Set<String> (hashcodes)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 2011-09-04
    • 1970-01-01
    • 2012-05-11
    相关资源
    最近更新 更多