Ty może całkiem dobrze zrobić to teraz z ziarnami o określonym zasięgu, z jednym zastrzeżeniem, że fasola jest specyficzna dla NSF. Chociaż wydaje mi się, że zestaw startowy XSP zawiera przykład, jak wykonać komponent bean z obsługą serwera (który jest tak naprawdę singletonem, co oznacza, że istnieje tylko jedno wystąpienie tej klasy dla całej maszyny JVM).
Najpierw utwórz proste POJO z serializacją o nazwie CachedData, które ma dwa pola składowe, pierwszym jest pole zawierające wartość daty, która wskazuje, kiedy ostatnio odczytałeś dane z dysku, a drugie jest jakimś obiektem listy , podobnie jak wektor, który trzyma twoje wartości.
Następnie utworzyć kolejną POJO nazwie ServerMap że ma map < ciąg, mapa < ciąg, mapa < ciąg, mapa < Object, mapa < obiekt, CachedData > > > > jako członek, a funkcja nazywa doCachedLookup() lub coś w tym stylu. Parametry tej funkcji mogą być prawie takie same jak @DbLookup, serwer, baza danych, widok, klucz itp. Następnie w instrukcji doCachedLookup sprawdź swoją Mapę serwerów pod kątem istnienia określonego serwera jako klucza. Jeśli nie istnieje, utwórz nową mapę i wstaw ją do mapy serwerów z kluczem będącym nazwą serwera. Jeśli istnieje, wyszukaj nazwę bazy danych na tej mapie, następnie widok na następnej mapie, a na końcu wartość na ostatniej mapie. Po pobraniu obiektu CachedData można sprawdzić pole daty i sprawdzić, czy wygasło, a jeśli nie, zwrócić wektor, a jeśli tak, odrzucić go, a następnie wykonać nowe wyszukiwanie i ponownie zapisać w pamięci podręcznej. dane, a następnie zwróć wektor.
Oto przykłady kodu, byłem trochę leniwy w swoich przeciążonych metodach uzyskiwania kolumny w porównaniu z uzyskiwaniem nazwy pola i używam pewnych wycofanych metod datowania java, ale to da ci dobrą podstawę do rozpoczęcia. Cały kod jest testowany:
CachedData Klasa: klasa
package com.ZetaOne.example;
import java.io.Serializable;
import java.util.Date;
import java.util.Vector;
public class CachedData implements Serializable {
private static final long serialVersionUID = 1L;
private Date updateTime;
private Vector<Object> values;
public Date getUpdateTime() {
return this.updateTime;
}
public void setUpdateTime(Date UpdateTime) {
updateTime = UpdateTime;
}
public Vector<Object> getValues() {
return this.values;
}
public void setValues(Vector<Object> values) {
this.values = values;
}
}
CachedLookup który jest zaimplementowany jako pojedyncza tak, że może on być stosowany całego serwera:
package com.ZetaOne.example;
import java.io.Serializable;
import java.util.Date;
import java.util.Vector;
import com.ZetaOne.example.CachedData;
import java.util.HashMap;
import java.util.Collections;
import java.util.Map;
import lotus.domino.Session;
import lotus.domino.Database;
import lotus.domino.View;
import lotus.domino.NotesException;
import lotus.domino.ViewEntryCollection;
import lotus.domino.ViewEntry;
import lotus.domino.Document;
import javax.faces.context.FacesContext;
public class CachedLookup implements Serializable {
private static CachedLookup _instance;
private static final long serialVersionUID = 1L;
private Map<String, HashMap<String, HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>>> cachedLookup;
public static CachedLookup getCurrentInstance() {
if (_instance == null) {
_instance = new CachedLookup();
}
return _instance;
}
private CachedLookup() {
HashMap<String, HashMap<String, HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>>> cachedLookupMap =
new HashMap<String, HashMap<String, HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>>>();
this.cachedLookup = Collections.synchronizedMap(cachedLookupMap);
}
@SuppressWarnings("deprecation")
public Vector<Object> doCachedLookup(String serverName, String filePath, String viewName, Object keyValues, int columnNumber, boolean exactMatch) {
if (cachedLookup.containsKey(serverName)) {
if (cachedLookup.get(serverName).containsKey(filePath)) {
if (cachedLookup.get(serverName).get(filePath).containsKey(viewName)) {
if (cachedLookup.get(serverName).get(filePath).get(viewName).containsKey(keyValues)) {
if (cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).containsKey(columnNumber)) {
CachedData cache = cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).get(columnNumber);
if (cache.getUpdateTime().compareTo(new Date()) > 0) {
System.out.println("Cache Hit");
return cache.getValues();
}
}
}
}
}
}
System.out.println("Cache Miss");
// if we drop to here, cache is either expired or not present, do the lookup.
try {
Session session = (Session)resolveVariable("session");
Database db = session.getDatabase(serverName, filePath);
View view = db.getView(viewName);
ViewEntryCollection vc = view.getAllEntriesByKey(keyValues, exactMatch);
ViewEntry ve, vn;
ve = vc.getFirstEntry();
Vector<Object> results = new Vector<Object>();
while (ve != null) {
results.add(ve.getColumnValues().elementAt(columnNumber));
vn = vc.getNextEntry();
ve.recycle();
ve = vn;
}
vc.recycle();
if (!cachedLookup.containsKey(serverName)) {
cachedLookup.put(serverName, new HashMap<String, HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>>());
}
if (!cachedLookup.get(serverName).containsKey(filePath)) {
cachedLookup.get(serverName).put(filePath, new HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>());
}
if (!cachedLookup.get(serverName).get(filePath).containsKey(viewName)) {
cachedLookup.get(serverName).get(filePath).put(viewName, new HashMap<Object, HashMap<Object, CachedData>>());
}
if (!cachedLookup.get(serverName).get(filePath).get(viewName).containsKey(keyValues)) {
cachedLookup.get(serverName).get(filePath).get(viewName).put(keyValues, new HashMap<Object, CachedData>());
}
CachedData cache;
if (cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).containsKey(columnNumber)) {
cache = cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).get(columnNumber);
} else {
cache = new CachedData();
}
Date dt = new Date();
dt.setHours(dt.getHours() + 1);
cache.setUpdateTime(dt);
cache.setValues(results);
cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).put(columnNumber, cache);
view.recycle();
db.recycle();
return results;
} catch (NotesException e) {
// debug here, im lazy
return null;
}
}
public Vector<Object> doCachedLookup(String serverName, String filePath, String viewName, Object keyValues, String fieldName, boolean exactMatch) {
if (cachedLookup.containsKey(serverName)) {
if (cachedLookup.get(serverName).containsKey(filePath)) {
if (cachedLookup.get(serverName).get(filePath).containsKey(viewName)) {
if (cachedLookup.get(serverName).get(filePath).get(viewName).containsKey(keyValues)) {
if (cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).containsKey(fieldName)) {
CachedData cache = cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).get(fieldName);
if (cache.getUpdateTime().compareTo(new Date()) > 0) {
System.out.println("Cache Hit");
return cache.getValues();
}
}
}
}
}
}
System.out.println("Cache Miss");
// if we drop to here, cache is either expired or not present, do the lookup.
try {
Session session = (Session)resolveVariable("session");
Database db = session.getDatabase(serverName, filePath);
View view = db.getView(viewName);
ViewEntryCollection vc = view.getAllEntriesByKey(keyValues, exactMatch);
ViewEntry ve, vn;
ve = vc.getFirstEntry();
Vector<Object> results = new Vector<Object>();
while (ve != null) {
Document doc = ve.getDocument();
results.add(doc.getItemValue(fieldName));
doc.recycle();
vn = vc.getNextEntry();
ve.recycle();
ve = vn;
}
vc.recycle();
if (!cachedLookup.containsKey(serverName)) {
cachedLookup.put(serverName, new HashMap<String, HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>>());
}
if (!cachedLookup.get(serverName).containsKey(filePath)) {
cachedLookup.get(serverName).put(filePath, new HashMap<String, HashMap<Object, HashMap<Object, CachedData>>>());
}
if (!cachedLookup.get(serverName).get(filePath).containsKey(viewName)) {
cachedLookup.get(serverName).get(filePath).put(viewName, new HashMap<Object, HashMap<Object, CachedData>>());
}
if (!cachedLookup.get(serverName).get(filePath).get(viewName).containsKey(keyValues)) {
cachedLookup.get(serverName).get(filePath).get(viewName).put(keyValues, new HashMap<Object, CachedData>());
}
CachedData cache;
if (cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).containsKey(fieldName)) {
cache = cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).get(fieldName);
} else {
cache = new CachedData();
}
Date dt = new Date();
dt.setHours(dt.getHours() + 1);
cache.setUpdateTime(dt);
cache.setValues(results);
cachedLookup.get(serverName).get(filePath).get(viewName).get(keyValues).put(fieldName, cache);
view.recycle();
db.recycle();
return results;
} catch (NotesException e) {
// debug here, im lazy
return null;
}
}
private static Object resolveVariable(String variable) {
return FacesContext.getCurrentInstance().getApplication()
.getVariableResolver().resolveVariable(
FacesContext.getCurrentInstance(), variable);
}
}
przykład jak używać w XPage:
<xp:text id="text1">
<xp:this.value><![CDATA[#{javascript:
com.ZetaOne.example.CachedLookup.getCurrentInstance().doCachedLookup(
database.getServer(),
database.getFilePath(),
"lookup",
"Test Category",
"Value",
true
)
}]]></xp:this.value>
</xp:text>
Czy to musi być wtyczka osgi? Czy może to być również wykonane przy użyciu userbean zdefiniowanej w bazie danych? Gdzie są przechowywane informacje o przechowywanych bazach danych? – jjtbsomhorst
Może to być komponent bean zdefiniowany w wtyczce OSGi. Moim zdaniem, posiadanie go w wtyczce spowoduje, że będzie on globalny na serwerze, więc każda aplikacja, która musi wykonać odnośnik, może po prostu wywołać funkcję zwracającą wartość. Bazy wyszukiwania znajdują się w ustalonej lokalizacji na serwerze. –