Description

Usually in software devellopement we use values liste that we take from “properties”, SQL tables or in the worst case, “in hard codding” in our application.

As many people I had this problem ans I solve it by creating “Tables Memories”. It permits me to limit the access to the database (or file), to low the occupation memory by having just one request of these memories liste, and to simplify my code.

This code is quite old and could be improved (use of the patern singleton instead of a full static classe, synchronize optimisation…). I use this in a huge number of project and I always report these modifications because I don’t have any performance or memories problems.

Fonctions

During the cration of this componant I wanted to have the following functions also I simplify in maximum its use in a JSP page or a Servtel :

  • “Connection” sql connection outside bean
  • Do not reload the data if they are already in memory
  • Load of a liste from a select SQL : loadQuery(…)
  • Load of a list from a values liste : loadListe(…)
  • Read of the description associated to a code (String) : getValue(…)
  • Read of the description associated to a code (Combobox) : getListe(…)
  • Read of the description associated to a code (Radio Bouton) : getRadio(…)

Download

memorytable.zip

Use

This little sample of a code (jsp) show how to do the load (initialisation) of the “Memory Table”.

<%@ page language="java" import="com.berthou.sql.*"%>
<%
java.sql.Connection conn = .... ; // Initialize you connection
 
// Load a hard coded liste
MemoryTable.loadListe("TEST_L_ETAT","    = ;V=Valide;E=En erreur;I=Incomplete;" ) ;
 
// Load a SQL Query liste
// Research of the service code and of the description of the actifs service.
String sql = "select cdserv, libelle from service where status = 'O' " ;
MemoryTable.loadQuery(conn, "TBL_SERV",sql ) ;
%>

When this load has been made you can use at once the “memory tables”

<%@ page language="java" import="com.berthou.sql.*"%>
....
<% String service = "1305" ; %>
Service : <%=service%> - <%=MemoryTable.getValue("TBL_SERV", service)%>
(affiche Service : 1305 - Libelle du service1305)
 
Service :
<select name="service"><%=MemoryTable.getListe("TBL_SERV", service)%></select>
(build a combobox by activating the asked service)

The MemoryTable class

package com.berthou.sql;
 
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;
 
import org.apache.log4j.Logger;
 
/**
 * @author rberthou
 *
 * Creating 3 févr. 2001
 * Package  com.berthou.sql
 * Projet   tools
 * -------+------------+-------------------------------------------------------------------------
 *   Ver  | Date       | Comments
 * -------+------------+-------------------------------------------------------------------------
 *  2.00  | 04/04/2006 | List's add and radio button (+ comments)
 *  1.00  | 03/02/2001 | Creation
 * -------+------------+-------------------------------------------------------------------------
 */
public class MemoryTable {
 
	private static final Logger logger = Logger.getLogger(MemoryTable.class);
 
	static protected Hashtable h = new Hashtable(10, 1);
 
	/**
	 * Reload of the data of a guery
	 *
	 * @param Connection
	 *            conn : used connection
	 * @param String
	 *            tableName : Name of the Query
	 * @param String
	 *            Sql : Ordre SQL à executer
	 * @param boolean
	 *            tr : true if trim colonne code
	 *
	 * @return int rc : nombre d'enregistrements chargés
	 */
	static public synchronized int reloadQuery(Connection conn,
			String tableName, String sql, boolean tr) throws SQLException {
		/* Si la table est déja chargé on la recharge */
		freeTable(tableName);
 
		return loadQuery(conn, tableName, sql, tr);
	}
 
	/**
	 * rechargement des données d'un query
	 *
	 * @param Connection
	 *            conn : Connexion utilisée
	 * @param String
	 *            tableName : Nom du Query
	 * @param String
	 *            Sql : Ordre SQL à executer
	 *
	 * @return int rc : nombre d'enregistrements chargés
	 */
	static public synchronized int reloadQuery(Connection conn,
			String tableName, String sql) throws SQLException {
		return reloadQuery(conn, tableName, sql, false);
	}
 
