All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.moparisthebest.jdbc.CachingQueryMapper Maven / Gradle / Ivy

The newest version!
package com.moparisthebest.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

import static com.moparisthebest.jdbc.TryClose.tryClose;

/**
 * This class caches the PreparedStatement's it creates for the strings you send in, then closes them when the close() method is called.
 * Since PreparedStatement is not thread-safe, this class cannot be either.  Be sure to call it from only a single thread
 * or synchronize around it.
 */
public class CachingQueryMapper extends QueryMapper {

	protected final Map cache;

	protected CachingQueryMapper(Connection conn, String jndiName, ResultSetMapper cm, final int maxEntries) {
		super(conn, jndiName, cm);
		if (maxEntries > 0) { // we want a limited cache
			final float loadFactor = 0.75f; // default for HashMaps
			// if we set the initialCapacity this way, nothing should ever need re-sized
			final int initialCapacity = ((int) Math.ceil(maxEntries / loadFactor)) + 1;
			cache = new LinkedHashMap(initialCapacity, loadFactor, true) {
				@Override
				protected boolean removeEldestEntry(Map.Entry eldest) {
					final boolean remove = size() > maxEntries;
					if(remove){
						//System.out.printf("closing PreparedStatement '%s' with key '%s'\n", eldest.getValue(), eldest.getKey());
						tryClose(eldest.getValue());
					}
					return remove;
				}
			};
		} else
			cache = new HashMap();
	}

	public CachingQueryMapper(Connection conn, ResultSetMapper cm, final int maxEntries) {
		this(conn, null, cm, maxEntries);
	}

	public CachingQueryMapper(Connection conn, final int maxEntries) {
		this(conn, null, null, maxEntries);
	}

	public CachingQueryMapper(String jndiName, ResultSetMapper cm, final int maxEntries) {
		this(null, jndiName, cm, maxEntries);
	}

	public CachingQueryMapper(String jndiName, final int maxEntries) {
		this(null, jndiName, null, maxEntries);
	}

	protected CachingQueryMapper(Connection conn, String jndiName, ResultSetMapper cm) {
		this(conn, jndiName, cm, 20); // default size of 20
	}

	public CachingQueryMapper(Connection conn, ResultSetMapper cm) {
		this(conn, null, cm);
	}

	public CachingQueryMapper(Connection conn) {
		this(conn, null, null);
	}

	public CachingQueryMapper(String jndiName, ResultSetMapper cm) {
		this(null, jndiName, cm);
	}

	public CachingQueryMapper(String jndiName) {
		this(null, jndiName, null);
	}

	protected PreparedStatement getPreparedStatement(String sql) throws SQLException {
		return getPreparedStatement(sql, ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
	}
	
	protected PreparedStatement getPreparedStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
		PreparedStatement ps = cache.get(sql);
		if (ps == null) {
			//System.out.println("cache miss");
			ps = conn.prepareStatement(sql,resultSetType,resultSetConcurrency);
			cache.put(sql, ps);
		}
		//else System.out.println("cache hit");
		return ps;
	}

	public void clearCache(boolean close) {
		//System.out.println("cache size: "+cache.size());
		for (PreparedStatement ps : cache.values())
			tryClose(ps);
		if (close)
			super.close();
		else
			cache.clear();
	}

	public void clearCache() {
		this.clearCache(false);
	}

	@Override
	public void close() {
		this.clearCache(true);
	}

	@Override
	public int executeUpdate(String sql, Object... bindObjects) throws SQLException {
		return super.executeUpdate(getPreparedStatement(sql), bindObjects);
	}

	@Override
	public boolean executeUpdateSuccess(String sql, Object... bindObjects) throws SQLException {
		return super.executeUpdateSuccess(getPreparedStatement(sql), bindObjects);
	}

	// these grab ResultSets from the database

	@Override
	public ResultSet toResultSet(String sql, Object... bindObjects) throws SQLException {
		return super.toResultSet(getPreparedStatement(sql), bindObjects);
	}
	
	@Override
	public ResultSet toResultSet(String sql, Integer rsType, Integer rsConcurrency, Object... bindObjects) throws SQLException {
		return super.toResultSet(getPreparedStatement(sql,rsType,rsConcurrency), bindObjects);
	}
	
	// DO NOT EDIT BELOW THIS LINE, OR CHANGE THIS COMMENT, CODE AUTOMATICALLY GENERATED BY genQueryMapper.sh

	@Override
	public  T toObject(String sql, Class componentType, final Object... bindObjects) throws SQLException {
		return super.toObject(getPreparedStatement(sql), componentType, bindObjects);
	}

	@Override
	public , V> Map toSingleMap(String sql, Class componentType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toSingleMap(getPreparedStatement(sql), componentType, mapValType, bindObjects);
	}

	@Override
	public  Map toSingleMap(String sql, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toSingleMap(getPreparedStatement(sql), mapValType, bindObjects);
	}

	@Override
	public , E> T toCollection(String sql, final Class collectionType, Class componentType, final Object... bindObjects) throws SQLException {
		return super.toCollection(getPreparedStatement(sql), collectionType, componentType, bindObjects);
	}

	@Override
	public , E> T toCollection(String sql, T list, Class componentType, final Object... bindObjects) throws SQLException {
		return super.toCollection(getPreparedStatement(sql), list, componentType, bindObjects);
	}

	@Override
	public , K, E> T toMap(String sql, final Class returnType, Class mapKeyType, Class componentType, final Object... bindObjects) throws SQLException {
		return super.toMap(getPreparedStatement(sql), returnType, mapKeyType, componentType, bindObjects);
	}

