///Load List Values for Improved Efficiency

Load List Values for Improved Efficiency

How to load drop-down list values at application start-up time

Reduce the number of database hits and improve your Web application’s efficiency when you load common shared list values only once. In this code-filled article, learn to load the values for drop-down lists when your Web application starts and then to share these loaded list values among all the users of your application.

If you load common shared list values only once, you can reduce the number of database hits and make your Web application more efficient. In this quick-and-easy, code-filled article, I explain how to load list values for the drop-down list at start-up time for your Web application. I also show you how to share these loaded list values among all users of the application.

You can choose from three different scenarios when your application loads a drop-down list of items:

  • Every time a page displays drop-down lists, it makes a hit to the database to load the drop-down lists. If your application sends 10 requests for five drop-down lists on a page, the number of database hits is 50 (10×5). The database hit count increases proportionally to the number of requests.
  • The application loads all drop-down list items at the start of the user session and uses them for the entire session. The drop-down list items are stored in the session. In a user session, the number of database hits is constant and the database hit count increases proportionally to the number of sessions.
  • Your application loads all drop-down list items at application start-up and uses them for all application users. The drop-down list items are stored in the application with static reference. The number of database hits is constant for the application.

In this article, I explain how to implement the third case I mention above — loading all items when the application starts.

Before I jump into the implementation details, though, it is important for you to understand that drop-down list values display in the HTML <SELECT> tag. The <SELECT> tag creates the drop-down list like so: <SELECT attribute1="..." attribute2="...">< /SELECT>. The <OPTION> tags placed inside the opening and closing <SELECT> tag define the list items. The attributes for this are:

  • MULTIPLE specifies that the user can select multiple items.
  • NAME="..." specifies the name of the list (part of the NAME/VALUE pair).
  • SIZE="..." specifies how many items are visible.

The command <OPTION value="...">item specifies an item in the drop-down list and is placed within the opening and closing <SELECT> tags. Any text that follows the <OPTION> tag is what the user sees in the list. The attributes for this are:

  • VALUE="..." specifies the value that returns (part of the NAME/VALUE pair).
  • SELECTED is already highlighted when the page loads.

Implement listload at app start-up

First, define the ApplicationServlet class to initiate the list values loading process at application start-up time. In general, the ApplicationServlet is not the primary servlet of your application. This servlet class will not do request intercept or user/session validations.

Define the entries of ApplicationServlet in the web.xml file as defined in Listing 1. The actual ApplicationServlet class follows in Listing 2.

Listing 1. Entries of ApplicationServlet: Initiate the loading process



<servlet>
<servlet-name>ApplicationServlet</servlet-name>
<display-name>ApplicationServlet</display-name>
<servlet-class>test.controller.application.ApplicationServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>ApplicationServlet</servlet-name>
<url-pattern>/ApplicationServlet</url-pattern>
</servlet-mapping>

Listing 2. The ApplicationServlet class



package test.controller.application;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

/**
* @version 1.0
* @author
*/
public class ApplicationServlet extends HttpServlet {

/**
* @see javax.servlet.GenericServlet#void ()
*/
public void init() throws ServletException {

super.init();
try {
ListValuesLoader listValues = new ListValuesLoader();
listValues.createValidValuesList();
} catch(Exception e){
System.out.println("There is a problem in getting the list values");
}
}

/**
* @see javax.servlet.GenericServlet#void ()
*/
public void destroy() {

super.destroy();

}

}

ApplicationServlet calls the ListValuesLoader class to load all types of list values (Listing 3).

Listing 3. ListValuesLoader class: Load all list types



package test.controller.application;

import java.util.Hashtable;
import java.util.Vector;

import test.controller.validValues.AssetList;
import test.controller.validValues.CustomerLocationList;
import test.controller.validValues.ManufacturerList;
import test.controller.validValues.StatusList;


