PRODUCTS AND SERVICES INDUSTRIES SUPPORT PARTNERS COMMUNITIES ABOUT
  Coherence 3.1 User Guide
  Sample CacheStore
Added by Mark Falco, last edited by Mark Falco on Feb 14, 2006  (view change)

Labels

 
(None)

Sample CacheStore

This page provides a simple implementation of the com.tangosol.net.cache.CacheStore interface. Cache stores are used by caches to read and write cache entries to external stores such as a database. This example uses JDBC to perform these tasks. See the cache configuration samples, for an example of a database cache configuration.

package com.tangosol.examples.coherence;


import com.tangosol.net.cache.CacheStore;
import com.tangosol.util.Base;

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;


/**
* An example implementation of CacheStore
* interface.
*
* @author erm 2003.05.01
*/
public class DBCacheStore
        extends Base
        implements CacheStore
    {
    // ----- constructors ---------------------------------------------------
    /**
    * Constructs DBCacheStore for a given database table.
    *
    * @param sTableName the db table name
    */
    public DBCacheStore(String sTableName)
        {
        m_sTableName = sTableName;
        configureConnection();
        }

	/** 
	* Set up the DB connection.
	*/
	protected void configureConnection()
		{
		try
			{
			Class.forName("org.gjt.mm.mysql.Driver");
			m_con = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);
			m_con.setAutoCommit(true);
			}
		catch (Exception e)
			{
			throw ensureRuntimeException(e, "Connection failed");
			}
		}


	// ---- accessors -------------------------------------------------------

    /** 
    * Obtain the name of the table this CacheStore is persisting to.
    * 
    * @return the name of the table this CacheStore is persisting to
    */
    public String getTableName()
        {
        return m_sTableName;
        }

    /** 
    * Obtain the connection being used to connect to the database.
    * 
    * @return the connection used to connect to the database
    */
    public Connection getConnection()
        {
        return m_con;
        }


    // ----- CacheStore Interface --------------------------------------------

    /**
    * Return the value associated with the specified key, or null if the
    * key does not have an associated value in the underlying store.
    *
    * @param oKey  key whose associated value is to be returned
    *
    * @return the value associated with the specified key, or
    *         <tt>null</tt> if no value is available for that key
    */
    public Object load(Object oKey)
        {
        Object     oValue = null;
        Connection con    = getConnection();
        String     sSQL   = "SELECT id, value FROM " + getTableName()
                          + " WHERE id = ?";
        try
            {
            PreparedStatement stmt = con.prepareStatement(sSQL);

            stmt.setString(1, String.valueOf(oKey));

            ResultSet rslt = stmt.executeQuery();
            if (rslt.next())
                {
                oValue = rslt.getString(2);
                if (rslt.next())
                    {
                    throw new SQLException("Not a unique key: " + oKey);
                    }
                }
            stmt.close();
            }
        catch (SQLException e)
            {
            throw ensureRuntimeException(e, "Load failed: key=" + oKey);
            }
        return oValue;
        }

    /**
    * Store the specified value under the specific key in the underlying
    * store. This method is intended to support both key/value creation
    * and value update for a specific key.
    *
    * @param oKey    key to store the value under
    * @param oValue  value to be stored
    *
    * @throws UnsupportedOperationException  if this implementation or the
    *         underlying store is read-only
    */
    public void store(Object oKey, Object oValue)
        {
        Connection con     = getConnection();
        String     sTable  = getTableName();
	String     sSQL;
        
        // the following is very inefficient; it is recommended to use DB
        // specific functionality i.e. REPLACE for MySQL or MERGE for Oracle
	if (load(oKey) != null)
		{
		// key exists - update
		sSQL = "UPDATE " + sTable + " SET value = ? where id = ?";
		}
	else
		{
		// new key - insert
		sSQL = "INSERT INTO " + sTable + " (value, id) VALUES (?,?)";
		}
	try
		{
		PreparedStatement stmt = con.prepareStatement(sSQL);
		int i = 0;
		stmt.setString(++i, String.valueOf(oValue));
		stmt.setString(++i, String.valueOf(oKey));
		stmt.executeUpdate();
		stmt.close();
		}
	catch (SQLException e)
		{
		throw ensureRuntimeException(e, "Store failed: key=" + oKey);
		}
        }

    /**
    * Remove the specified key from the underlying store if present.
    *
    * @param oKey key whose mapping is to be removed from the map
    *
    * @throws UnsupportedOperationException  if this implementation or the
    *         underlying store is read-only
    */
    public void erase(Object oKey)
        {
        Connection con  = getConnection();
        String     sSQL = "DELETE FROM " + getTableName() + " WHERE id=?";
        try
            {
            PreparedStatement stmt = con.prepareStatement(sSQL);

            stmt.setString(1, String.valueOf(oKey));
            stmt.executeUpdate();
            stmt.close();
            }
        catch (SQLException e)
            {
            throw ensureRuntimeException(e, "Erase failed: key=" + oKey);
            }
        }

	/**
	* Remove the specified keys from the underlying store if present.
	*
	* @param colKeys  keys whose mappings are being removed from the cache
	*
	* @throws UnsupportedOperationException  if this implementation or the
	*         underlying store is read-only
	*/
	public void eraseAll(Collection colKeys)
		{
		throw new UnsupportedOperationException();
		}

	/**
	* Return the values associated with each the specified keys in the
	* passed collection. If a key does not have an associated value in
	* the underlying store, then the return map will not have an entry
	* for that key.
	*
	* @param colKeys  a collection of keys to load
	*
	* @return a Map of keys to associated values for the specified keys
	*/
	public Map loadAll(Collection colKeys)
		{
		throw new UnsupportedOperationException();
		}

	/**
	* Store the specified values under the specified keys in the underlying
	* store. This method is intended to support both key/value creation
	* and value update for the specified keys.
	*
	* @param mapEntries   a Map of any number of keys and values to store
	*
	* @throws UnsupportedOperationException  if this implementation or the
	*         underlying store is read-only
	*/
	public void storeAll(Map mapEntries)
		{
		throw new UnsupportedOperationException();
		}

    /**
    * Iterate all keys in the underlying store.
    *
    * @return a read-only iterator of the keys in the underlying store
    */
    public Iterator keys()
        {
        Connection con  = getConnection();
        String     sSQL = "SELECT id FROM " + getTableName();
        List       list = new LinkedList();
        
        try
            {
            PreparedStatement stmt = con.prepareStatement(sSQL);
            ResultSet         rslt = stmt.executeQuery();
            while (rslt.next())
                {
                Object oKey = rslt.getString(1);
                list.add(oKey);
                }
            stmt.close();
            }
        catch (SQLException e)
            {
            throw ensureRuntimeException(e, "Iterator failed");
            }

        return list.iterator();
        }

    
    // ----- data members ---------------------------------------------------

    /**
    * The connection.
    */
    protected Connection m_con;

    /**
    * The db table name.
    */
    protected String m_sTableName;

	/**
	* Driver class name.
	*/
	private static final String DB_DRIVER   = "org.gjt.mm.mysql.Driver";

	/**
	* Connection URL.
	*/
	private static final String DB_URL      = "jdbc:mysql://localhost:3306/CacheStore";

	/**
	* User name.
	*/
	private static final String DB_USERNAME = "root";

	/**
	* Password.
	*/
	private static final String DB_PASSWORD = null;
    }