在我们的应用程序中,我们非常使用属性文件。几个月后我开始学习番石榴,我实际上很喜欢它。
创建Map<String, Datasource>
的最佳方法是什么?
属性文件格式不严格。如果可以用其他格式更好地表达它,它可以改变吗?
示例属性文件:
datasource1.url=jdbc:mysql://192.168.11.46/db1
datasource1.password=password
datasource1.user=root
datasource2.url=jdbc:mysql://192.168.11.45/db2
datasource2.password=password
datasource2.user=root
答案 0 :(得分:6)
最简单的事情可能就是使用JSON而不是属性文件:
{ "datasources": [ { "name": "datasource1", "url": "jdbc:mysql://192.168.11.46/db1", "user": "root", "password": "password" }, { "name": "datasource2", "url": "jdbc:mysql://192.168.11.46/db2", "user": "root", "password": "password" } ] }
然后您可以使用Gson之类的库将其转换为对象:
public class DataSources {
private List<DataSourceInfo> dataSources;
public Map<String, DataSource> getDataSources() {
// create the map
}
}
public class DataSourceInfo {
private String name;
private String url;
private String user;
private String password;
// constructor, getters
}
然后获取地图:
Gson gson = new Gson();
Map<String, DataSource> dataSources = gson.fromJson(/* file or stream here */,
DataSources.class).getDataSources();
答案 1 :(得分:5)
Properties类是HashTable的子类,它又实现了Map。
您可以像往常一样加载:
Properties properties = new Properties();
try {
properties.load(new FileInputStream("filename.properties"));
} catch (IOException e) {
}
编辑:好的,所以你想将它转换为Map&lt; String,Datasource&gt; ;)
//First convert properties to Map<String, String>
Map<String, String> m = Maps.fromProperties(properties);
//Sort them so that password < url < user for each datasource and dataSource1.* < dataSource2.*. In your case default string ordering is ok so we can take a normal treemap
Map<String, String> sorted = Maps.newTreeMap();
sorted.putAll(m);
//Create Multimap<String, List<String>> mapping datasourcename->[password,url, user ]
Function<Map.Entry<String, String>, String> propToList = new Function<String, Integer>() {
@Override
public String apply(Map.Entry<String, String> entry) {
return entry.getKey().split("\\.")[0];
}
};
Multimap<Integer, String> nameToParamMap = Multimaps.index(m.entrySet(), propToList);
//Convert it to map
Map<String, Collection<String>> mm = nameToParamMap.asMap();
//Transform it to Map<String, Datasource>
Map<String, Datasource> mSD = Maps.transformEntries(mm, new EntryTransformer<String, Collection<String>, DataSource>() {
public DataSource transformEntry(String key, Collection<String> value) {
// Create your datasource. You know by now that Collection<String> is actually a list so you can assume elements are in order: [password, url, user]
return new Datasource(.....)
}
};
//Copy transformed map so it's no longer a view
Map<String, Datasource> finalMap = Maps.newHashMap(mSD);
可能有一种更简单的方法,但这应该有效:)
使用json或xml还是比较好的。您还可以从不同的文件加载不同数据源的属性。
edit2:使用更少的番石榴,更多的java:
//Sort them so that password < url < user for each datasource and dataSource1.* < dataSource2.*. In your case default string ordering is ok so we can take a normal SortedSet
SortedSet <String> sorted = new SortedSet<String>();
sorted.putAll(m.keySet);
//Divide keys into lists of 3
Iterable<List<String>> keyLists = Iterables.partition(sorted.keySet(), 3);
Map<String, Datasource> m = new HashMap<String, Datasource>();
for (keyList : keyLists) {
//Contains datasourcex.password, datasroucex.url, datasourcex.user
String[] params = keyList.toArray(new String[keyList.size()]);
String password = properties.get(params[0]);
String url = properties.get(params[1]);
String user = properties.get(params[2]);
m.put(params[0].split("\\.")[0], new DataSource(....)
}
答案 2 :(得分:0)
如果您用于配置的文件不严格,则可以使用XML文件来存储定义。
示例定义:
<resources>
<configuration>
<datasrouce>
<connection name="" url="" password="" user=""/>
<connection name="" url="" password="" user=""/>
</datasource>
</configuration>
</resources>
使用Connection管理器类,您只需读取XML即可获取连接信息并创建连接实例并管理它们。