public class ListValuesLoader {


public ListValuesLoader() {

}

public void createValidValuesList() {

// For Status
loadStatusList();
//For Customer Location
loadCustomerLocationsList();
// For Asset types
loadAssetList();
// For Manufacturer types
loadManufacturerList();

}

/**
* To load SR Stauts list
*/
private void loadStatusList() {
Hashtable obj_Hashtable = new Hashtable();
ListValuesDAO listValuesDAO = new ListValuesDAO();
obj_Hashtable = listValuesDAO.getListValues("STATUS");
StatusList statusList = StatusList.getInstance();
statusList.setOptionsAndValues((Vector)obj_Hashtable.get("OPTION"),
(Vector) obj_Hashtable.get("VALUE"));
}

/**
* To load Customer's Location list
*/
private void loadCustomerLocationsList() {
Hashtable obj_Hashtable = new Hashtable();
ListValuesDAO listValuesDAO = new ListValuesDAO();
obj_Hashtable = listValuesDAO.getListValues("CUSTOMERLOCATIONS");
CustomerLocationList locationList = CustomerLocationList.getInstance();
locationList.setOptionsAndValues((Vector)obj_Hashtable.get("OPTION"),
(Vector) obj_Hashtable.get("VALUE"));
}

/**
* To load Asset list
*/
private void loadAssetList() {
Hashtable obj_Hashtable = new Hashtable();
ListValuesDAO listValuesDAO = new ListValuesDAO();
obj_Hashtable = listValuesDAO.getListValues("ASSETS");
AssetList assetList = AssetList.getInstance();
assetList.setOptionsAndValues((Vector)obj_Hashtable.get("OPTION"),
(Vector) obj_Hashtable.get("VALUE"));
}

/**
* To load Manufacturer list
*/
private void loadManufacturerList() {
Hashtable obj_Hashtable = new Hashtable();
ListValuesDAO listValuesDAO = new ListValuesDAO();
obj_Hashtable = listValuesDAO.getListValues("MANUFACTURER");
ManufacturerList manufacturerList = ManufacturerList.getInstance();
manufacturerList.setOptionsAndValues((Vector)obj_Hashtable.get("OPTION"),
(Vector) obj_Hashtable.get("VALUE"));
}
}

Suppose the application needs the following list types at application start-up time:

  • AssetList
  • CustomerLoactionList
  • ManufacturerList
  • StatusList

So the ListValuesLoader class uses a single different method for each of the list types:

  • loadStatusList() loads the status of the drop-down list.
  • loadCustomerLocationsList() loads customer location data from the drop-down list.
  • loadAssetList() loads asset information from the drop-down list.
  • loadManufacturerList() loads manufacturer information from the drop-down list.

For each list type, the ListValuesLoader calls the ListValuesDAO class to get these values from the database. After getting list values from the database, the ListValuesLoader stores these values in a specific list values class which extends from base ValidValuesTable class.

For simplicity’s sake, I made ListValuesLoader interact with ListValuesDAO class directly by making a direct call to getListValues() method on ListValuesDAO. You can use either service classes or Session Beans to interact with ListValuesDAO. Listing 4 shows the ListValuesDAO class.

Listing 4. ListValuesDAO Class: Get list values from the DB



package test.controller.application;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.Vector;

import javax.sql.DataSource;


