使用Java,我需要编码Map< String,String>名称值对存储到String中,并能够再次解码它。这些将存储在数据库列中,并且通常可能简短,因此常见的情况应该产生一个简单漂亮的行,但不应该破坏数据,即使它包含意外的字符等。
你会如何选择这样做:
网址编码? JSON?自己做?请指定您使用的任何帮助程序库或方法。
(根据要求编辑以指定更多上下文和要求。)
答案 0 :(得分:5)
正如@Uri所说,额外的背景会很好。我认为您的主要关注点不在于特定的编码方案,因为对于简单的Map<String, String>
来说,为大多数编码滚动自己很简单。
一个有趣的问题是:这个中间字符串编码将用于什么?
如果它纯粹是内部的,那么ad-hoc格式很好,例如简单连接:
key1|value1|key2|value2
如果人类晚上读它,像Ruby的地图声明这样的格式很不错:
{ first_key => first_value,
second_key => second_value }
如果编码是通过网络将序列化地图发送到另一个应用程序,那么XML建议很有意义,因为它是标准的,并且合理地自我记录,代价是XML的冗长。
<map>
<entry key='foo' value='bar'/>
<entry key='this' value='that'/>
</map>
如果要将地图刷新到文件并稍后由另一个Java应用程序回读,@ Cletus对Properties class的建议是一个很好的建议,并且具有易于使用的额外好处开放并由人类检查。
编辑:您已添加了要存储在数据库列中的信息 - 是否有理由使用单个列,而不是像这样使用三列:
CREATE TABLE StringMaps
(
map_id NUMBER NOT NULL, -- ditch this if you only store one map...
key VARCHAR2 NOT NULL,
value VARCHAR2
);
除了让您存储更多具有语义意义的数据外,这还可以更正式地将编码/解码移动到您的数据访问层,并允许其他数据库读取器轻松查看数据,而无需了解您可能使用的任何自定义编码方案。如果您愿意,也可以通过键或值轻松查询。
再次编辑:你说它确实需要适合单个列,在这种情况下我要么:
使用第一个以管道分隔的编码(或者您喜欢的任何外来字符,也许是一些不可打印的英文unicode字符)。最简单的事情。或...
如果您使用像Oracle这样的数据库将XML识别为真实类型(因此可以对其进行XPath评估等等)并且需要能够从数据库层中很好地读取数据,使用XML。编写用于解码的XML解析器永远不会有趣,但使用这样一个简单的模式不应该太痛苦。
即使您的数据库本身不支持XML,您也可以将其放入任何旧的类似字符的列类型...
答案 1 :(得分:3)
为什么不使用Properties class?这正是你想要的。
答案 2 :(得分:1)
我一直在考虑通过外观模式为我的客户端和服务器之间的对话(传输内容)选择公共表示的类似需求。我想要一个标准化,人类可读(简短),健壮,快速的表示。我希望它实现和运行轻量级,易于测试,并且易于“包装”。请注意,我已经通过我的定义和明确的意图消除了XML。
通过“wrap”,我的意思是我想支持其他传输内容表示,例如XML,SOAP,可能是Java属性或Windows INI格式,逗号分隔值(CSV)等,Google协议缓冲区,自定义二进制格式,专有二进制格式,如Microsoft Excel工作簿,以及可能出现的任何其他格式。我将使用主要外观周围的包装器/装饰器来实现这些辅助表示。这些次要表示中的每一个都是可取的,特别是在某些情况下与其他系统集成,但由于各种缺点(未能满足上面列出的一个或多个标准),它们都不适合作为主要表示。
因此,到目前为止,我选择将JSON格式作为主要的传输内容表示。我打算在不久的将来详细探讨这个选项。
仅在极端性能考虑的情况下,我才会跳过翻译基础传统格式。清洁设计的优点包括良好的性能(无需浪费精力,易于维护),适当的硬件选择应该是唯一必要的补充。当性能需求变得极端时(例如,每天处理四万个传入数据文件,总计四万次交易),无论如何都必须重新审视所有内容。
作为开发人员,DBA,架构师等,我构建了几乎所有尺寸和描述的系统。我对自己选择的标准充满信心,并急切地等待确认其适用性。实际上,我希望将一个实现发布为开源(但不要屏住呼吸)。
请注意,此设计讨论忽略了有意的传输介质(HTTP,SMTP,RMI,.Net Remoting等)。我发现将传输介质和传输内容视为完全独立的设计考虑因素,彼此之间以及与所讨论的系统相比更为有效。实际上,我的目的是使这些实际上“可插拔”。
因此,我鼓励您强烈考虑JSON。祝福。
答案 3 :(得分:0)
该问题的一些额外背景会有所帮助。
如果要以整个地图粒度进行编码和解码,为什么不使用XML?
答案 4 :(得分:0)
正如@DanVinton所说,如果你需要内部使用(我的意思是“
内部使用
as
它仅由我的组件使用,而不是由其他人编写的组件
你可以连接键和值。
我更喜欢在键和键之间使用不同的分隔符和键和值:
而不是
key1+SEPARATOR+value1+SEPARATOR+key2 etc
我代码
key1+SEPARATOR_KEY_AND_VALUE+value1+SEPARATOR_KEY(n)_AND_KEY(N+1)+key2 etc
如果你必须调试,这种方式更清晰(按设计也是如此)
答案 5 :(得分:0)
查看apache commons配置包。这将允许您以XML或属性格式读取/保存文件。它还为您提供了自动将属性更改保存到文件的选项。
答案 6 :(得分:0)
意识到这是一个古老的“致命”线索,但我有一个以前没有提出的解决方案,我认为值得投入戒指。
我们在标准XML属性格式的DB中的单个features列中存储地理CLOB的“任意”属性(即由用户在运行时创建)。那就是:
name="value" name="value" name="value"
要创建XML元素,只需在xml元素中“包装”属性即可。那就是:
String xmlString += "<arbitraryAttributes" + arbitraryAttributesString + " />"
将一个属性实例“序列化”到一个xml-attributes-string是一个简单的...它就像十行代码。我们很幸运,因为我们可以向用户强加所有属性名称必须是有效的xml-element-names的规则;我们xml-escape(即“e; etc)”每个“值”以避免双引号和值字符串中的任何问题。
它有效,灵活,快速(足够)和简单。
现在,说了这么多......如果我们有时间,我们只是通过存储完整的未掺杂的未解释的元数据xml文档完全脱离整个“元数据问题”在CLOB中使用其中一个开源元数据编辑器来处理整个混乱。
干杯。基思。