一、连接池的作用及讲解
连接池的作用就是为了提高性能。并不是提高了访问的效率,而是建立连接的效率,提前在连接池中放了很多连接,在祁东服务器时就与数据库建立了多个连接对象(放在连接池中,加快连接与关闭的效率),访问数据时直接从连接池中获取连接。
连接池的作用:连接池是将已经创建好的连接保存在池中,当有请求来时,直接使用已经创建好的连接对数据库进行访问。这样省略了创建连接和销毁连接的过程。这样性能上得到了提高。
关闭连接时,只是将连接重新放回连接池,如果不放回,则访问达到最大值后,无法再进行访问。
基本原理是这样的:
(1)建立数据库连接池对象(服务器启动)。
(2)按照事先指定的参数创建初始数量的数据库连接(即:空闲连接数)。
(3)对于一个数据库访问请求,直接从连接池中得到一个连接。如果数据库连接池对象中没有空闲的连接,且连接数没有达到最大(即:最大活跃连接数),创建一个新的数据库连接。
(4)存取数据库。
(5)关闭数据库,释放所有数据库连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中。如实际空闲连接数大于初始空闲连接数则释放连接)。
(6)释放数据库连接池对象(服务器停止、维护期间,释放数据库连接池对象,并释放所有连接)。
1 .连接池的概念和为什么要使用连接池?
连接池放了N个Connection对象,本质上放在内存当中,在内存中划出一块缓存对象,应用程序每次从池里获得Connection对象,而不是直接从数据里获得,这样不占用服务器的内存资源。
2 .如果不使用连接池会出现的情况:
a.占用服务器的内存资源
b.导致服务器的速度非常慢
3 .应用连接池的三种方式:
a.自定义连接池
b.使用第三方连接池
c.使用服务器自带的连接池
连接池一般比直接连接更有优越性,因为它提高了性能的同时还保存了宝贵的资源。在整个应用程序的使用过程,当中重复的打开直接连接将导致性能的下降。而池连接只在服务器启动时打开一次,从而消除了这种性能问题。
连接池主要考虑的是性能,每次获取连接和释放连接都有很大的工作量,会对性能有很大影响;而对资源来说起的是反作用,因为保存一定数量的连接是要消耗内存的。应用程序每次从池里获得Connection对象,而不是直接从数据里获得,这样不占用服务器的内存资源。所以一般要建立连接池,而连接的数量要适当,不能太大,太大会过多消耗资源。(所以,考虑2个方面,一个是内存,另一个是资源)。
连接池就是为了避免重复多次的打开数据库连接而造成的性能的下降和系统资源的浪费。
原文链接:https://blog.csdn.net/cbmljs/article/details/87858536
二、自定义连接池
1、定义连接池工厂
package cn.bjsxt.sscs.util; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.util.Properties; import org.logicalcobwebs.proxool.configuration.PropertyConfigurator; public class ConnectPoolFactory { private static ConnectPoolFactory connectPoolFactory=null; private ConnectPoolFactory() {//构造方法 init(); } public void init(){//把properties文件加载到链接对象 InputStream is = ConnectPoolFactory.class.getResourceAsStream("/proxool.properties"); Properties properties = new Properties(); try { properties.load(is); PropertyConfigurator.configure(properties); } catch (Exception e) { e.printStackTrace(); } } public static ConnectPoolFactory getInstance(){//单例 if(null == connectPoolFactory){ connectPoolFactory = new ConnectPoolFactory(); } return connectPoolFactory; } public Connection getConnect(){ Connection conn=null; try { Class.forName("org.logicalcobwebs.proxool.ProxoolDriver"); conn = DriverManager.getConnection("proxool.test");//与配置文件的名称保持一致 } catch (Exception e) { e.printStackTrace(); } return conn; } }
2、配置文件
jdbc-1.proxool.alias=test #jdbc-1.proxool.driver-class=com.mysql.jdbc.Driver #jdbc-1.proxool.driver-url=jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=utf8 jdbc-1.proxool.driver-class=oracle.jdbc.OracleDriver jdbc-1.proxool.driver-url=jdbc:oracle:thin:@127.0.0.1:1521:orcls jdbc-1.user=c02 jdbc-1.password=c02 #最大连接数 jdbc-1.proxool.maximum-connection-count=100 jdbc-1.proxool.minimum-connection-count=5 jdbc-1.proxool.prototype-count=4 jdbc-1.proxool.verbose=true jdbc-1.proxool.statistics=10s,1m,1d jdbc-1.proxool.statistics-log-level=error
3、工具类
package cn.bjsxt.sscs.util; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import org.apache.log4j.Logger; public class DBUtil { //定义一个日志记录器 private static final Logger logger=Logger.getLogger(DBUtil.class.getName()); //使用日志记录器记录日志(在需要的地方) /** * 获取数据库连接 * @return */ public static Connection getConnection(){ //Connection conn = null; // String driver ="oracle.jdbc.OracleDriver"; // String url ="jdbc:oracle:thin:@127.0.0.1:1521:orcls"; // String user="c02"; // String password ="c02"; // try { // //加载驱动 // Class.forName(driver); // //(和数据库)建立连接 // conn = DriverManager.getConnection(url, user, password); // } catch (ClassNotFoundException e) { // e.printStackTrace(); // } catch (SQLException e) { // e.printStackTrace(); // } Connection conn=ConnectPoolFactory.getInstance().getConnect(); /* *配置了web.xml后用这个获取连接 * try { Class.forName("org.logicalcobwebs.proxool.ProxoolDriver"); conn = DriverManager.getConnection("proxool.test"); } catch (Exception e) { e.printStackTrace(); }*/ logger.info("成功建立了数据库连接:"+conn); return conn; } /** * 关闭数据库资源 * PrepraredStataement是Statement的子接口,也可以传入 * @param rs * @param stmt * @param conn */ public static void closeAll(ResultSet rs,Statement stmt,Connection conn){ try { if(rs != null){ rs.close(); } } catch (SQLException e) { e.printStackTrace(); } logger.debug("成功关闭了结果集:"+stmt); try { if(stmt != null){ stmt.close(); } } catch (SQLException e) { e.printStackTrace(); } logger.debug("成功关闭了Statement:"+stmt); try { if(conn != null){ conn.close(); } } catch (SQLException e) { e.printStackTrace(); } logger.debug("成功关闭了连接:"+conn); } /** * 完成DML操作:insert,update和delete * @param sql * @param params * @return */ public static int executeUpdate(String sql,Object [] params) { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; int n=0; try { //(和数据库)建立连接 conn = getConnection(); //(向数据库)发送命令并得到结果 pstmt = conn.prepareStatement(sql); for(int i=0;i<params.length;i++){ pstmt.setObject(i+1, params[i]); } n = pstmt.executeUpdate(); //处理结果 } catch (SQLException e) { //e.printStackTrace(); logger.error(e.toString()); }finally{ //关闭资源 closeAll(rs, pstmt, conn); } //返回数据 return n; } public static void main(String[] args) { Connection conn = DBUtil.getConnection(); System.out.println(conn); } }
三、web.xml配置连接池
也可以在web.xml中配置连接池,则无需再创建工具类(只有web项目可以这么用)。在开发时,一般不在web.xml中配置获取连接池的servlet,这样就无法用test进行检验了。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>sscs</display-name> <!-- Web项目中配置proxool,并自动加载 --> <!-- <servlet> <servlet-name>ServletConfigurator</servlet-name> <servlet-class> org.logicalcobwebs.proxool.configuration.ServletConfigurator </servlet-class> <init-param> <param-name>propertyFile</param-name> <param-value>WEB-INF/classes/proxool.properties</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> --> <!-- 监控 proxool 连接池 --> <!--需要连接池也在web.xml中进行配置才可以监控到 --> <!-- <servlet> <servlet-name>AdminServlet</servlet-name> <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>AdminServlet</servlet-name> <url-pattern>/admin.jsp</url-pattern> </servlet-mapping> --> <servlet> <servlet-name>CourseAddServlet</servlet-name> <servlet-class>cn.bjsxt.sscs.servlet.CourseAddServlet</servlet-class> </servlet> <servlet> <servlet-name>ShowAllCouServlet</servlet-name> <servlet-class>cn.bjsxt.sscs.servlet.ShowAllCouServlet</servlet-class> </servlet> <servlet> <servlet-name>AdmminServlet</servlet-name> <servlet-class>cn.bjsxt.sscs.servlet.AdmminServlet</servlet-class> </servlet> <servlet> <servlet-name>StudentServlet</servlet-name> <servlet-class>cn.bjsxt.sscs.servlet.StudentServlet</servlet-class> </servlet> <servlet> <servlet-name>TeacherServlet</servlet-name> <servlet-class>cn.bjsxt.sscs.servlet.TeacherServlet</servlet-class> </servlet> <servlet> <servlet-name>CourseServlet</servlet-name> <servlet-class>cn.bjsxt.sscs.servlet.CourseServlet</servlet-class> </servlet> <servlet> <servlet-name>RandomServlet</servlet-name> <servlet-class>cn.bjsxt.sscs.util.RandomServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CourseAddServlet</servlet-name> <url-pattern>/servlet/CourseAddServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ShowAllCouServlet</servlet-name> <url-pattern>/servlet/ShowAllCouServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AdmminServlet</servlet-name> <url-pattern>/servlet/AdmminServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>StudentServlet</servlet-name> <url-pattern>/servlet/StudentServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TeacherServlet</servlet-name> <url-pattern>/servlet/TeacherServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CourseServlet</servlet-name> <url-pattern>/servlet/CourseServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>RandomServlet</servlet-name> <url-pattern>/random.jpg</url-pattern> </servlet-mapping> <!--配置过滤器 --> <filter> <filter-name>AuthFilter</filter-name> <filter-class>cn.bjsxt.sscs.filter.AuthFilter</filter-class> </filter> <filter> <filter-name>EncodingFilter</filter-name> <filter-class>cn.bjsxt.sscs.filter.EncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value><!--加入变量 --> </init-param> </filter> <filter> <filter-name>ReplaceFilter</filter-name> <filter-class>cn.bjsxt.sscs.filter.ReplaceFilter</filter-class> </filter> <filter-mapping> <filter-name>AuthFilter</filter-name> <url-pattern>/servlet/*</url-pattern> <url-pattern>*.jsp</url-pattern> <url-pattern>*.html</url-pattern> </filter-mapping> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/servlet/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>ReplaceFilter</filter-name> <url-pattern>/servlet/*</url-pattern> <url-pattern>*.jsp</url-pattern> </filter-mapping> <!--配置监听器 --> <listener> <listener-class>cn.bjsxt.sscs.listener.LogListener</listener-class> </listener> <listener> <listener-class>cn.bjsxt.sscs.listener.SettionTestListener</listener-class> </listener> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>