如何在重复控件

时间:2016-02-12 15:26:27

标签: jdbc xpages

目前,我对计算字段进行了重复控制,该字段显示Domino视图中的列值。在重复控件的每一行中,我有另一个计算字段,它执行从SQL表中返回值的SQL查询。 SQL查询的参数使用Domino视图中的一个列值。

对于SQL计算字段,我编写了一个实例化JDBC连接的函数,然后对repeat控件中的每一行执行SQL查询。该函数如下所示(pTextNo参数来自Domino视图中的一个列值):

function getFormulaTextDetailRows(pTextNo){
if(pTextNo == null){return ""};
var con:java.sql.Connection;
try {
    con = @JdbcGetConnection("as400");
    vStatement = "SELECT TXSQN, TXDTA FROM LIB1.PRTEXTS WHERE RTRIM(TEXT#) = ? ORDER BY TXSQN";
    var vParam = [pTextNo];
    var resultset:java.sql.ResultSet = @JdbcExecuteQuery(con, vStatement, vParam);
    var returnList = "<ul>";
    //format the results
    while(resultset.next()){
        returnList += ("<li>" + resultset.getString("TXDTA").trim() + "</li>");
    }
    returnList += "</ul>";
}catch(e){
    returnList = e.toString()
}finally{
    con.close();
}
    return returnList;
}

这很好但我确定这不是利用JDBC连接的最有效方式。在重复控件中的每一行上打开和关闭JDBC连接是不对的,我担心当多个人打开XPage时,服务器将遇到打开连接数的困难。

在互联网上做了一些研究后,似乎我应该在页面上使用jdbcConnectionManager。

我在自定义控件中添加了一个jdbcConnectionManager,并在包含重复控件的面板中添加了一个jdbcQuery数据源。 jdbcConnectionManager如下所示:

<xe:jdbcConnectionManager
    id="jdbcConnectionManager1"
    connectionName="as400">
</xe:jdbcConnectionManager>

jdbcQuery数据源如下所示:

<xe:jdbcQuery
    var="jdbcProcessText"
    scope="request"
    calculateCount="true"
    sqlQuery="SELECT TXSQN,TXDTA FROM DOMINO.PRTEXTS WHERE RTRIM(TEXT#) = ? AND TXSQN != '0' ORDER BY TXSQN"
    connectionManager="jdbcConnectionManager1">
    <xe:this.sqlParameters>
        <xe:sqlParameter value="#{javascript:requestScope.processTextNo}">
        </xe:sqlParameter>
    </xe:this.sqlParameters>
</xe:jdbcQuery>

重复控件中我的计算字段的value属性如下所示:

requestScope.processTextNo = textrow.getDocument().getItemValueString('ProcessTextNo');
var vCount = jdbcProcessText.getCount();
var returnList = "<ul>";
for(i=0; i<vCount; i++){
    returnList += ("<li>" + jdbcProcessText.get(i).getColumnValue("TXDTA") + "</li>");
}
returnList += "</ul>";
return returnList;

我遇到的问题是我根本没有从JDBC查询中获取任何数据。即使我硬编码一个值,我知道在jdbcQuery对象的sqlParameter属性的SQL表中存在的值,我仍然没有得到任何结果。我怀疑我没有正确调用jdbcQuery对象,但我无法弄清楚如何这样做。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

You may want to reconsider your approach. I would suggest creating a Java bean to get the Domino view data, loop through that and call out to your query for each row in the view. Build up a List (Java List) of a Row class that has all the data you want to show. Then in the repeat call to your Java bean to a method that returns the List of Row classes. In each control in the repeat you would call to the getXXX method in your Row class. This way you can quickly build the List the repeat works on. Doing it your way in the control in the repeat will be very slow.

Howard

答案 1 :(得分:0)

这是我写的用来完成工作的bean。在开始时,它打开与SQL数据源的连接,使用文档UNID作为键来获取viewEntryCollection,然后将列值放入viewEntryCollection中每行的HashMap中。 HashMap中的一个值是从SQL查询中提取的。我的重复控件遍历bean返回的List。换句话说,bean返回一个HashMaps List,其中每个HashMap中的大多数值来自Domino视图条目数据,一个值来自SQL(不确定这是否是正确的说法,但对我来说是有道理的!)

