在XPages和Java中检索数据的最佳方法

在XPages和Java中检索数据的最佳方法,xpages,Xpages,很抱歉,这不是一个“编码”问题,但在学习XPages和Java的过程中花了相当长的时间后,我仍然难以找到关于正确实现基础的确切信息 使用Java开发XPages应用程序时,访问数据的最佳或最有效方法是什么 1) 设置和维护一个视图,文档中的每个字段都有一列,并通过ViewEntry.getColumnValues().get(int)检索数据;i、 e.不访问文档并从视图中检索数据。这就是我一直在做的,但是我的视图列随着维护列序列的麻烦不断增加。我的理解是这是一种更快的方法 或 2) 只需在必要

很抱歉,这不是一个“编码”问题,但在学习XPages和Java的过程中花了相当长的时间后,我仍然难以找到关于正确实现基础的确切信息

使用Java开发XPages应用程序时,访问数据的最佳或最有效方法是什么

1) 设置和维护一个视图,文档中的每个字段都有一列,并通过ViewEntry.getColumnValues().get(int)检索数据;i、 e.不访问文档并从视图中检索数据。这就是我一直在做的,但是我的视图列随着维护列序列的麻烦不断增加。我的理解是这是一种更快的方法


2) 只需在必要时使用视图将所有内容放到文档中,但在主文档中使用数据库.getDocumentByUNID().getItemValueAsString(“字段”),不必担心添加大量列,维护起来容易得多,但访问文档是否会减慢速度?

这是关于平衡的。每样东西都有它的价格。大视图(案例1)会降低索引速度。每次打开文档(案例2)都会降低代码的速度

找到介于两者之间的东西。

无论是1)还是2)

通过以下方式在Java类中管理文档数据:

  • 将Java类中的所有文档项一次性读入类字段
  • 还记得类字段中的UNID吗
  • 阅读项目后回收文档
  • 在UNID的帮助下重新获取每次读/写的文档,并在之后进行回收
Database.getDocumentByUNID()非常快,但对一个文档只调用一次,而不是对每个项目调用一次

更新

正如您在评论中提到的,您有一个包含50000个不同类型文档的数据库

我会尽量只看你真正需要的文件。例如,如果您想阅读某个客户的所有支持票证文档,您可以使用包含按客户排序的支持票证的视图(无附加列)。您可以使用
getAllDocumentsByKey(customer,true)
获取文档,并将Java对象(每个对象基于一个文档)放入一个映射中


此外,还可以维护缓存。创建模型映射(对于文档类型,model=Java对象)并使用UNID作为键。这样可以避免两次读取/存储文档。

这是一个非常好的问题。首先,我要说我100%同意Knut,这就是我如何编写表示文档的对象的方法

下面我粘贴了一个我通常做的代码示例。请注意,这段代码使用的是OpenNTF Domino API,它为我处理了循环利用的问题。所以你不会看到任何回收电话

但正如克努特所说,抓住文件。得到你所需要的,然后它可以再次被丢弃。当你想保存一些东西时,只需再次获取文档即可。在此阶段,您甚至可以检查lastModified或查看自加载后发生的另一次保存

有时为了方便起见,我重载load()方法并添加NotesViewEntry: 公共布尔加载(ViewEntry){}

然后在那里我可以得到文档,如果是特定情况,可以使用视图列

现在,当一次处理单个文档时,这种方法非常有效。如果我想为一个集合循环浏览许多文档,那么它的效果非常好。但是,如果你得到太多,你可能会看到一些偷听开始放慢速度。我有一个应用程序,如果我将30000个这样的文档“输入”到一个集合中,它可能会变得有点慢

我还没有一个很好的答案。我试过很多列的大视图,听起来像是你做的。我已经尝试过创建一个包含所需字段的对象的低级基本版本,该版本更适合处理viewEntry及其列。我还没有一个很好的答案。我认为,确保你尽可能地懒散地加载是非常重要的

无论如何,这里有一个代码示例,展示了我如何构建大多数文档驱动对象

package com.notesIn9.video;

import java.io.Serializable;
import java.util.Date;

import org.openntf.domino.Database;
import org.openntf.domino.Document;
import org.openntf.domino.Session;
import org.openntf.domino.View;
import org.openntf.domino.utils.Factory;

