xpages

2012-03-06 7 views
6

के लिए जावा में कैशिंग लुकअप सिस्टम बनाना हमारे पास कई लुकअप डेटाबेस हैं जिनका उपयोग हम कई अनुप्रयोगों में करते हैं और मैं इन लुकअप डेटाबेस को जावा फ़ंक्शन के माध्यम से उपलब्ध कराने के लिए सबसे अच्छा और सबसे प्रभावी तरीका जानने का प्रयास कर रहा हूं या ओएसजीआई प्लगइन लाइब्रेरी में बीन।xpages

मैं क्या प्राप्त करना चाहते हैं एक समारोह है कि मैं एक देखने कुंजी और एक क्षेत्र के नाम पर पारित कर सकते हैं और समारोह वापस आ जाएगी सही मान और संभवतः प्रकार वस्तु (datatime मूल्यों से निपटने के लिए) बनाने के कुछ तरीका है। इसे एप्लिकेशन स्तर पर लगभग एक घंटे के लिए मूल्य को कैश करने की भी आवश्यकता होगी क्योंकि इन लुकअप दस्तावेज़ बिल्कुल नहीं बदलते हैं।

आमतौर पर मैं प्रदर्शन प्रयोजनों के लिए उपयोग करने के लिए इतना है कि मैं सिर्फ अपने नोट्स दस्तावेज़ में कुंजी संग्रहीत और फिर कुछ ऐसा उपयोग करने की आवश्यकता चाहते हैं स्क्रीन मैं क्या जरूरत है पर प्रदर्शित करने के लिए निम्नलिखित

<xp:text escape="true" id="computedField1"> 
    <xp:this.value><![CDATA[#{javascript:com.mycompany.lookup.GetDoc("docID","fieldName")}]]></xp:this.value> 
</xp:text> 
+0

यह सुनिश्चित करने के लिए, क्या इसे ओजीआई प्लगइन होने की आवश्यकता है? या डेटाबेस में परिभाषित उपयोगकर्ताबीन के साथ भी किया जा सकता है? लुकअप डेटाबेस संग्रहीत करने के बारे में जानकारी कहां है? – jjtbsomhorst

+0

यह ओएसजीआई प्लगइन में परिभाषित एक बीन हो सकता है। मेरी सोच यह है कि प्लगइन में होने से यह सर्वर पर वैश्विक हो जाएगा, इसलिए कोई भी ऐप जिसे लुकअप करने की ज़रूरत है, केवल फ़ंक्शन को एक मान वापस करने के लिए कॉल कर सकता है। लुकअप डेटाबेस सर्वर पर एक निश्चित स्थान पर हैं। –

उत्तर

8

आप स्कोप्ड बीन्स के साथ अब यह बहुत अच्छी तरह से कर सकते हैं, एक चेतावनी के साथ कि एक बीन एनएसएफ विशिष्ट है। हालांकि एक्सएसपी स्टार्टर किट में मेरा मानना ​​है कि सर्वर स्कोप्ड बीन (जो वास्तव में एक सिंगलटन है, का अर्थ है कि पूरे जेवीएम के लिए कक्षा का केवल एक उदाहरण है) का एक उदाहरण शामिल है।

सबसे पहले एक सरल धारावाहिक पीओजेओ बनाएं जिसे कैश्डडाटा कहा जाता है जिसमें दो सदस्य फ़ील्ड होते हैं, पहला ऐसा क्षेत्र होता है जिसमें दिनांक समय मान होता है जो इंगित करता है कि जब आप डिस्क से डेटा को आखिरी बार पढ़ते हैं, और दूसरा किसी प्रकार की सूची वस्तु है , एक वेक्टर की तरह, जो आपके मूल्य रखता है।

फिर एक और POJO ServerMap मानचित्र < स्ट्रिंग है कि कहा जाता है, नक्शा < स्ट्रिंग, नक्शे < स्ट्रिंग, नक्शे < वस्तु, नक्शे < वस्तु, CachedData > > > > एक सदस्य के रूप बनाते हैं, और एक समारोह doCachedLookup कहा जाता है() या ऐसा कुछ। उस फ़ंक्शन के पैरामीटर लगभग @DbLookup, सर्वर, डेटाबेस, व्यू, कुंजी इत्यादि के समान हो सकते हैं। फिर doCachedLookup में, निर्दिष्ट सर्वर के अस्तित्व के लिए कुंजी के रूप में अपना सर्वर मैप जांचें। यदि यह अस्तित्व में नहीं है, तो एक नया नक्शा बनाएं और उसे सर्वर नाम के साथ सर्वरमैप में डालें। यदि यह अस्तित्व में है, तो उस मानचित्र में डेटाबेस नाम देखें, फिर अगले मानचित्र में दृश्य, फिर अंत में अंतिम मानचित्र में मान। एक बार जब आप कैशडेटा ऑब्जेक्ट प्राप्त कर लेते हैं, तो आप डेट टाइम फ़ील्ड देख सकते हैं और देख सकते हैं कि यह समाप्त हो गया है, अगर यह नहीं है, तो वेक्टर वापस करें, और यदि यह है, तो इसे छोड़ दें, और फिर एक नया लुकअप करें, और फिर कैश करें डेटा, और फिर वेक्टर वापस।

यहां कोड नमूने हैं, मैं एक स्तंभ नाम बनाम कॉलम प्राप्त करने के लिए अपने अधिभारित तरीकों में थोड़ा आलसी था, और मैं कुछ बहिष्कृत जावा तिथि विधियों का उपयोग करता हूं, लेकिन यह आपको शुरू करने के लिए एक अच्छा आधार देगा। सभी कोड का परीक्षण किया जाता है:

CachedData कक्षा:

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 वर्ग है कि एक सिंगलटन के रूप में कार्यान्वित किया जाता है इतना है कि यह सर्वर चौड़ा किया जा सकता है: कैसे में उपयोग करने पर

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); 
    } 

} 