这是我的代码:

package com.foo;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import javax.faces.context.FacesContext;

import lotus.domino.Database;
import lotus.domino.NotesException;
import lotus.domino.View;
import lotus.domino.ViewEntry;
import lotus.domino.ViewEntryCollection;

import com.ibm.xsp.extlib.relational.util.JdbcUtil;
import com.ibm.xsp.extlib.util.ExtLibUtil;

public class ProcessTextLines implements Serializable {

    private static final long serialVersionUID = 1L;

    private Connection conn = null;

    public int rowCount = 0;

    public int getRowCount() {
        return rowCount;
    }

    // public void setRowCount(int rowCount) {
    // this.rowCount = rowCount;
    // }

    public ProcessTextLines() {
        /*
         * argumentless constructor
         */
        try {
            // System.out.println("ProcessTextLines.java - initialising connection to as400");
            this.conn = this.initialiseConnection();

        } catch (SQLException e) {
            e.printStackTrace();
        }

        finally {
            if (this.conn != null) {
                // System.out.println("ProcessTextLines.java - closing connection to as400");
                try {
                    this.conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public List<HashMap<String, String>> getRows(final String unid)
            throws NotesException {

        List<HashMap<String, String>> result = new ArrayList<HashMap<String, String>>();

        try {
            Database db = ExtLibUtil.getCurrentSession().getCurrentDatabase();
            View view = db.getView("luProductMasterFormula");
            view.setAutoUpdate(false);
            ViewEntryCollection vec = view.getAllEntriesByKey(unid, true);
            ViewEntry ve = vec.getFirstEntry();
            while (ve != null) {

                result.add(processRowVals(ve));
                rowCount++;

                ViewEntry tmp = vec.getNextEntry(ve);
                ve.recycle();
                ve = tmp;
            }

            view.recycle();
            db.recycle();
            vec.recycle();
        } catch (NotesException e) {
            e.printStackTrace();
        }

        return result;

    }

    /*
     * Create a HashMap of names + column values from a ViewEntry
     */
    @SuppressWarnings("unchecked")
    private HashMap<String, String> processRowVals(ViewEntry ve) {

        HashMap<String, String> processRow = new HashMap<String, String>();

        try {
            Vector cols = ve.getColumnValues();

            processRow.put("sequenceNo", cols.get(1).toString());
            processRow.put("textNo", cols.get(3).toString());
            processRow.put("status", cols.get(6).toString());
            processRow.put("textLines", getProcessTextLines(cols.get(3).toString()));
            // unid of the entry's doc
            processRow.put("unid", ve.getUniversalID());

        } catch (NotesException e) {
            e.printStackTrace();
        }

        return processRow;
    }

    private Connection initialiseConnection() throws SQLException {

        Connection connection = null;

        try {
            connection = JdbcUtil.createNamedConnection(FacesContext
                    .getCurrentInstance(), "as400");

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return connection;
    }

    private String getProcessTextLines(String textNo) {

        String resultHTML = "<ul class=\"processTextList\">";

        try {
            // System.out.println("ProcessTextLines.java - setting SQL parameter: " + textNo);
            PreparedStatement prep = conn
                    .prepareStatement("SELECT TXSQN,TXDTA FROM LIB1.PRTEXTS WHERE RTRIM(TEXT#) = ? AND TXSQN != '0' ORDER BY TXSQN");
            // supply a value to the PreparedStatement's parameter (the first
            // argument is 1 because it is the first parameter)
            prep.setString(1, textNo);

            ResultSet resultSet = prep.executeQuery();
            while (resultSet.next()) {
                resultHTML += ("<li>" + resultSet.getString("TXDTA").trim() + "</li>");
            }

        } catch (SQLException e) {
            // e.printStackTrace();
        }

        resultHTML += "</ul>";
        return resultHTML;

    }
}

由于我缺乏Java知识,我花了一段时间,但是@Howard提供的指示加上我在网上找到的一些零碎的东西,我能够将它拼凑在一起。

在构造函数中打开和关闭SQL连接对我来说很直观,但它似乎有用。