在java中为xpages构建缓存查找系统

Dec*_*nch 6 xpages

我们在多个应用程序中使用了许多查找数据库,并且我正在尝试找出通过OSGi插件库中的java函数或bean提供这些查找数据库的最佳和最有效的方法.

我想要实现的是一些创建函数的方法,我可以在查找键和字段名称中传递,函数将返回正确的值和可能的对象类型(以处理数据时间值).它还需要在应用程序级别缓存大约一个小时的值,因为这些查找文档根本不会更改.

通常,我想将它们用于显示目的,这样我只需要将密钥存储在我的笔记文档中,然后使用类似下面的内容在屏幕上显示我需要的内容

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

Jer*_*dge 8

你现在可以使用scoped bean来做这件事,但需要注意的是bean是特定于NSF的.虽然我相信XSP入门套件包含一个如何做一个服务器作用域bean的例子(它实际上是一个单例,意味着整个JVM只有一个类的实例).

首先创建一个名为CachedData的简单可序列化POJO,它有两个成员字段,第一个是一个字段,它保存一个日期时间值,指示您上次从磁盘读取数据的时间,第二个是某种列表对象,如矢量,这是你的价值观.

然后创建另一个名为ServerMap的POJO,它有一个map <string,map <string,map <string,map <Object,map <object,CachedData >>>>作为成员,以及一个名为doCachedLookup()的函数.该函数的参数可以与@DbLookup,服务器,数据库,视图,密钥等几乎相同.然后在doCachedLookup中,检查ServerMap是否存在指定的服务器作为密钥.如果它不存在,则创建一个新映射并将其插入ServerMap,其中键为服务器名称.如果确实存在,则在该映射中查找数据库名称,然后在下一个映射中查找该视图,最后查找最后一个映射中的值.获得CachedData对象后,可以检查日期时间字段并查看它是否已过期,如果不是,则返回向量,如果是,则丢弃它,然后执行全新查找,并重新缓存数据,然后返回向量.

这是代码示例,我在我的重载方法中获取列而不是获取字段名称有点懒,而且我使用了一些弃用的java日期方法,但它将为您提供一个良好的基础.所有代码都经过测试:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

}
Run Code Online (Sandbox Code Playgroud)

有关如何在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>
Run Code Online (Sandbox Code Playgroud)