उदाहरण एक 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> 

+1

यह वास्तव में सहायक रहा है। चूंकि मेरे लुकअप डेटाबेस तय किए गए हैं, इसलिए मैंने संख्या को कम किया है यदि फंक्शन में केवल कुंजी और फ़ील्ड में पास करने के लिए चर की आवश्यकता होती है और लुकअप के लिए आवश्यक बाकी फ़ंक्शन के भीतर सेट होते हैं। इसके लिए धन्यवाद। –

+0

मुझे सर्वर स्कोप्ड बीन्स के साथ कोई अनुभव नहीं है लेकिन इस तरह के बीन को कब तक अवैध करना होगा? एनएसएफ स्तर पर आप स्मृति से एप्लिकेशन को साफ़ करने से पहले टाइमआउट निर्दिष्ट कर सकते हैं। – jjtbsomhorst

+1

यह वास्तव में एक सर्वर स्कैन बीन के रूप में एक ही अर्थ में बीन नहीं है। इसका एक सिंगलटन कहा जाता है, जिसका अर्थ है कि केवल एक उदाहरण बनाया गया है और पूरे JVM के लिए उपयोग किया जाता है और JVM पुनरारंभ होने तक मर नहीं जाता है। चूंकि यह मामला है, इसलिए कैश्डडाटा में अपडेटटाइम सदस्य है, जो कैश किए गए डेटा के वैध जीवनकाल को नियंत्रित करता है। यह उदाहरण किसी भी कैश को नहीं खींचता है, इसलिए यह अभी भी स्मृति में बैठता है, भले ही यह अब मान्य न हो, और एक और मजबूत कार्यान्वयन निर्दिष्ट अवधि में स्टेल कैश रिकॉर्ड को हल करने के लिए काम कर सकता है। –

2

जब आप बीन्स करते हैं तो आप एसएसजेएस से अधिक सामग्री प्राप्त करने के लिए ईएल का उपयोग कर सकते हैं। और हाँ - एक्सएसपी स्टार्टर किट से सर्वर स्कोप का उपयोग करें। कैशिंग के लिए: पहिया को पुन: पेश न करें!उपलब्ध फैंसी कैशिंग के सभी प्रकारों का एक बहुत ही पूर्ण कार्यान्वयन उपलब्ध है: http://commons.apache.org/jcs/ मैंने इसे पहले टॉमकैट ऐप में इस्तेमाल किया और यह बहुत विश्वसनीय काम करता था। मुझे नहीं लगता कि यह आपके काम के लिए एक अच्छा विकल्प क्यों नहीं होगा।

संबंधित मुद्दे