	@Override
	public , K, E> T toMap(String sql, T map, Class mapKeyType, Class componentType, final Object... bindObjects) throws SQLException {
		return super.toMap(getPreparedStatement(sql), map, mapKeyType, componentType, bindObjects);
	}

	@Override
	public , K, E extends Collection, C> T toMapCollection(String sql, final Class returnType, Class mapKeyType, Class collectionType, Class componentType, final Object... bindObjects) throws SQLException {
		return super.toMapCollection(getPreparedStatement(sql), returnType, mapKeyType, collectionType, componentType, bindObjects);
	}

	@Override
	public , K, E extends Collection, C> T toMapCollection(String sql, T map, Class mapKeyType, Class collectionType, Class componentType, final Object... bindObjects) throws SQLException {
		return super.toMapCollection(getPreparedStatement(sql), map, mapKeyType, collectionType, componentType, bindObjects);
	}

	@Override
	public  ListIterator toListIterator(String sql, final Class type, final Object... bindObjects) throws SQLException {
		return super.toListIterator(getPreparedStatement(sql), type, bindObjects);
	}

	@Override
	public  Iterator toIterator(String sql, final Class type, final Object... bindObjects) throws SQLException {
		return super.toIterator(getPreparedStatement(sql), type, bindObjects);
	}

	@Override
	public  T[] toArray(String sql, final Class type, final Object... bindObjects) throws SQLException {
		return super.toArray(getPreparedStatement(sql), type, bindObjects);
	}

	@Override
	public  List toList(String sql, Class componentType, final Object... bindObjects) throws SQLException {
		return super.toList(getPreparedStatement(sql), componentType, bindObjects);
	}

	@Override
	public  Map toMap(String sql, Class mapKeyType, Class componentType, final Object... bindObjects) throws SQLException {
		return super.toMap(getPreparedStatement(sql), mapKeyType, componentType, bindObjects);
	}

	@Override
	public , C> Map toMapList(String sql, Class mapKeyType, Class componentType, final Object... bindObjects) throws SQLException {
		return super.toMapList(getPreparedStatement(sql), mapKeyType, componentType, bindObjects);
	}

	@Override
	public , E extends Map, V> T toCollectionMap(String sql, final Class collectionType, Class componentType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toCollectionMap(getPreparedStatement(sql), collectionType, componentType, mapValType, bindObjects);
	}

	@Override
	public , E extends Map, V> T toCollectionMap(String sql, T list, Class componentType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toCollectionMap(getPreparedStatement(sql), list, componentType, mapValType, bindObjects);
	}

	@Override
	public , K, E extends Map, V> T toMapMap(String sql, final Class returnType, Class mapKeyType, Class componentType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toMapMap(getPreparedStatement(sql), returnType, mapKeyType, componentType, mapValType, bindObjects);
	}

	@Override
	public , K, E extends Map, V> T toMapMap(String sql, T map, Class mapKeyType, Class componentType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toMapMap(getPreparedStatement(sql), map, mapKeyType, componentType, mapValType, bindObjects);
	}

	@Override
	public , K, C extends Collection, E extends Map, V> T toMapCollectionMap(String sql, final Class returnType, Class mapKeyType, Class collectionType, Class componentType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toMapCollectionMap(getPreparedStatement(sql), returnType, mapKeyType, collectionType, componentType, mapValType, bindObjects);
	}

	@Override
	public , K, C extends Collection, E extends Map, V> T toMapCollectionMap(String sql, T map, Class mapKeyType, Class collectionType, Class componentType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toMapCollectionMap(getPreparedStatement(sql), map, mapKeyType, collectionType, componentType, mapValType, bindObjects);
	}

	@Override
	public , V> ListIterator> toListIteratorMap(String sql, final Class type, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toListIteratorMap(getPreparedStatement(sql), type, mapValType, bindObjects);
	}

	@Override
	public , V> Iterator> toIteratorMap(String sql, final Class type, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toIteratorMap(getPreparedStatement(sql), type, mapValType, bindObjects);
	}

	@Override
	public , V> Map[] toArrayMap(String sql, final Class type, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toArrayMap(getPreparedStatement(sql), type, mapValType, bindObjects);
	}

	@Override
	public , V> List> toListMap(String sql, Class componentType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toListMap(getPreparedStatement(sql), componentType, mapValType, bindObjects);
	}

	@Override
	public , V> Map> toMapMap(String sql, Class mapKeyType, Class componentType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toMapMap(getPreparedStatement(sql), mapKeyType, componentType, mapValType, bindObjects);
	}

	@Override
	public , V> Map>> toMapListMap(String sql, Class mapKeyType, Class componentType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toMapListMap(getPreparedStatement(sql), mapKeyType, componentType, mapValType, bindObjects);
	}

	@Override
	public  ListIterator> toListIteratorMap(String sql, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toListIteratorMap(getPreparedStatement(sql), mapValType, bindObjects);
	}

	@Override
	public  Iterator> toIteratorMap(String sql, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toIteratorMap(getPreparedStatement(sql), mapValType, bindObjects);
	}

	@Override
	public  List> toListMap(String sql, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toListMap(getPreparedStatement(sql), mapValType, bindObjects);
	}

	@Override
	public  Map> toMapMap(String sql, Class mapKeyType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toMapMap(getPreparedStatement(sql), mapKeyType, mapValType, bindObjects);
	}

	@Override
	public  Map>> toMapListMap(String sql, Class mapKeyType, Class mapValType, final Object... bindObjects) throws SQLException {
		return super.toMapListMap(getPreparedStatement(sql), mapKeyType, mapValType, bindObjects);
	}

}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy