/**
*
* Copyright 2014 The Darks ORM Project (Liu lihua)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package darks.orm.datasource.factory;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import darks.orm.core.config.DataSourceConfiguration;
import darks.orm.core.config.ResultSetConfig;
import darks.orm.datasource.ProxyConnection;
import darks.orm.datasource.ProxyPrepareStatement;
import darks.orm.log.Logger;
import darks.orm.log.LoggerFactory;
/**
*
*
* <p>
* <h1>StatementFactory.java</h1>
* <p>
*
* @author Liu LiHua
* @version 1.0.0 v05/03/2012
* @since JDK1.5
*/
public class StatementFactory
{
private static final Logger logger = LoggerFactory.getLogger(StatementFactory.class);
private ConcurrentMap<String, PreparedStatement> mapPS = new ConcurrentHashMap<String, PreparedStatement>();
private ConcurrentMap<String, CallableStatement> mapCS = new ConcurrentHashMap<String, CallableStatement>();
public enum StatementType
{
Normal, Scorllable, GenerateKey
}
public void removePreparedStatement(String sql)
{
mapPS.remove(sql);
}
public void removeCallableStatement(String sql)
{
mapCS.remove(sql);
}
public CallableStatement getCallableStatement(ProxyConnection conn, String sql)
throws SQLException
{
DataSourceConfiguration config = ConnectionFactory.getInstance().getCurrentDataSourceConfig();
CallableStatement cstmt = null;
cstmt = mapCS.get(sql);
if (cstmt != null)
{
if (cstmt.isClosed())
{
mapCS.remove(sql);
cstmt = conn.prepareCall(sql);
mapCS.put(sql, cstmt);
}
}
else
{
cstmt = conn.prepareCall(sql);
mapCS.put(sql, cstmt);
}
if (cstmt != null)
{
cstmt.clearParameters();
cstmt.setFetchSize(config.getFetchSize());
}
return cstmt;
}
/**
* �������PrepareStatement
*
* @param sql SQL���
* @param conn ���ݿ�����
* @param stateType PrepareStatement����
* @return PrepareStatement
* @throws Exception
*/
public PreparedStatement getPrepareStatement(String sql, ProxyConnection conn, StatementType stateType)
throws SQLException
{
DataSourceConfiguration config = ConnectionFactory.getInstance().getCurrentDataSourceConfig();
PreparedStatement pstmt = null;
if (stateType == StatementType.Scorllable)
{
try
{
pstmt = getPrepareStatementScorllable(sql, conn);
}
catch (SQLException e)
{
pstmt = getPrepareStatementNormal(sql, conn);
}
}
else if (stateType == StatementType.GenerateKey)
{
pstmt = getPrepareStatementGenerateKey(sql, conn);
}
else
{
pstmt = getPrepareStatementNormal(sql, conn);
}
if (pstmt != null)
{
pstmt.clearParameters();
pstmt.setFetchSize(config.getFetchSize());
}
return pstmt;
}
/**
* ��ÿ��Է�������ֵ��PrepareStatement
*
* @param sql SQL���
* @param conn ���ݿ�����
* @return PrepareStatement
* @throws Exception
*/
private PreparedStatement getPrepareStatementGenerateKey(String sql, ProxyConnection conn)
throws SQLException
{
PreparedStatement pstmt = mapPS.get(sql);
if (pstmt != null)
{
if (pstmt.isClosed())
{
mapPS.remove(sql);
pstmt = getPrepareStatementByType(sql, conn, StatementType.GenerateKey);
mapPS.put(sql, pstmt);
}
}
else
{
pstmt = getPrepareStatementByType(sql, conn, StatementType.GenerateKey);
mapPS.put(sql, pstmt);
}
return pstmt;
}
/**
* ��ÿɻ�����PrepareStatement
*
* @param sql SQL���
* @param conn ���ݿ�����
* @return PrepareStatement
* @throws Exception
*/
private PreparedStatement getPrepareStatementScorllable(String sql, ProxyConnection conn)
throws SQLException
{
PreparedStatement pstmt = mapPS.get(sql);
if (pstmt != null)
{
if (pstmt.isClosed())
{
mapPS.remove(sql);
pstmt = getPrepareStatementByType(sql, conn, StatementType.Scorllable);
mapPS.put(sql, pstmt);
}
}
else
{
pstmt = getPrepareStatementByType(sql, conn, StatementType.Scorllable);
mapPS.put(sql, pstmt);
}
return pstmt;
}
/**
* �����ͨPrepareStatement
*
* @param sql SQL���
* @param conn ���ݿ�����
* @return PrepareStatement
* @throws Exception
*/
private PreparedStatement getPrepareStatementNormal(String sql, ProxyConnection conn)
throws SQLException
{
PreparedStatement pstmt = mapPS.get(sql);
if (pstmt != null)
{
if (pstmt.isClosed())
{
mapPS.remove(sql);
pstmt = getPrepareStatementByType(sql, conn, StatementType.Normal);
mapPS.put(sql, pstmt);
}
}
else
{
pstmt = getPrepareStatementByType(sql, conn, StatementType.Normal);
mapPS.put(sql, pstmt);
}
return pstmt;
}
/**
* ���PrepareStatement
*
* @param sql SQL���
* @param conn ����
* @param stateType ����
* @return PrepareStatement
* @throws Exception
*/
private PreparedStatement getPrepareStatementByType(String sql, ProxyConnection conn, StatementType stateType)
throws SQLException
{
DataSourceConfiguration config = ConnectionFactory.getInstance().getCurrentDataSourceConfig();
ResultSetConfig rsConfig = config.getResultSetConfig();
PreparedStatement pstmt = null;
if (stateType == StatementType.Scorllable)
{
pstmt = conn.prepareStatement(sql, rsConfig.getType(), rsConfig.getConcurrency());
}
else if (stateType == StatementType.GenerateKey)
{
pstmt = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
}
else
{
pstmt = conn.prepareStatement(sql);
}
pstmt = new ProxyPrepareStatement(sql, conn, pstmt);
return pstmt;
}
/**
* �ر�PreparedStatement
*/
public void close()
{
if (mapPS.size() > 0)
{
for (PreparedStatement stmt : mapPS.values())
{
try
{
stmt.close();
}
catch (SQLException e)
{
logger.debug("StatementFactory close PreparedStatement " + stmt + " error.", e);
}
}
mapPS.clear();
}
if (mapCS.size() > 0)
{
for (CallableStatement stmt : mapCS.values())
{
try
{
stmt.close();
}
catch (SQLException e)
{
logger.debug("StatementFactory close CallableStatement " + stmt + " error.", e);
}
}
mapCS.clear();
}
}
}