一般我们在操作数据库时候,需要频繁的打开和关闭连接,而创建数据库连接往往开销比较大,因而我们需要避免这种情况的发生,在这里我们可以创建一个连接池,当操作数据的时候,我们从连接池中取出连接,操作完毕后再将连接放回到池中。
在这里我们需要用到集合,大家知道ArrayList结合其实是一个数组,它读取数据的时候速度比较快,而LinkedList集合在操作的时候要比ArrayList要快的多,所以这里我们选择集合LinkedList。
1.编写一个连接池的类
1 package cn.mycast.bank.db; 2 3 import java.sql.Connection; 4 import java.util.LinkedList; 5 import cn.mycast.bank.util.JdbcUtil; 6 public class MyDatabasePool { 7 private LinkedList<Connection> connPool=new LinkedList<Connection>();//存放连接 8 public MyDatabasePool(){ 9 for(int i=0;i<10;i++)//连接池中存放10个连接 10 { 11 this.connPool.addLast(this.CreateConnection());//每次添加到集合最后面 12 } 13 } 14 public Connection CreateConnection(){//获得连接 15 return JdbcUtil.getConnection(); 16 } 17 public Connection GetConnection(){ 18 return connPool.removeFirst();//取出最上面的一个连接 19 } 20 public void FreeConnection(Connection conn){//将用完后的连接放回到集合中 21 this.connPool.addLast(conn); 22 } 23 }
2.编写一个操作数据库连接的工具类
1 package cn.mycast.bank.util; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.sql.Connection; 6 import java.sql.DriverManager; 7 import java.sql.ResultSet; 8 import java.sql.SQLException; 9 import java.sql.Statement; 10 import java.util.Properties; 11 12 import cn.mycast.bank.db.MyDatabasePool; 13 public class JdbcUtil { 14 private static String driver; 15 private static String url; 16 private static String username; 17 private static String password; 18 private static MyDatabasePool connPool;//连接池类 19 static{ 20 // 通过类加载器获得资源,并以流的方式进行操作 21 InputStream is=JdbcUtil.class.getClassLoader().getResourceAsStream("cn/mycast/bank/util/Mysqldb.properties"); 22 Properties properties=new Properties(); 23 try { 24 properties.load(is); 25 url=properties.getProperty("url"); 26 driver=properties.getProperty("driver"); 27 username=properties.getProperty("username"); 28 password=properties.getProperty("password"); 29 } catch (IOException e) { 30 e.printStackTrace(); 31 } 32 } 33 static{ 34 try { 35 Class.forName(driver);//注册驱动 36 connPool=new MyDatabasePool(); 37 } catch (ClassNotFoundException e) { 38 e.printStackTrace(); 39 } 40 } 41 42 public static Connection getConnection(){ 43 Connection conn=null; 44 try { 45 conn=DriverManager.getConnection(url, username, password);//获得连接 46 } catch (SQLException e) { 47 e.printStackTrace(); 48 }finally{ 49 50 } 51 return conn; 52 } 53 public static void close(Connection conn){ 54 if(conn!=null) 55 connPool.FreeConnection(conn); //将连接放回集合 56 } 57 public static void close(Statement stm){ 58 try { 59 if(stm!=null) 60 stm.close(); 61 } catch (SQLException e) { 62 e.printStackTrace(); 63 } 64 } 65 public static void close(ResultSet rs){ 66 try { 67 if(rs!=null) 68 rs.close(); 69 } catch (SQLException e) { 70 e.printStackTrace(); 71 } 72 } 73 }
后面只需调用该工具类的相关方法即可
其实可以注意到,在获取数据库连接的时候,如果是多个线程并发的获取的话,当连接池中没有连接的时候,那么这候再获取的时候就会报错,而且该操作属于非线程安全的,这里
需要加上同步代码块,避免多个线程获取同一个连接。
1 public Connection CreateConnection(){//获得连接 2 synchronized(connectionsPool){ 3 if(this.connectionsPool.size()>0){ 4 return JdbcUtil.getConnection(); 5 } 6 if(this.currentCount<MaxCount){ 7 this.currentCount++; 8 return this.CreateConnection(); 9 } 10 } 11 }