public class ListValuesDAO {

/*
* Return the list of values
*/
public Hashtable getListValues(String key1) {
Connection obj_Connection = null;
PreparedStatement obj_PreparedStatement = null;
ResultSet obj_ResultSet = null;

Vector obj_VectorOptions = new Vector();
Vector obj_VectorValues = new Vector();
Hashtable obj_HashListValues = new Hashtable();

try {

obj_Connection = getConnection();

String query =
"SELECT OPTION, VALUE FROM LIST_VALUES_TABLE WHERE KEY1=?";

//Creating the Statement Object from the SQL Query
obj_PreparedStatement = obj_Connection.prepareStatement(query);

obj_PreparedStatement.setString(1, key1);

obj_ResultSet = obj_PreparedStatement.executeQuery();

while (obj_ResultSet.next()) {

obj_VectorOptions.add(obj_ResultSet.getString("OPTION"));

obj_VectorValues.add(obj_ResultSet.getString("VALUE"));
}

obj_HashListValues.put("OPTION", obj_VectorOptions);
obj_HashListValues.put("VALUE", obj_VectorValues);

} catch (SQLException obj_SQLException) {
obj_SQLException.printStackTrace();
} finally {
try {
if (obj_ResultSet != null) {
obj_ResultSet.close();
obj_ResultSet = null;
}
if (obj_PreparedStatement != null) {
obj_PreparedStatement.close();
obj_PreparedStatement = null;
}
if (obj_Connection != null) {
obj_Connection.close();
obj_Connection = null;
}
} catch (SQLException obj_SQLException) {
obj_SQLException.printStackTrace();
}

}

return obj_HashListValues;

}

/**
* To get connection from Database.
*/
public Connection getConnection() {
Connection conn = null;
DataSource dataSource = null;
try {
dataSource = ListValuesUtility.getDatasource();
conn = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}

}

The class ListValuesDAO connects to the database and gets the list values as OPTION and VALUE. In this example, I assume that the list values are stored in a table LIST_VALUES_TABLE with KEY1 as identification for list types.

Now, ListValuesDAO calls the ListValuesUtility class to get the database connection (Listing 5).

Listing 5. ListValuesUtility class: Make the DB connection



package test.controller.application;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;


public class ListValuesUtility {
static DataSource dataSource = null;

/*
* To get the datsource
*/
public static DataSource getDatasource() {
Context ctx = null;
if (dataSource == null){
try {
java.util.Properties props = new java.util.Properties();
String initialContextFactory =
"com.ibm.websphere.naming.WsnInitialContextFactory";
props.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
ctx = new InitialContext(props);
dataSource = (DataSource) ctx.lookup("TESTDB");
} catch (Exception e) {
e.printStackTrace();
}
try {
ctx.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return dataSource;
}

}

The ListValuesUtility class has static data source reference. It creates the data source reference for the first time and uses that same reference for subsequent requests.

Next, look at the ValidValuesTable class, the base class for all specific list values classes (Listing 6).

Listing 6. ValidValuesTable Class: Base class for all specific list values classes



package test.controller.validValues;

import java.util.ArrayList;
import java.util.Vector;

/*
This is the Base class for all valid values; all the specific list
value classes should extend from this class
*/
public class ValidValuesTable {

protected Vector optionsVector = new Vector();
protected Vector valuesVector = new Vector();
protected ArrayList itemsList = new ArrayList();

protected String[] options = null;
protected String[] values = null;

/**
* ValidValuesTable Constructor.
*/
protected ValidValuesTable() {

}

/**
* ValidValuesTable Constructor.
*/
protected ValidValuesTable(String[] options, String[] values) {

setOptionsAndValues(options, values);
}

/**
* ValidValuesTable Constructor.
*/
public ValidValuesTable(Vector options, Vector values) {

setOptionsAndValues(options, values);
}

/**
* Returns the value of options.
* @return java.lang.String[]
*/
public String getOption(String value) {
String option = "";
if (value != null) {
int index = valuesVector.indexOf(value);
if (index != -1) {
option = (String) optionsVector.elementAt(index);
}
}
return option;
}

/**
* Returns the value of options.
* @return java.lang.String[]
*/
public String[] getOptions() {
return options;
}

/**
* Returns a Vector of optionsVector.
* @return java.util.Vector
*/
public Vector getOptionsVector() {
return optionsVector;
}

/**
* Returns the value of value.
* @return java.lang.String
* @param value java.lang.String
*/
public String getValue(String option) {
String value = "";
if (option != null) {
int index = optionsVector.indexOf(option);
if (index != -1) {
value = (String) valuesVector.elementAt(index);
}
}
return value;
}

/**
* Returns the value of values.
* @return java.lang.String[]
*/
public String[] getValues() {
return values;
}

/**
* Returns a Vector of valuesVector.
* @return java.util.Vector
*/
public Vector getValuesVector() {
return valuesVector;
}

/**
* Returns the boolean value.
* @return boolean
* @param option java.lang.String
*/
public boolean isValidOption(String option) {
option = (option != null) ? option.trim() : option;
return optionsVector.contains(option);
}

/**
* Returns the boolean value.
* @return boolean
* @param value java.lang.String
*/
public boolean isValidValue(String value) {
value = (value != null) ? value.trim() : value;
return valuesVector.contains(value);
}

/**
* This method sets both the options and values of this
* class. The options and values must be set at the same time,
* because the internal Vectors are re-initialized using the
* values passed in. If either of the arrays is null, or the
* arrays are not the same size, no update of the class
* will take place.
*
* @param options java.lang.String[]
* @param values java.lang.String[]
*/
public void setOptionsAndValues(String[] options, String[] values) {

if ((options == null) || (values == null)) {
return;
}

if (options.length != values.length) {
return;
}

this.options = options;
this.values = values;

optionsVector.removeAllElements();
valuesVector.removeAllElements();

for (int i = 0; i < options.length; i++) {
optionsVector.addElement(options[i].trim());
valuesVector.addElement(values[i].trim());

//Add items to ArrayList
DropDownItem dropDownItem = new DropDownItem();
dropDownItem.setDropDownDisplayValue(values[i].trim());
dropDownItem.setDropDownIdValue(options[i].trim());
itemsList.add(dropDownItem);
}
}

/**
* This method sets both the options and values of this
* class. The options and values must be set at the same time,
* because the internal Vectors are re-initialized using the
* values passed in. If the Vectors are not the same size,
* or either of them is null, no update of the class will
* take place.
*
* @param optionsVector java.util.Vector
* @param valuesVector java.util.Vector
*/
public void setOptionsAndValues(Vector newOptions, Vector newValues) {

if ((newOptions == null) || (newValues.size() <= 0)) {
return;
}

if (newOptions.size() != newValues.size()) {
return;
}

int num = newOptions.size();
options = new String[num];
values = new String[num];
itemsList = new ArrayList();

optionsVector.removeAllElements();
valuesVector.removeAllElements();

for (int i = 0; i < num; i++) {
String opt = (String) newOptions.elementAt(i);
String val = (String) newValues.elementAt(i);
options[i] = opt;
values[i] = val;
optionsVector.addElement(opt);
valuesVector.addElement(val);

//Add items to ArrayList
DropDownItem dropDownItem = new DropDownItem();
dropDownItem.setDropDownDisplayValue(val);
dropDownItem.setDropDownIdValue(opt);
itemsList.add(dropDownItem);

}
}

/**
* Returns the itemsList.
* @return ArrayList
*/
public ArrayList getItemsList() {
return itemsList;
}

}

All specific list values classes should extend from ValidValuesTable. The reference to list values is stored inside sub-classes.

Now, look at the

Each of these is important because each implements a singleton pattern and the class ListValuesLoader gets/creates the object of the mentioned class. The single instance of mentioned class holds the reference for drop-down values of that class. The code to display the class’s drop down uses the same single instance of that class (for example, AssetList or StatusList) created by the ListValuesLoader class to load the drop-down values.

Listing 7. AssetList class



package test.controller.validValues;

/**
* The AssetList class contains the valid options and values for the Assets.
*/
public class AssetList extends ValidValuesTable {

private static AssetList table = null;

private AssetList() {

}

public static AssetList getInstance() {
if (table == null) {
table = new AssetList();
}
return table;
}
}

Listing 8. CustomerLocationList class



package test.controller.validValues;

/**
* The CustomerLocationList class contains the valid options
* and values for customer locations
*/
public class CustomerLocationList extends ValidValuesTable {

private static CustomerLocationList table = null;

private CustomerLocationList() {

}

public static CustomerLocationList getInstance() {
if (table == null) {
table = new CustomerLocationList();
}
return table;
}
}

Listing 9. ManufacturerList class



package test.controller.validValues;


/**
* The ManufacturerList class contains the valid options
* and values for the Manufacturers.
*/
public class ManufacturerList extends ValidValuesTable {

private static ManufacturerList table = null;

private ManufacturerList() {

}

public static ManufacturerList getInstance() {
if (table == null) {
table = new ManufacturerList();
}
return table;
}
}

Listing 10. StatusList class



package test.controller.validValues;


/**
* The StatusList class contains the valid options
* and values for the Status.
*/
public class StatusList extends ValidValuesTable {

private static StatusList table = null;

private StatusList() {

}

public static StatusList getInstance() {
if (table == null) {
table = new StatusList();
}
return table;
}
}

The class DropDownItem holds option and value as one item. The class ValidValuesTable creates a list of DropDownItem objects.

Listing 11. DropDownItem class



package test.controller.validValues;
public class DropDownItem {

        //For Drop down Display Values.
        private String dropDownDisplayValue = null;

        //For Drop down Id Values.
        private String dropDownIdValue = null;


        /**
         * Returns the dropDownDisplayValue.
         * @return String
         */
        public String getDropDownDisplayValue() {
                return dropDownDisplayValue;
        }

        /**
         * Returns the dropDownIdValue.
         * @return String
         */
        public String getDropDownIdValue() {
                return dropDownIdValue;
        }

        /**
         * Sets the dropDownDisplayValue.
         * @param dropDownDisplayValue The dropDownDisplayValue to set
         */
        public void setDropDownDisplayValue(String dropDownDisplayValue) {
                this.dropDownDisplayValue = dropDownDisplayValue;
        }

        /**
         * Sets the dropDownIdValue.
         * @param dropDownIdValue The dropDownIdValue to set
         */
        public void setDropDownIdValue(String dropDownIdValue) {
                this.dropDownIdValue = dropDownIdValue;
        }

}

Finally, Listing 12 demonstrates how to use the drop-down lists in JSP.

Listing 12. How to use drop-down lists in JSP



<%@ page import="test.controller.validValues.AssetList"%>
<%@ page import="test.controller.validValues.CustomerLocationList"%>
<%@ page import="test.controller.validValues.ManufacturerList"%>
<%@ page import="test.controller.validValues.StatusList"%>

<%

String[] asset_list_option= null;
String[] asset_list_value= null;
String[] customerLoaction_list_option=null;
String[] customerLoaction_list_value=null;
String[] manufacturer_list_option= null;
String[] manufacturer_list_value= null;
String[] status_list_option=null;
String[] status_list_value=null;

asset _list_option = AssetList.getInstance().getOptions();
asset _list_value = AssetList.getInstance().getValues();
customerLoaction _list_option = CustomerLocationList.getInstance().getOptions();
customerLoaction _list_value = CustomerLocationList.getInstance().getValues();
manufacturer _list_option = ManufacturerList.getInstance().getOptions();
manufacturer _list_value = ManufacturerList.getInstance().getValues();
status_list_option = StatusList.getInstance().getOptions();
status_list_value = StatusList.getInstance().getValues();

%>

// To create list box
<html:select property="status" multiple="true" size="3" styleId="status">
<html:option value=""></html:option>
<%

if (status_list_option != null) {
for(int rows=0;rows<status_list_option.length;rows++) {
%>
<html:option value="<%= status_list_value[rows] %>">
<%=status_list_option[rows] %>
</html:option>
<%} }%>
</html:select>

In conclusion

In this article, you learned how to load common shared drop-down list items at the start of your Web application and how to use these drop-down lists for all users of the application. If you implement the quick and easy approach I’ve described, you can make your Web application load drop-down list items just once for the duration of the application’s runtime. With the subsequent decrease in database hits, you reduce network overhead and make your Web application run more efficiently.

Resources

  • Look at the database, view, and form properties that most commonly affect how well your applications perform in Application Performance Tuning, two-part series(developerWorks, April 2003).
  • For DB2 UDB application developers or database administrators, dig into DB2 UDB/WebSphere Performance Tuning Guide and learn to tune a DB2 UDB/WebSphere Application Server environment (IBM Redbook, March 2003).
  • Get the details of an analytics process that lets you rapidly find the cause of performance problems and develop remedial actions and tuning suggestions in Top 10 performance tips (developerWorks, March 2004).
  • In the three-part series, Using DB2 Information Integrator for J2EE Development, discover how to use DB2 Information Integrator in a J2EE environment to access disparate back-end data sources (developerWorks, May 2003).
  • Browse the servlets page for a detailed web.xml structure.
  • Peruse the Developers Bookstore for many more helpful titles specific to Web Architecture.
  • Visit the developerWorks Web Architecture zone. It specializes in articles covering various Web-based solutions.
  • Get involved in the developerWorks community by participating in developerWorks blogs.
  • 2010-05-26T09:46:54+00:00 June 22nd, 2005|Java|0 Comments

    About the Author:

    Srinivasa Rao Karanam has worked with IBM Global Services for one year, and has five years of experience in J2EE-related technologies. Currently, he is working on BizPortlets, sample portlets developed for the WebSphere Portal Server. He can be reached at srkarana@in.ibm.com.

    Leave A Comment