1. O que é o JDBC Connection Pool?
Nas conexões tradicionais do JDBC, cada vez que você obtém uma conexão de conexão, é necessário carregar algum código complicado para obter, como o seguinte código:
conexão estática pública getConn () {conexão conn = null; String url = "jdbc: mysql: // localhost: 3306/teste"; String user = "root"; String senha = "root"; tente {Class.ForName ("com.mysql.jdbc.driver"); Conn = DriverManager.getConnection (URL, usuário, senha); } catch (classNotFoundException e) {e.printStackTrace (); } catch (sqLexception e) {e.printStackTrace (); } retornar Conn; }Tais operações complicadas são apenas para obter uma conexão. Obviamente, podemos encapsulá -lo em uma classe de ferramentas para acessar (a figura acima encapsula a conexão da conexão), mas é um desperdício de desempenho para carregar cada conexão? Para otimizar o desempenho, um pool de conexões é exibido.
Quando o pool de conexões é inicializado, várias conexões são criadas para usarmos. Quando precisamos nos conectar, precisamos apenas obter conexões existentes no pool de conexões. Quando não houver conexões inicializadas, uma conexão será recriada. Depois de usar a conexão, a conexão não será destruída, mas será devolvida ao pool de conexão para uso posterior. (Claro, o pool de conexões não é apenas tão simples, aqui estão as apresentações)
Os pools de conexão comumente usados incluem DBCP e C3P0. Os mais mainstream agora são o Druid Connection Pool do Alibaba e o próprio JNDI Connection Pool do Tomcat.
2. Personalize um pool de conexão simples
Análise dos pools de conexão personalizados:
1.2. Por ser um pool de conexões, precisamos implementar a interface DataSource e implementar os métodos nele. Com base em nossa situação, somos sobre o método getConnection ();
2. Como queremos armazenar vários objetos de conexão, usamos uma coleção para armazená -la. Com base nas operações frequentes de adição e exclusão, use o LinkedList;
3. A destruição de uma conexão não é destruir a conexão, mas retornar a conexão ao pool de conexão.
codificação:
1. Crie uma classe MyDataSource e implemente a interface DataSource
Quando esta classe é carregada, ela precisa ter um contêiner para armazenar a conexão, então defina uma propriedade estática:
Lista estática privada <Cneconoming> ConnectionList = new LinkedList <> ();
2. Como precisamos obter a conexão do banco de dados, encapsulamos um método para obter a conexão do banco de dados.
Public Connection getOneConnection () {conexão conn = null; tente {// Os dados obtidos aqui são obtidos através do arquivo de propriedades externas, que é mais flexível. InputStream in = myDatasource.class.getclassloader (). getResourceasStream ("jdbc/jdbc.properties"); Propriedades pro = new Properties (); pro.load (in); driver = pro.getProperty ("driver"); url = pro.getProperty ("url"); nome de usuário = pro.getProperty ("usuário"); senha = pro.getProperty ("senha"); Class.ForName (Driver); Conn = DriverManager.getConnection (URL, nome de usuário, senha); } catch (Exceção e) {e.getStackTrace (); } retornar Conn; }Observe que os dados que obtive através do arquivo de propriedade podem ser selecionados de acordo com a situação real.
3. Inicialize várias conexões e coloque -as no recipiente. Ele pode ser implementado usando blocos de código estático, mas se essa fonte de dados não for usada, causará resíduos de recursos, por isso pensei em colocar a implementação de inicializar várias conexões em seu construtor, ou seja, quando esse pool de conexão for necessário, criará várias conexões de acordo. do seguinte modo:
public myDataSource () {for (int i = 0; i <5; i ++) {conexão Conn = getOneConnection (); // Chame o método para criar o ConnectionList.add (Conn); }}4. Agora comece a substituir o método externo para getConnection () para obter a conexão deste pool de conexão
@Override Public Connection getConnection () lança sqlexception {conexão conn = null; if (ConnectionList == NULL || ConnectionList.size () <= 0) {Connection Connection = getConnection (); ConnectionList.add (conexão); } Conn = ConnectionList.Remove (0); retornar Conn; }5. Crie um método de retorno de objeto, coloque a conexão usada no pool de conexão
public void backconnection (conexão Conn) {ConnectionList.add (Conn); }OK, isso completa um pool de conexão personalizado simples e o código de teste é o seguinte:
public static void main (string [] args) lança sqlexception {myDataSource DataSource = new MyDataSource (); Conexão Conn = DataSource.getConnection (); String sql = "selecione * do usuário onde u_id =?"; Preparado estatement ps = null; ResultSet rs = null; tente {ps = Conn.Preparestatement (SQL); ps.setInt (1, 1); rs = ps.executeQuery (); while (rs.Next ()) {System.out.println ("id ="+rs.getInt (1)); System.out.println ("userName ="+rs.getString (2)); System.out.println ("senha ="+rs.getString (3)); }} catch (sqLexception e) {e.printStackTrace (); } finalmente {DataSource.backConnection (Conn); }}Porque ignorar, não há outros dois objetos no meu código para fechar.
Agora, há um pequeno problema que nossa conexão de fechamento é alcançada através do método do pool de conexões. No entanto, se o usuário chamar o método de fechamento do objeto de conexão, a conexão será destruída e não devolvida ao pool de conexões. Em seguida, otimizamos para que o usuário não destrua a conexão, mas retorne a conexão.
Entre eles, existem muitas soluções e aqui está um modelo decorativo.
Otimização:
1. Crie uma nova classe MyConnection para implementar a interface de conexão, onde seus tipos de atributo são conexões Connecn e uma liis <neconned>.
conexão privada Conn; Lista privada <neconoms> pool; public myConnection (conexão conn, list <neconne> pool) {this.conn = conn; this.pool = pool; }2. Em seguida, implemente o método próximo da interface
@Override public void Close () lança SqLexception {System.out.println ("Recicle Connection"); pool.add (Conn); }3. Em seguida, implemente o método de obter a declaração. Se não for implementado, ocorrerá um erro de ponteiro nulo ao obter esta instrução. Eu implemento apenas o método de obtenção do estatuto preparado.
@Override public preparado estatamento PreparEstatement (string sql) lança sqlexception {system.out.println ("get declaration"); Retornar Conn.Preparestatement (SQL); }4. Em seguida, exclua o método backconnection da classe MyDataSource para retornar a conexão e modificar o construtor e o método para obter a conexão da seguinte maneira
public myDataSource2 () {for (int i = 0; i <5; i ++) {conexão conn = getOneConnection (); MyConnection myConn = new MyConnection (Conn, ConnectionList); ConnectionList.add (MyConn); }} @Override Public Connection getConnection () lança sqlexception {conexão conn = null; if (ConnectionList == NULL || ConnectionList.size () <= 0) {Connection Connection = getConnection (); MyConnection myconn = new myConnection (conexão, conexãolist); ConnectionList.add (MyConn); } Conn = ConnectionList.Remove (0); retornar Conn; }OK, para que o usuário não destrua a conexão chamando nosso método de fechamento de conexão diretamente e o retornará corretamente ao pool de conexões. Você pode testá -lo fazendo uma pequena modificação no código de teste.
O artigo acima é o conteúdo inteiro que compartilhei com você. Espero que possa lhe dar uma referência e espero que você possa apoiar mais o wulin.com.