1、新建Java工程,导入mysql的jar包(案例使用8.0版本的jar包)
2、新建fh-config.properties文件,用于保存数据库信息
3、分析:
(1)连接池类用来获取连接(FeihongConnectionPool)
(2)实现继承实现Connection接口的抽象类(FeihongConnection),目的是使用代理模式,保证通用性
(3)实现Connection接口的抽象类(AbstractConnection),使用适配器模式,灵活按需重写方法
(4)Test测试类
4、FeihongConnectionPool实现:
package feihongconnectionpool;
import java.sql.Connection;
import java.util.ArrayList;
public class FeihongConnectionPool {
//连接池集合
private static ArrayList<Connection> connections = new ArrayList<>();
//连接池状态数组 1:占用 0:空闲
private static ArrayList<Integer> status = new ArrayList<>();
//connections的长度
private int index = 0;
public synchronized Connection getConnection () {
//将集合瘦身,如果大小超过最大值,不给连接
connections.trimToSize();
Connection con = null;
//获取空闲的连接池索引
int con_index = findFree();
if(con_index == -1){
if(connections.size() >= LoadConfig.getInteger("maxPoolSize")){
return null;
}
//设置这个索引是为了归还的时候设置状态参数
con = new FeihongConnection(this.index);
connections.add(con);
status.add(1);
this.index++;
return con;
}else{
con = connections.get(con_index);
status.set(con_index,1);
return con;
}
}
private int findFree () {
//如果为0获取元素会出现异常
if(status.size()==0){
return -1;
}
//如果状态数组里有空闲,返回空闲状态的索引
for(int i = 0; i < status.size(); i++){
if(status.get(i) == 0){
return i;
}
}
return -1;
}
public static void setStatus (int index,int value) {
status.set(index,value);
}
//测试方法
public static ArrayList<Connection> getConnections () {
return connections;
}
public static ArrayList<Integer> getStatus () {
return status;
}
}
5、实现FeihongConnection类
package feihongconnectionpool;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class FeihongConnection extends AbstractConnection {
private Connection connection;
public int index;
//获取连接
{
try {
Class.forName(LoadConfig.getString("driver"));
String url = LoadConfig.getString("url");
String user = LoadConfig.getString("user");
String password = LoadConfig.getString("password");
this.connection = DriverManager.getConnection(url,user,password);
} catch (Exception e) {
e.printStackTrace();
}
}
public FeihongConnection(int index) {
this.index = index;
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
return connection.prepareStatement(sql);
}
@Override
public void close() throws SQLException {
FeihongConnectionPool.setStatus(this.index,0);
}
}
6、实现AbstractConnection类(子类必须重写PrepareStatement和close方法)
package feihongconnectionpool;
import java.sql.*;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
public abstract class AbstractConnection implements Connection {
public AbstractConnection() {
super();
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return super.toString();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
}
@Override
public Statement createStatement() throws SQLException {
return null;
}
@Override
public abstract PreparedStatement prepareStatement(String sql) throws SQLException;
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
return null;
}
@Override
public String nativeSQL(String sql) throws SQLException {
return null;
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
}
@Override
public boolean getAutoCommit() throws SQLException {
return false;
}
@Override
public void commit() throws SQLException {
}
@Override
public void rollback() throws SQLException {
}
@Override
public abstract void close() throws SQLException ;
@Override
public boolean isClosed() throws SQLException {
return false;
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
return null;
}
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
}
@Override
public boolean isReadOnly() throws SQLException {
return false;
}
@Override
public void setCatalog(String catalog) throws SQLException {
}
@Override
public String getCatalog() throws SQLException {
return null;
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
}
@Override
public int getTransactionIsolation() throws SQLException {
return 0;
}
@Override
public SQLWarning getWarnings() throws SQLException {
return null;
}
@Override
public void clearWarnings() throws SQLException {
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
return null;
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
}
@Override
public void setHoldability(int holdability) throws SQLException {
}
@Override
public int getHoldability() throws SQLException {
return 0;
}
@Override
public Savepoint setSavepoint() throws SQLException {
return null;
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
return null;
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return null;
}
@Override
public Clob createClob() throws SQLException {
return null;
}
@Override
public Blob createBlob() throws SQLException {
return null;
}
@Override
public NClob createNClob() throws SQLException {
return null;
}
@Override
public SQLXML createSQLXML() throws SQLException {
return null;
}
@Override
public boolean isValid(int timeout) throws SQLException {
return false;
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
}
@Override
public String getClientInfo(String name) throws SQLException {
return null;
}
@Override
public Properties getClientInfo() throws SQLException {
return null;
}
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return null;
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return null;
}
@Override
public void setSchema(String schema) throws SQLException {
}
@Override
public String getSchema() throws SQLException {
return null;
}
@Override
public void abort(Executor executor) throws SQLException {
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
}
@Override
public int getNetworkTimeout() throws SQLException {
return 0;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
}
注意:可以通过适配器模式,只是偷懒
7、测试类及结果
package feihongconnectionpool;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
FeihongConnectionPool fcp = new FeihongConnectionPool();
//最大设置8
Connection con = fcp.getConnection();
Connection con1 = fcp.getConnection();
Connection con2 = fcp.getConnection();
Connection con3 = fcp.getConnection();
Connection con4 = fcp.getConnection();
Connection con5 = fcp.getConnection();
Connection con6 = fcp.getConnection();
Connection con7 = fcp.getConnection();
String sql = "select * from users;";
try {
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next()){
System.out.println(rs.getString("name")+":"+rs.getString("job"));
}
con.close();//会释放
} catch (SQLException e) {
e.printStackTrace();
}
Connection con8 = fcp.getConnection();
Connection con9 = fcp.getConnection();
System.out.println(con9);//feihongconnectionpool.FeihongConnection@7946e1f4
System.out.println(con9);//null
ArrayList<Connection> cons_list = FeihongConnectionPool.getConnections();
ArrayList<Integer> status_list = FeihongConnectionPool.getStatus();
System.out.println("cons_size:" + cons_list.size());//size:8
for(int i : status_list){
System.out.println("status:"+i);//1 1 1 1 1 1 1 1
}
}
输出结果:
--------------------------------------------思考的过程是有趣的------------------------------------------------------------------------
测试还是花了时间和精力的,但是最后终于实现功能还是很开心的,哈哈。。。。