データベース接続プールの実装(待機処理を含む)


これはデータベース接続プール実装の例であり、接続待機処理を含む簡単な実装である.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import org.lt.cj.config.ServerProperty;

//     
public class MyDataSource {

    private static MyDataSource instance = new MyDataSource();
    private static String driver = "com.mysql.jdbc.Driver";
    private static String url = "jdbc:mysql://127.0.0.1:3306/tmall";
    private static String user = "root";
    private static String password = "123456";
    private static int initCount = 3; //       
    private static int maxCount = 10; //      
    private static int timeout = 100; //               (  )
    int currentCount = 0; //      
    // LinkedList        ,   ArrayList 
    private final LinkedList<Connection> connectionsPool = new LinkedList<Connection>();

    public MyDataSource() {
        try {
            for (int i = 0; i < this.initCount; i++) {
                //                 
                this.connectionsPool.addLast(this.createConnection());
                this.currentCount++;
            }
        } catch (SQLException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public static MyDataSource getInstance() {
        return instance;
    }

    //                     
    static {
        ServerProperty sp = new ServerProperty();
        driver = sp.getValue("driver");
        url = sp.getValue("databaseUrl");
        user = sp.getValue("username");
        password = sp.getValue("password");
        initCount = Integer.parseInt(sp.getValue("initCount"));
        maxCount = Integer.parseInt(sp.getValue("maxCount"));
        timeout = Integer.parseInt(sp.getValue("timeout"));
        sp.closeI();

        try {
            Class.forName(driver);//       ,   ,     
        } catch (ClassNotFoundException e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public Connection getConnection() {
        synchronized (connectionsPool) {
            if (this.connectionsPool.size() > 0) { //               ,        
                return this.connectionsPool.removeFirst();
            }
            if (this.currentCount < maxCount) {
                try {
                    this.currentCount++;
                    return this.createConnection();
                } catch (SQLException ex) {
                    return null;  //      ,   
                }
            }
            return getConnection(timeout);
        }
    }

    /**
     *               
     */
    public synchronized Connection getConnection(long timeout) {
        Connection con = null;
        while ((con = getConnection()) == null) {
            try {
                Thread.sleep(timeout);
            } catch (InterruptedException e) {
            }
        }
        return con;
    }

    //     ,          ,       
    public void free(Connection conn) {
        synchronized (connectionsPool) {
            this.connectionsPool.addLast(conn);
        }
    }

    //           ,           
    private Connection createConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }
}

プロファイル読み込みクラス:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ServerProperty {

    private Properties prop = null;
    private InputStream in = null;

    public ServerProperty() {
        initProperty();
    }

    public ServerProperty(String path) {
        try {
            prop = new Properties();
            in = new FileInputStream(path);
        } catch (FileNotFoundException ex) {
        }
    }

    private void initProperty() {
        try {
            prop = new Properties();
            in = new FileInputStream("conf/database.properties");
        } catch (FileNotFoundException ex) {
        }
    }

    private void setIs() {
        try {
            if (in == null) {
                in = new FileInputStream("conf/database.properties");
            }
        } catch (IOException ex) {
        }
    }

    public Properties getProperty() {
        try {
            setIs();
            prop.load(in);
        } catch (IOException ex) {
        }
        return prop;
    }

    public String getValue(String key) {
        String value = "";
        try {
            setIs();
            prop.load(in);
            value = prop.getProperty(key);
        } catch (IOException ex) {
        }
        return value;
    }

    public void closeI() {
        try {
            if (in != null) {
                in.close();
            }
        } catch (IOException ex) {
        }
    }
}

プロジェクトディレクトリの下のファイル:conf/database.properties
内容:

#Oracle config#
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@192.168.0.23:1521:ora10g
#user=openlab
#password=open123

#Mysql config#
driver=com.mysql.jdbc.Driver
databaseUrl=jdbc:mysql://127.0.0.1:3306/tmall
username=root
password=123456
#     
initCount=3
#     
maxCount=20
#               (  )
timeout=100

呼び出し:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class CollectImpl implements ICollectDao {

    private static final MyDataSource ds = new MyDataSource();
    private static Connection conn = null;

    public Connection getConnection() {
        return (Connection) ds.getConnection(); 
    }

    //    
    public void closePsRs(PreparedStatement ps, ResultSet rs) {
        try {
            if (ps != null) {
                ps.close();
            }
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException ex) {
        }
    }

    public void free(Connection conn) {
        ds.free(conn);
    }

    //        
    public void insertCategory(String name, int firstCate, int secondCate, String lanFrom, String toLan, int updated) {
        conn = getConnection();
        System.out.println("---------" + conn);
        PreparedStatement ps = null;
        ResultSet rs = null;
        String sql = "INSERT INTO `" + lanFrom + "_category` (`name`,`first_cate`,`second_cate`,`orig_lan`,`to_lan`,`updated`) VALUES(?,?,?,?,?,?)";
        try {
            ps = (PreparedStatement) conn.prepareStatement(sql);
            ps.setString(1, name);
            ps.setInt(2, firstCate);
            ps.setInt(3, secondCate);
            ps.setString(4, lanFrom);
            ps.setString(5, toLan);
            ps.setInt(6, updated);
            ps.executeUpdate();
        } catch (SQLException ex) {
        } finally {
            closePsRs(ps, rs);
            free(conn);
        }
    }
}