public class Episode implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String title;
    private Double number;
    private String authorId;
    private String contributorId;
    private String summary;
    private String subTitle;
    private String youTube;
    private String libsyn;
    private Date publishedDate;
    private Double minutes;
    private Double seconds;

    private String blogLink;

    private boolean valid;
    private String unid;
    private String unique;
    private String creator;

    public Episode() {
        this.unid = "";

    }

    public void create() {

        Session session = Factory.getSession(); // this will be slightly
                                                // different if not using the
                                                // OpenNTF Domino API
        this.setUnique(session.getUnique());
        this.setCreator(session.getEffectiveUserName());
        this.valid = true;

    }

    public Episode load(Document doc) {

        this.loadValues(doc);
        return this;

    }

    public boolean load(String key) {

        // this key is the unique key of the document. UNID would be
        // faster/easier.. I just kinda hate using them and seeing them in URLS
        Session session = Factory.getSession();
        Database currentDb = session.getCurrentDatabase();
        Database db = session.getDatabase(currentDb.getServer(), "episodes.nsf");
        View view = db.getView("lkup_episodes");
        Document doc = view.getDocumentByKey(key); // This is deprecated because
                                                    // the API prefers to use
                                                    // getFirstDocumentByKey

        if (null == doc) {
            // document not found. DANGER
            this.valid = false;
        } else {

            this.loadValues(doc);

        }

        return this.valid;

    }

    private void loadValues(Document doc) {

        this.title = doc.getItemValueString("title");
        this.number = doc.getItemValueDouble("number");
        this.authorId = doc.getItemValueString("authorId");
        this.contributorId = doc.getItemValueString("contributorId");
        this.summary = doc.getItemValueString("summary");
        this.subTitle = doc.getItemValueString("subtitle");
        this.youTube = doc.getItemValueString("youTube");
        this.libsyn = doc.getItemValueString("libsyn");
        this.publishedDate = doc.getItemValue("publishedDate", Date.class);
        this.minutes = doc.getItemValueDouble("minutes");
        this.seconds = doc.getItemValueDouble("seconds");
        this.blogLink = doc.getItemValueString("blogLink");

        this.unique = doc.getItemValueString("unique");
        this.creator = doc.getItemValueString("creator");

        this.unid = doc.getUniversalID();
        this.valid = true;

    }

    public boolean save() {

        Session session = Factory.getSession();
        Database currentDb = session.getCurrentDatabase();
        Database db = session.getDatabase(currentDb.getServer(), "episodes.nsf");
        Document doc = null;

        if (this.unid.isEmpty()) {
            doc = db.createDocument();
            doc.replaceItemValue("form", "episode");
            this.unid = doc.getUniversalID();
        } else {
            doc = db.getDocumentByUNID(this.unid);
        }

        this.saveValues(doc);
        return doc.save();

    }

    private void saveValues(Document doc) {

        doc.replaceItemValue("title", this.title);
        doc.replaceItemValue("number", this.number);
        doc.replaceItemValue("authorId", this.authorId);
        doc.replaceItemValue("contributorId", this.contributorId);
        doc.replaceItemValue("summary", this.summary);
        doc.replaceItemValue("subtitle", this.subTitle);
        doc.replaceItemValue("youTube", this.youTube);
        doc.replaceItemValue("libsyn", this.libsyn);
        doc.replaceItemValue("publishedData", this.publishedDate);
        doc.replaceItemValue("minutes", this.minutes);
        doc.replaceItemValue("seconds", this.seconds);
        doc.replaceItemValue("blogLink", this.blogLink);

        doc.replaceItemValue("unique", this.unique);
        doc.replaceItemValue("creator", this.creator);

    }

    // getters and setters removed to condense code.


    public boolean remove() {

        Session session = Factory.getSession();
        Database currentDb = session.getCurrentDatabase();
        Database db = session.getDatabase(currentDb.getServer(), "episodes.nsf");

        if (this.unid.isEmpty()) {
            // this is a new Doc
            return false;

        } else {

            Document doc = db.getDocumentByUNID(this.getUnid());
            return doc.remove(true);

        }

    }

}

对不起,我不明白你的第一个要点,克努特。我的问题是-检索文档后,最好是从视图列或单个文档项将数据传递到每个类字段中。我的建议是一次读取单个文档,但同时读取所有项。你的2)会再次阅读每个项目的文档…是的,对不起,我只会收到一次文档,它写得很糟糕。通常我会使用getDocumentByUNID(),而不是浪费时间处理大量的视图列。非常感谢。我根据你在大卫回答下面的评论更新了我的答案。除了快速访问某些文档之外,您最好使用一些视图,但不必在视图中创建大量列。我想,由于涉及到许多变化,似乎没有确定的最佳方法。我喜欢模型地图上的提示。谢谢你的帮助。嗨,大卫,这正是我想要纠正的情况。一个有许多视图的数据库,视图可能只包含几百个文档,但整个应用程序有50000个不同类型的文档。然后,我在一个视图中循环创建一个ArrayList或对象映射,例如每个客户的所有支持票证的对象。因此,我试图从总体上理解,使用循环getDocumentByUNID()访问总共50000个文档并从文档中获取数据,或者从特定视图的视图条目和列构建映射是否更好。非常感谢你的帮助。你需要做一点实验。。如果你真的需要收集所有50000个,那么我会尝试使用viewEntry/列值的东西。。。但是你得玩它。。也许您不需要预加载每个字段,可以延迟加载一些字段。你走对了我想。。。但将50000个文档转换为对象确实需要一些时间。所以你也希望能够做到