一、先来看看手工创建的方式
public static Connection getConnection() { Connection conn = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/mytable?useUnicode=true&characterEncoding=utf8", "root", "123456"); } catch (Exception e) { e.printStackTrace(); } return conn; }
这种直接建立的方式一定要注意:在访问完成后链接的释放。
conn.close();
如果这个时候循环查询一个表100次,你能看到数据库建立了100个链接,如果你释放了的话,100个链接会或快或慢的全部释放掉。
如果数据库访问很频繁的话,好可惜啊,刚建立好一个链接就拆掉了,刚拆完又要新建一个链接……
所以,连接池出来了。较为熟悉的有c3p0、dbcp2等等。
二、通过dbcp2连接池获取Connection
一个较好的初始化配置实例。
1 // ThreadSafe 2 private static final ThreadLocalconnHolder; 3 private static final BasicDataSource dataSource; 4 5 static { 6 connHolder = new ThreadLocal (); 7 dataSource = new BasicDataSource(); 8 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 9 dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/mytable");10 dataSource.setUsername("root");11 dataSource.setPassword("123456");12 /// 设置空闲和借用的连接的最大总数量,同时可以激活。13 dataSource.setMaxTotal(60);14 // 设置初始大小15 dataSource.setInitialSize(5);16 // 最小空闲连接17 dataSource.setMinIdle(8);18 // 最大空闲连接19 dataSource.setMaxIdle(16);20 // 超时等待时间毫秒21 dataSource.setMaxWaitMillis(2 * 10000);22 // 只会发现当前连接失效,再创建一个连接供当前查询使用23 dataSource.setTestOnBorrow(true);24 // removeAbandonedTimeout :超过时间限制,回收没有用(废弃)的连接(默认为 300秒,调整为180)25 dataSource.setRemoveAbandonedTimeout(180);26 // removeAbandoned :超过removeAbandonedTimeout时间后,是否进27 // 行没用连接(废弃)的回收(默认为false,调整为true)28 // DATA_SOURCE.setRemoveAbandonedOnMaintenance(removeAbandonedOnMaintenance);29 dataSource.setRemoveAbandonedOnBorrow(true);30 // testWhileIdle31 dataSource.setTestOnReturn(true);32 // testOnReturn33 dataSource.setTestOnReturn(true);34 // setRemoveAbandonedOnMaintenance35 dataSource.setRemoveAbandonedOnMaintenance(true);36 // 记录日志37 dataSource.setLogAbandoned(true);38 dataSource.setDefaultAutoCommit(true);39 40 }41 42 public static Connection getConnection() {43 Connection conn = connHolder.get();44 if (conn == null) {45 try {46 conn = dataSource.getConnection();47 System.out.println("get connection success");48 } catch (SQLException e) {49 System.out.println("get connection failure:" + e);50 } finally {51 connHolder.set(conn);52 }53 }54 return conn;55 }56 57 public static void closeConnection() {58 Connection conn = connHolder.get();59 if (conn != null) {60 try {61 conn.close();62 System.out.println("close connection success");63 } catch (SQLException e) {64 System.out.println("close connection failure:" + e);65 throw new RuntimeException(e);66 } finally {67 connHolder.remove();68 }69 }70 }
实际使用的时候,释放conn链接的方法可以直接调用conn.close()方法,也可以使用closeConnection()方法。
区别就是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。