如何像hibernate一样在Java中灵活生成字符串

Posted

技术标签:

【中文标题】如何像hibernate一样在Java中灵活生成字符串【英文标题】:How to flexibly generate string in Java as hibernate does 【发布时间】:2015-06-23 21:22:57 【问题描述】:

在我的查询中我不能使用休眠,我需要生成一个字符串,如下所示:

我有带有 3 个键的 Map<String, String> restrictions 实例(idnamevalue),我想获取条目(String)。

if (restrictions.get("id") != null && restrictions.get("name") == null && restrictions.get("value") == null)
       return "ID = " + restrictions.get("id");
 else if (restrictions.get("id") != null && restrictions.get("name") != null && restrictions.get("value" != null))
       return "ID = " + restrictions.get("id") + " and Name = " + restrictions.get("name");

等等……

显式编写if-else 子句是非常不灵活且难以维护的方式。有什么想法吗?

【问题讨论】:

这个问题的范围太广了? 【参考方案1】:

使用java.util.StringJoiner:

import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

public class SOPlayground 

    public static void main(String[] args) throws Exception 
        Map<String, String> restrictions = new HashMap<>();
        restrictions.put("id", "foo");
        restrictions.put("name", "bar");
        restrictions.put("not set", null);

        StringJoiner joiner = new StringJoiner(" AND ");
        restrictions.keySet().stream().filter((column) -> (restrictions.get(column) != null)).map((column) -> 
            StringBuilder builder = new StringBuilder();
            builder.append(column).append("='").append(restrictions.get(column)).append("'");
            return builder;
        ).map((builder) -> builder.toString()).forEach((term) -> 
            joiner.add(term);
        );
        System.out.println(joiner.toString());
    

输出:

id='foo' AND name='bar'

【讨论】:

嗯,这是 Java-8 的解决方案。也许在 Java-7 中有类似的东西? Java 8 已经推出一年多了。使用它。 那么问题应该被标记为java-7java 标签表示当前 Java 版本为 8。 但事实上,您可以使用 StringBuilder 轻松实现相同的目标。提供的代码 sn-p 应该足够提示。顺便说一句,这只是纯粹的挑剔;)java意味着任何版本,它的概括,而不是限制。 "java 表示任何版本"。所以让我们编写没有泛型的代码;)【参考方案2】:

只需尝试搜索有关“如何在 java 中迭代地图”的问题。 How to efficiently iterate over each Entry in a Map? 应该给你一个例子。

至于注释,下面可以是代码,虽然你可以很容易地优化它:

StringBuffer clause = new StringBuffer();
for(Map.Entry<String, String> entry : restrictions.entrySet()) 
    clause.append(entry.getKey()).append(\"=\").append(entry.getValue());
    clause.append(" AND ");


String strClause = clause.toString();
strClause = strCluase.subString(0, strClause.length() - 5); //5 is length of " AND "

【讨论】:

【参考方案3】:

这个问题之前已经回答过了。在我看来,我更喜欢使用Colin Hebert answer。 您的 if-else 会很好,但由于 OOP(代码可重用性),您始终可以覆盖这些功能以满足您的需求。 您想要实现的目标可以通过多种方式完成,每个人都有自己的编码方式。

【讨论】:

以上是关于如何像hibernate一样在Java中灵活生成字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何在java中制作像枚举一样的键值[重复]

mybatis可以像hibernate一样自动创建表吗

Mybatis与Hibernate不同处

mybatis与hibernate的不同

JetBrains Rider - 像 getter/setter 一样生成 Java? [关闭]

如何设置在 Java JPA/Hibernate 中不是自动生成的 @Id 主键?