Ho sempre sbagliato, sono sicuro che anche molti altri hanno un riferimento tramite una mappa e scrivono in DB ecc.
Ho bisogno di farlo bene, e non so proprio come farlo. So come voglio che i miei oggetti siano memorizzati nella cache ma non sono sicuro su come ottenerlo. Ciò che complica le cose è che devo fare questo per un sistema legacy in cui il DB può cambiare senza preavviso alla mia applicazione.
Quindi nel contesto di un'applicazione web, supponiamo di avere un WidgetService
che ha diversi metodi:
Widget getWidget();
Collection<Widget> getAllWidgets();
Collection<Widget> getWidgetsByCategory(String categoryCode);
Collection<Widget> getWidgetsByContainer(Integer parentContainer);
Collection<Widget> getWidgetsByStatus(String status);
Dato questo, potrei decidere di memorizzare nella cache con la firma del metodo, cioè getWidgetsByCategory("AA")
avrebbe una singola voce di cache, o potrei citare i widget individualmente, il che sarebbe difficile, credo; OPPURE, una chiamata a qualsiasi metodo dovrebbe prima memorizzare nella cache TUTTI i widget con una chiamata a getAllWidgets()
ma getAllWidgets()
produrrebbe cache che corrispondono a tutte le chiavi per le altre chiamate di metodo. Ad esempio, prendi il seguente codice teorico non testato.
Collection<Widget> getAllWidgets() {
Entity entity = cache.get("ALL_WIDGETS");
Collection<Widget> res;
if (entity == null) {
res = loadCache();
} else {
res = (Collection<Widget>) entity.getValue();
}
return res
}
Collection<Widget> loadCache() {
// Get widgets from underlying DB
Collection<Widget> res = db.getAllWidgets();
cache.put("ALL_WIDGETS", res);
Map<String, List<Widget>> byCat = new HashMap<>();
for (Widget w : res) {
// cache by different types of method calls, i.e. by category
if (!byCat.containsKey(widget.getCategory()) {
byCat.put(widget.getCategory(), new ArrayList<Widget>);
}
byCat.get(widget.getCatgory(), widget);
}
cacheCategories(byCat);
return res;
}
Collection<Widget> getWidgetsByCategory(String categoryCode) {
CategoryCacheKey key = new CategoryCacheKey(categoryCode);
Entity ent = cache.get(key);
if (entity == null) {
loadCache();
}
ent = cache.get(key);
return ent == null ? Collections.emptyList() : (Collection<Widget>)ent.getValue();
}
NOTA : Non ho lavorato con un gestore cache, il codice sopra illustra cache
come un oggetto che può contenere cache per coppie chiave / valore, sebbene non sia modellato su alcuna implementazione specifica.
Usando questo ho il vantaggio di essere in grado di memorizzare nella cache tutti gli oggetti nei diversi modi in cui verranno chiamati con solo singoli oggetti nell'heap, mentre se dovessi memorizzare nella cache l'invocazione di chiamata del metodo tramite dire Spring, sarebbe (credo ) memorizza nella cache più copie degli oggetti.
Desidero davvero provare a capire i modi migliori per memorizzare nella cache gli oggetti del dominio prima di intraprendere il percorso sbagliato e renderlo più difficile per me stesso in seguito. Ho letto la documentazione sul sito web di Ehcache e ho trovato vari articoli di interesse, ma nulla per dare una buona tecnica solida.
Dato che sto lavorando con un sistema ERP, alcune chiamate DB sono molto complicate, non che il DB sia lento, ma la rappresentazione aziendale degli oggetti di dominio lo rende molto goffo, in aggiunta al fatto che ci sono in realtà 11 diversi Nei database in cui è possibile contenere informazioni che questa applicazione si sta consolidando in un'unica vista, ciò rende la cache molto importante.