	/**
	 * chargement des données d'une table
	 *
	 * @param Connection
	 *            conn : Connexion utilisée
	 * @param String
	 *            tableName : Nom du Query
	 * @param String
	 *            Sql : Ordre SQL à executer
	 *
	 * @return int rc : nombre d'enregistrements chargés
	 */
	static public synchronized int loadQuery(Connection conn, String queryName,
			String sql) throws SQLException {
		return loadQuery(conn, queryName, sql, false);
	}
 
	/**
	 * chargement des données d'une table
	 *
	 * @param Connection
	 *            conn : Connexion utilisée
	 * @param String
	 *            tableName : Nom du Query
	 * @param String
	 *            Sql : Ordre SQL à executer
	 * @param boolean
	 *            isTrim : Vrai si colonne code a trim
	 *
	 * @return int rc : nombre d'enregistrements chargés
	 */
	static public synchronized int loadQuery(Connection conn, String queryName,
			String sql, boolean isTrim) throws SQLException {
		if (isLoaded(queryName))
			return ((Vector) h.get(queryName)).size();
 
		int rc = 0;
		Vector v = new Vector(10, 5);
 
		try {
			Statement stmt = conn.createStatement();
 
			/* Execution */
			ResultSet rs = stmt.executeQuery(sql);
			if (rs != null) {
				ResultSetMetaData rsdt = rs.getMetaData();
				/* Si utile recherche de la liste des colonnes */
				int K = rsdt.getColumnCount();
				/* Lecture des données et mémorisation dans un Vecteur */
				while (rs.next()) {
					String[] s = new String[K];
					for (int I = 0; I < K; I++) {
						if (I == 0 && isTrim)
							s[I] = rs.getString(I+1).trim();
						else
							s[I] = rs.getString(I+1);
					}
					rc++;
					v.add(s);
				}
				/* Ajout de ce Vecteur dans la HashTable */
				h.put(queryName, v);
				rs.close();
			}
			stmt.close();
		} catch (SQLException e) {
			logger
					.error("unable to fetch table [" + queryName + "] err : "
							+ e);
			throw e;
		} finally {
 
		}
 
		if (rc > 0)
			logger.info("Chargement de la table/query [" + queryName + "] : "
					+ rc);
 
		return rc;
	}
 
	/**
	 * rechargement des données d'une liste
	 *
	 * @param String
	 *            tableName : Nom de la liste
	 * @param String
	 *            valeurs : liste des valeurs
	 *
	 * @return int rc : nombre d'enregistrements chargés
	 */
	static public synchronized int reloadListe(String tableName, String sql) {
		/* Si la table est déja chargé on la recharge */
		freeTable(tableName);
 
		return loadListe(tableName, sql);
	}
 
	/**
	 * rechargement des données d'une liste
	 *
	 * @param String
	 *            tableName : Nom de la liste
	 * @param String
	 *            valeurs : liste des valeurs
	 *
	 * @return int rc : nombre d'enregistrements chargés
	 */
	static public synchronized int loadListe(String tableName, String sql) {
		if (isLoaded(tableName))
			return ((Vector) h.get(tableName)).size();
 
		int rc = 0;
		Vector v = new Vector(5, 2);
		StringTokenizer stoken = new StringTokenizer(sql, ";");
 
		/* Lecture des données et mémorisation dans un Vecteur */
		while (stoken.hasMoreElements()) {
			String[] s = new String[2];
			String token = stoken.nextToken();
			int i = token.indexOf('=');
			s[0] = token.substring(0, i); // cle
			s[1] = token.substring(i + 1); // valeur
			rc++;
			v.add(s);
		}
		/* Ajout de ce Vecteur dans la HashTable */
		h.put(tableName, v);
 
		if (rc > 0)
			logger.info("Chargement de la table/liste [" + tableName + "] : "
					+ rc);
 
		return rc;
	}
 
