赞
踩
通过使用数据库连接池可以极大提升数据库CURD操作的效率,尝试参考Druid的github官网配置了一些参数。
DruidDataSource-德鲁伊数据源可以理解为它就是正在使用的某个数据库,最普遍的操作就是直接用于获取维护在连接池中的Connection连接对象,而不用自己再重新new对象了,为我们省去了创建、释放Connection对象的时间。
以下是基本的Druid数据的一些参数配置,像:JDBC基本连接参数、连接池初始化/最大容量等参数的配置。官网的配置是整合了Spring框架,通过XML文档配置的,然后通过IOC机制便捷的获取DruidDataSource的对象,可以省去自己编写代码创建数据源对象的繁琐步骤,这也是使用框架开发的好处了吧。
另外值得一提的是,官网的配置直接指定好了初始化时调用的方法init()和销毁时调用的方法close(),在start和shutdown-Spring项目时会自动调用。当然如果通过Servlet技术开发的话,也是可以基于ServletContext监听器(或者说Application域对象的监听器)javax.servlet.ServletContextListener的contextInitialized()和contextDestroyed()方法模拟Spring的IOC机制实现数据源的创建和销毁。
driverClassName=com.mysql.cj.jdbc.Driver #开启预编译机制|开启批处理机制 url=jdbc:mysql://localhost:3306/数据库名称?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true username=root password=root initialSize=5 minIdle=5 maxActive=30 maxWait=60000 poolPreparedStatements=true #是否使用预编译机制 maxPoolPreparedStatementPerConnectionSize=20 filters=log4j,wall,stat #-------------连接泄漏回收参数-------------------------------- #当未使用的时间超过removeAbandonedTimeout时,是否视该连接为泄露连接并删除 #默认为false removeAbandoned=false #泄露的连接可以被删除的超时值, 单位毫秒-默认为300*1000 removeAbandonedTimeoutMillis=300*1000 #标记当Statement或连接被泄露时是否打印程序的stack traces日志。 #默认为false logAbandoned=true #连接最大存活时间 #默认-1 #phyTimeoutMillis=-1
Servlet(最常用的用于收发请求和响应的类),Druid内置提供了一个StatViewServlet用于展示Druid的统计信息。其的用途包括:
①提供监控信息展示的html页面
②提供监控信息的JSON API内置监控页面是一个Servlet。
只需要在web.xml中按照Servlet的配置方法配置就行了。官网给出的例子如下,
<!-- 配置 Druid 监控信息显示页面 --> <servlet> <servlet-name>DruidStatView</servlet-name> <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class> <init-param> <!-- 允许清空统计数据 --> <param-name>resetEnable</param-name> <param-value>true</param-value> </init-param> <init-param> <!-- 用户名 --> <param-name>loginUsername</param-name> <param-value>druid</param-value> </init-param> <init-param> <!-- 密码 --> <param-name>loginPassword</param-name> <param-value>druid</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DruidStatView</servlet-name> <url-pattern>/druid/*</url-pattern> </servlet-mapping>
监听器(Listener)WebStatFilter用于采集web-jdbc关联监控的数据,其实就是让自己指定想要统计、不想要统计哪些数据。
关于这些init-param参数名称这样写,肯定是因为Druid内部已经预先做好了规范,只要了解参数的作用,并进行配置就可以生效了。
<!--filter配置--> <filter> <filter-name>DruidWebStatFilter</filter-name> <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class> <!--排除一些不必要的url数据统计-就是把不想统计的请求过滤掉--> <init-param> <param-name>exclusions</param-name> <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value> </init-param> <init-param> <param-name>profileEnable</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>resetEnable</param-name> <param-value>true</param-value> </init-param> <!-- 用户名 --> <init-param> <param-name>loginUsername</param-name> <param-value>druid</param-value> </init-param> <init-param> <!-- 密码 --> <param-name>loginPassword</param-name> <param-value>druid</param-value> </init-param> <init-param> <param-name>principalCookieName</param-name> <param-value>USER_COOKIE</param-value> </init-param> <init-param> <param-name>principalSessionName</param-name> <param-value>USER_SESSION</param-value> </init-param> </filter> <filter-mapping> <filter-name>DruidWebStatFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
通过手写DruidUtil类实现DruidDataSource创建,并提供获取Connection对象的获取方法,向外部提供数据库连接对象,然后配合DButils.jar提供的QueryRunner实现数据库CURD操作。
package com.xwd.utils; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * @ClassName DruidUtils * @Description: com.xwd.utils * @Auther: xiwd * @Date: 2022/2/17 - 02 - 17 - 2:33 * @version: 1.0 */ public class DruidUtil { //properties private static PropertyUtil propertyUtil =null; private static DruidDataSource dataSource;//数据源对象 // private static Logger logger;//日志打印对象 //setter //getter //static block static { //实例化Logger对象 // logger = Logger.getLogger(DruidUtil.class); //加载配置文件 propertyUtil=new PropertyUtil("/druid.properties"); try { //实例化数据源对象 dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(propertyUtil.getProperties()); // logger.fatal("Druid DataSource has been initialized SUCCESSFULLY!"); } catch (Exception e) { e.printStackTrace(); // logger.fatal("Druid DataSource initialized FAILED!"); } } //constructors //methods /** * 获取数据源DataSource对象 * @return */ public static DruidDataSource getDruidDataSource(){ return dataSource; } /** * 获取数据库连接Connection对象 * @return Connection对象 */ public static Connection getConnection(){ Connection connection = null; try { connection = dataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); return connection; } return connection; } /** * 将数据库连接对象归还到数据库连接池中 * @param connection Connection-数据库连接对象 */ public static void returnResources( Connection connection){ returnResources(null,null,connection); } /** * 将数据库连接对象归还到数据库连接池中 * @param statement Statement-SQL语句执行器 * @param connection Connection-数据库连接对象 */ public static void returnResources( Statement statement,Connection connection){ returnResources(null,statement,connection); } /** * 将数据库连接对象归还到数据库连接池中 * @param resultSet ResultSet-结果集 * @param statement Statement-SQL语句执行器 * @param connection Connection-数据库连接对象 */ public static void returnResources(ResultSet resultSet, Statement statement,Connection connection){ if (null!=resultSet) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (null!=statement) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if (null!=connection) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
由于Druid内置提供了四种LogFilter(Log4jFilter、Log4j2Filter、CommonsLogFilter、Slf4jLogFilter),用于输出JDBC执行的日志。这些Filter都是Filter-Chain扩展机制中的Filter,在一开始已经配置了参数,指定使用log4j打印日志。
filters=log4j,wall,stat
但是在使用时,还需要引入log4j.jar包或者pom坐标,并准备好log4j.properties配置文件。
#默认error及其以上级别日志都会被记录下来
log4j.rootLogger=debug,stdout,logfile
#
#打印日志到控制台上
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
#
#通过文件记录日志
log4j.appender.logfile=org.apache.log4j.FileAppender
#日志文件路径
log4j.appender.logfile.File=d:/sys.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %F %p %m%n
上面提到Druid官网数据源初始化参数的例子显然是整合了spring框架的,很容易配置DruidDataSource数据源的销毁方法close(),但是在使用Servlet开发时,可能很容易忽略此项。然后,就可能导致Tomcat服务shutDown时,爆出如下内容:
如何解决?结合已有配置参数,猜想可能是因为没有做DruidDataSource数据源销毁的操作。既然官方配置文档提示了要使用close()方法,那么就可以在ServletContext监听器实现类中的contextDestroyed()方法中,进行数据源的关闭操作。
@Override public void contextDestroyed(ServletContextEvent sce) { //ServletContext销毁方法 //销毁自定义的线程池对象 // destroyThreadPoolExector(sce); //释放驱动 //releaseDriverResources(); //释放Druid数据库连接池资源 releaseDruidSources(); //提示关闭服务器应用 System.out.println("Application shut-down..."); } /** * 释放数据库连接池资源 */ private void releaseDruidSources() { System.out.println("try closing the Druid-DataSource..."); AbandonedConnectionCleanupThread.checkedShutdown(); DruidDataSource druidDataSource = DruidUtil.getDruidDataSource(); druidDataSource.close(); System.out.println(druidDataSource); }
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。