3.使用代理模式实现RealConnection和RealPreparedStatement
1.RealConnection持有一个数据库连接Connection,并且管理连接的负载和空闲时间。
public class RealConnection implements IStatementCallback {
private Connection connection;
private AtomicInteger statementCount=new AtomicInteger(0);
private long idleStartNanoTime = Long.MAX_VALUE;
public RealConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://...", "root", "passwd");
} catch (Exception e) {
e.printStackTrace();
}
}
public RealPreparedStatement prepareStatement(String sql) {
RealPreparedStatement realStatement = null;
try {
realStatement = new RealPreparedStatement(
connection.prepareStatement(sql), this);
} catch (SQLException e) {
e.printStackTrace();
}
return realStatement;
}
public int getCount() {
return statementCount.get();
}
public long getIdleAtNanos() {
if (idleStartNanoTime < 0)
return idleStartNanoTime;
return System.nanoTime() - idleStartNanoTime;
}
public void close() {
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void newStatement() {
statementCount.incrementAndGet();
idleStartNanoTime = -1L;
}
@Override
public void closeStatement() {
if (statementCount.decrementAndGet() <= 0) {
idleStartNanoTime = System.nanoTime();
}
}
}
2.RealPreparedStatement持有一个PreparedStatement,并且使用接口注入的方式回调新建和关闭事件。
public class RealPreparedStatement implements AutoCloseable{
private PreparedStatement statement;
private IStatementCallback callback;
public RealPreparedStatement(PreparedStatement statement, IStatementCallback callback) {
this.statement = statement;
this.callback = callback;
callback.newStatement();
}
public void setInt(int parameterIndex, int x) throws SQLException {
statement.setInt(parameterIndex, x);
}
public void setString(int parameterIndex, String x) throws SQLException {
statement.setString(parameterIndex, x);
}
public int executeUpdate() throws SQLException {
return statement.executeUpdate();
}
public ResultSet executeQuery() throws SQLException {
return statement.executeQuery();
}
public void close() throws SQLException {
if (statement != null) {
statement.close();
callback.closeStatement();
}
}
}