	/**
	 * Nombre de tables chargées
	 *
	 * @return int r : nombre de table
	 */
	static public synchronized int size() {
		return h.size();
	}
 
	/**
	 * Test si une table est chargée
	 *
	 * @param String
	 *            tableName : Nom de la table
	 *
	 * @return boolean b : oui ou non...
	 */
	static public synchronized boolean isLoaded(String tableName) {
		return h.containsKey(tableName);
	}
 
	/**
	 * libération d'une table
	 *
	 * @param String
	 *            tableName : Nom de la table
	 */
	static public synchronized void freeTable(String tableName) {
		if (h.containsKey(tableName))
			h.remove(tableName);
	}
 
	/**
	 * Lecture des données d'une table
	 *
	 * @param String
	 *            tableName : Nom de la table
	 *
	 * @return Vector v : les données
	 */
	static public synchronized Vector getTable(String tableName)
			throws SQLException {
		return (Vector) h.get(tableName);
	}
 
	/**
	 * Formatage des données d'une table sous forme d'une combobox
	 *
	 * @param String
	 *            tableName : Nom de la table
	 * @param String
	 *            val : Valeur selectionnée
	 *
	 * @return String s : les données (format : &lt;option ... )
	 */
	static public synchronized String getListe(String tableName, String val)
			throws SQLException {
		StringBuffer sb = new StringBuffer("");
		Vector v = getTable(tableName);
 
		if (v != null) {
			int K = v.size();
			String[] s;
			for (int I = 0; I < K; I++) {
				s = (String[]) v.elementAt(I);
				if (s.length > 1) {
					if (s[0].equals(val))
						sb.append("<option value=\"" + s[0] + "\" selected>"
								+ s[1] + "</option>\r\n");
					else
						sb.append("<option value=\"" + s[0] + "\">" + s[1]
								+ "</option>\r\n");
				}
			}
		}
 
		return sb.toString();
	}
 
	/**
	 * Formatage des données d'une table sous forme de radio boutons
	 *
	 * @param String :
	 *            Nom de la zone HTML (name = )
	 * @param String
	 *            tableName : Nom de la table
	 * @param String
	 *            val : Valeur selectionnée
	 * @param String
	 *            after : Le code html a ajouter apres chaque ligne
	 *            (&lt;br/&gt;)
	 *
	 * @return String s : les données (format : &lt;option ... )
	 */
	static public synchronized String getRadio(String nm, String tableName,
			String val, String after) throws SQLException {
		StringBuffer sb = new StringBuffer("");
		Vector v = getTable(tableName);
 
		if (after == null)
			after = "\r\n";
 
		if (v != null) {
			int K = v.size();
			String[] s;
			for (int I = 0; I < K; I++) {
				s = (String[]) v.elementAt(I);
				if (s.length > 1) {
					sb.append("<input type=\"RADIO\" name=\"" + nm + "\" id=\""
							+ nm + "\" value=\"" + s[0] + "\"");
					if (s[0].equals(val))
						sb.append(" checked");
					sb.append(">" + s[1] + "</input>" + after);
				}
			}
		}
 
		return sb.toString();
	}
 
	/**
	 * Lecture d'une valeur
	 *
	 * @param String
	 *            tableName : Nom de la table
	 * @param String
	 *            val : Valeur selectionnée
	 *
	 * @return String s : le libelle
	 */
	static public synchronized String getValue(String tableName, String val) throws SQLException {
		String r = "";
		Vector v = getTable(tableName);
 
		if (v != null) {
			int K = v.size();
			String[] s;
			for (int I = 0; I < K; I++) {
				s = (String[]) v.elementAt(I);
				if (s.length > 1) {
					if (s[0].equals(val)) {
						r = s[1];
						break;
					}
				}
			}
		}
 
		return r;
	}
}
Be Sociable, Share!