2011-11-21 57 views
6

在我們的應用程序中,我們非常使用屬性文件。自從幾個月後,我開始學習番石榴,而且我非常喜歡它。使用屬性文件創建番石榴對象

什麼是創建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 

回答

5

屬性類是哈希表,子類這又實現了地圖。

Properties properties = new Properties(); 
    try { 
     properties.load(new FileInputStream("filename.properties")); 
    } catch (IOException e) { 
} 

編輯:

你與加載它像往常一樣好了,所以要變換它地圖<字符串,數據源>)

//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(....) 
} 
+0

我意識到這一點,但在此之後你建議創建什麼Map Cemo

+0

您可以在我的解決方案中保存幾行文字。我離開他們,所以它更具可讀性。 – soulcheck

+0

我投了贊成票:)但我想再等一等。謝謝:)順便提一下第一次不清楚這個問題。 Stackoverflow忽略它:) – Cemo

0

如果您正在使用的配置文件是不嚴格的,你可以使用一個XML文件來存儲把定義。

示例定義:

<resources> 
<configuration> 
    <datasrouce> 
    <connection name="" url="" password="" user=""/> 
    <connection name="" url="" password="" user=""/> 
    </datasource> 
</configuration> 
</resources> 

的使用連接管理器類,你可以只讀取XML獲得連接信息,並創建連接的一個實例,奶源他們。

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(); 
+0

我投了贊成,因爲這個想法和優雅的解決方案,我也許會使用解決方案,你建議,但爲了適應我選擇另一個問題的答案。 :)順便科林,我也是你的粉絲。 :)感謝您的貢獻。不過,我也想看到你的另一個美妙的實施,以更好地學習。 ;) – Cemo

+0

@Sessizlik我想我的觀點是使用正確的工具。你在這裏得到的是一些你想讀的結構化數據。屬性文件是平坦的,不能很好地表達結構。番石榴不會改變這個事實。 Gson(順便說一句,Google的JSON轉換庫)似乎更合適,它使得這很簡單。 – ColinD