项目重构之数据源配置与优化:log4j 配置数据库连接池Druid,并实现日志存储到数据库
作者:泥沙砖瓦浆木匠
网站:http://blog.csdn.net/jeffli1993
个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节。
交流QQ群:【编程之美 365234583】http://qm.qq.com/cgi-bin/qm/qr?k=FhFAoaWwjP29_AonqzL0rpdQAjjqlHQQ
如果我的帮到了你,是否乐意捐助一下或请一杯啤酒也好呢?有你支持,干的更好~
点这参与众筹 我的支付宝:13958686678
一、 前言
泥瓦匠又和大家见面了,最近两天我在Code Review ,顺便代码小小的Refactoring(重构)下。先了解这个项目吧,这次解决的是数据源配置优化。因为这web项目中配置数据源的地方很多。例如JDBC要配置数据源,Mybatis要配置数据源,Quartz定时任务要配置数据源,还有Log4j存记录到数据库也要配置…
如题目,兴许大家的疑惑看了前面的说明会明白。这次给大家带来的 数据源配置与优化:log4j 配置数据库连接池Druid。
提纲:
- 二、准备知识
- 三、正文 开始动手吧
- 、配置文件
- 、建数据表
- 、核心代码讲解
- 四、结论及下载
二、准备知识
泥瓦匠也是怕自己说不清楚,又不想把Log4j 和 Durid介绍个遍。那样会太麻烦。这次主要是项目实战。所以泥瓦匠也不罗嗦知识准备这块也就是点到为止。
Log4j 简介
在应用程序中添加日志记录总的来说基于三个目的:
监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作;
跟踪代码运行时轨迹,作为日后审计的依据;
担当集成开发环境中的调试器的作用,向文件或控制台打印代码的调试信息。
它支持将日志信息输入到数据库,这次我们一Mysql为例说明。我们需要Log4j来将调试信息、操作信息等记录下来,以便后面的审计,这些日志信息包括用户ID、用户姓名、操作类、路径、方法、操作时间、日志信息。
Druid 简介
Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。不多多介绍了,阿里牛人作品必须精品。详细介绍在:https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
泥瓦匠的任务很简单,目的是为了数据源配置优化,实现数据源配置的唯一性。泥瓦匠也画了草图,曾经被人说成画图画出鬼画符的我告诉大家:没事,越做越好。如图,设计简单草图就是这样的。
结论:一个项目的配置文件要保持唯一性,就是数据源配置的唯一性。
三、正文 开始动手吧
开始弄吧,为了写这个东西。我就也搞了个demo项目。泥瓦匠很辛苦的,哈哈送钱的上面支付宝哦。哈哈,泡了杯水,准备说这个项目了。下面,泥瓦匠先给出这个项目的结构图,这样我待会讲起来不怎么累。逻辑性比较强吧。如图:
上面很清楚的写着我需要完成的功能模块。最后那个test,是一个测试的servlet类。大家一看就明白。我先从配置文件说起吧。
配置文件 :
dbConfig.properties 记录的是最基础的db配置:url name psd 等,代码如下:
- database.vendor = mysql
- db_url = jdbc:mysql://localhost:3307/test
- driverClassName= com.mysql.jdbc.Driver
- db_user = root
- db_password = 123456
- showsql= false
- devMode = true
- validationQuery=SELECT 1
log4j.properties则是日志的配置,但日志的配置中有一点注意的是如下:
- log4j.rootLogger=debug,appender1
- log4j.appender.appender1=org.apache.log4j.ConsoleAppender
- log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout
- log4j.logger.test=INFO, db
- # log db setting
- log4j.appender.db=org.nsg.dbsetting.MyJDBCAppender
- log4j.appender.db.BufferSize=1
- log4j.appender.db.sql=insert into operate_log(handclass,method,createtime,loglevel,logmsg) values ('%C','%M','%d{yyyy-MM-dd HH\:mm\:ss}','%p','%m')
- log4j.appender.db.layout=org.apache.log4j.PatternLayout
在这里,我们要注意两点:
一、设置我们包的下的logger权限,并给予存数据库的权限。
二、db的实现的应用要为你写的引用类。
- # log db setting
- log4j.appender.db=org.nsg.dbsetting.MyJDBCAppender
建数据表 :
然后我们要根据上面配置文件中写的数据库和表格我们要对应的建一个名为test的数据库和一张名为operate_log的表。
- /*
- Navicat MySQL Data Transfer
- Source Server : Mysql
- Source Server Version : 50617
- Source Host : localhost:3307
- Source Database : test
- Target Server Type : MYSQL
- Target Server Version : 50617
- File Encoding : 65001
- Date: 2014-12-08 18:46:21
- */
- SET FOREIGN_KEY_CHECKS=0;
- -- ----------------------------
- -- Table structure for operate_log
- -- ----------------------------
- DROP TABLE IF EXISTS `operate_log`;
- CREATE TABLE `operate_log` (
- `log_id` int(11) NOT NULL AUTO_INCREMENT,
- `handclass` varchar(100) DEFAULT NULL,
- `method` varchar(100) DEFAULT NULL,
- `createtime` varchar(100) DEFAULT NULL,
- `loglevel` varchar(20) DEFAULT NULL,
- `logmsg` text,
- PRIMARY KEY (`log_id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;
这样我们就可以开始写代码了,泥瓦匠是一个很细节的人。这次博客,我主要是讲下代码中的核心点。因为后面我会把项目提供给你们下载。所以,这里点到为止。
泥瓦匠说:点到为止,所谓师父领进门,修行在个人啊。
核心代码讲解:
MyJDBCAppender.java 用于Log4j的数据库Session管理[连接池用Druid]。这个肯定是我们得核心思想。这里我就继承了log4j提供的org.apache.log4j.jdbc.JDBCAppender;然后只要简单的重写了closeConnection和getConnection方法。如果获取Druid数据库源对象异常的话,我还写了个 取消初始化 的方法uninitialize。代码这边也贴出下,方便大家观看:
- package org.nsg.dbsetting;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.util.Properties;
- import org.apache.log4j.jdbc.JDBCAppender;
- import org.apache.log4j.spi.ErrorCode;
- import org.nsg.constant.PropertiesConst;
- import org.nsg.exception.JdbcException;
- import org.nsg.util.MyProperties;
- import org.nsg.util.PropertiesUtil;
- import com.alibaba.druid.pool.DruidDataSource;
- import com.alibaba.druid.pool.DruidDataSourceFactory;
- /**
- * @Description MyJDBCAppender.java
- * 用于Log4j的数据库Session管理[连接池用Druid]
- * @author 泥沙砖瓦浆木匠
- * @date 2014年12月7日下午1:50:56
- * @version 1.0
- */
- public class MyJDBCAppender extends JDBCAppender
- {
- /* Druid数据源 */
- private DruidDataSource dataSource;
- public MyJDBCAppender()
- {
- super();
- }
- @Override
- protected void closeConnection(Connection con)
- {
- try
- {
- /* 如果数据库连接对象不为空和没有被关闭的话,关闭数据库连接 */
- if ( con != null && !con.isClosed())
- con.close();
- }
- catch (SQLException e)
- {
- errorHandler.error("Error closing MyJDBCAppender.closeConnection() 's connection",e,ErrorCode.GENERIC_FAILURE);
- }
- }
- @Override
- protected Connection getConnection() throws SQLException
- {
- /* 获取数据库配置property */
- MyProperties properties = PropertiesUtil.loadPropertyFile(PropertiesConst.DB_CONFIG);
- String className = String.valueOf(properties.getProperty("driverClassName",""));
- String connUrl = String.valueOf(properties.getProperty("db_url",""));
- String uname = String.valueOf(properties.getProperty("db_user",""));
- String psw = String.valueOf(properties.getProperty("db_password",""));
- System.out.println(className);
- System.out.println(connUrl);
- System.out.println(uname);
- System.out.println(psw);
- Properties result = new Properties();
- result.put("driverClassName",className);
- result.put("url",connUrl);
- result.put("username",uname);
- result.put("password",psw);
- /* 其他配置 自然你也可以自己写property 然后获取set */
- result.put("maxActive","30");
- result.put("minIdle","3");
- try
- {
- dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(result);
- }
- catch (Exception e)
- {
- /* Druid数据库源对象产生失败后,取消初始化 */
- try {uninitialize();} catch(Exception e2) {}
- throw new JdbcException(e);
- }
- return dataSource.getConnection();
- }
- /* 取消初始化 */
- public void uninitialize()
- {
- try
- {
- if (dataSource != null)
- dataSource.close();
- }
- catch (Exception e)
- {
- throw new JdbcException(String.format("MyJDBCAppender uninitialize fail (%s)",e));
- }
- finally
- {
- super.close();
- }
- }
- }
值得注意的一点是,泥瓦匠为了方便,所以在其中的地方没有获取druid连接池的配置。而是直接写了下面:
- /* 其他配置 自然你也可以自己写property 然后获取set */
- result.put("maxActive","30");
- result.put("minIdle","3");
其实这样写是不好了,我们可以写一个druid.properties然后将连接池的配置放入其中。获取set,for循环set即可。这边我就不实现了。很简单哦,泥瓦匠相信你们。
最后我演示下,示例代码:放到tomcat7上,然后运行访问
看到控制台刷出来两条信息,因为我门设置的是log4j.logger.test=INFO, db。
然后我们去查看数据库,这边我用Navicat:
四、结论及下载
结论:重构很有意思,慢慢来,一点一点来,就行了。细节成就未来。
下载链接:
http://pan.baidu.com/s/1hqKN0Le
如以上文章或链接对你有帮助的话,别忘了在文章按钮或到页面右下角点击 “赞一个” 按钮哦。你也可以点击页面右边“分享”悬浮按钮哦,让更多的人阅读这篇文章
项目重构之数据源配置与优化:log4j 配置数据库连接池Druid,并实现日志存储到数据库的更多相关文章
- spring配置数据库连接池druid
连接池原理 连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象.使用完毕后,用户也并非将连 ...
- 数据库连接池druid 监控台配置
这篇文章主要讲druid 监控台的配置及界面使用介绍. 业界把 Druid 和 HikariCP 做对比后,虽说 HikariCP 的性能比 Druid 高,但是因为 Druid 包括很多维度的统计和 ...
- 数据库连接池----Druid配置详解
什么是连接池? 数据库连接池出现的原因在数据库连接资源的低效管理,使用数据库连接池是基于设计模式中的资源池的概念,从而解决资源频繁是分配.释放所造成的问题. 数据库连接池的基本思想就是为数据库连接建立 ...
- 数据库连接池Druid的介绍,配置分析对比总结
Druid的简介 Druid首先是一个数据库连接池.Druid是目前最好的数据库连接池,在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.JBos ...
- [转]阿里巴巴数据库连接池 druid配置详解
一.背景 java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池.数据库连接池有很多选择,c3p.dhcp.proxool等,druid作为一名后起之秀,凭借其出色 ...
- 阿里巴巴数据库连接池 druid配置详解
一.背景 java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池.数据库连接池有很多选择,c3p.dhcp.proxool等,druid作为一名后起之秀,凭借其出色 ...
- 数据源与JNDI资源实现JSP数据库连接池实例
名词解释:JNDI的全称是java命名与目录接口(Java Naming and Directory Interface),是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通 ...
- spring配置datasource三种方式 数据库连接池
尊重原创(原文链接):http://blog.csdn.net/kunkun378263/article/details/8506355 1.使用org.springframework.jdbc.da ...
- log4j日志存储到数据库
一.前提条件 系统必须是使用LOG4J进行日志管理,否则方法无效. 系统必须包含commons-logging-xxx.jar,log4j-xxx.jar这两个JAR包,XXX为版本号. 二.操作步骤 ...
随机推荐
- hw1
如上面两个小程序中,分析下列问题: 1.Identify the fault. 2. If possible, identify a test case that does not execute t ...
- MySQL优化:使用show status查看MySQL服务器状态信息
在网站开发过程中,有些时候我们需要了解MySQL的服务器状态信息,譬如当前MySQL启动后的运行时间,当前MySQL的客户端会话连接数,当前MySQL服务器执行的慢查询数,当前MySQL执行了多少SE ...
- kbmmw 5.08 正式发布
欢迎大家围观. Important notes (changes that may break existing code) ============================= ...
- Python——教你画朵太阳花
用python中的turtle函数画个太阳花,有以下几个步骤 1.首先,我们在开始中找到Python语言的IDLE软件脚本 2.然后出现该软件界面,如图,点击上面的Eile 3.然后在 ...
- LAPM 相关实验01
目录 lab1 静态.动态资源的区别lab2 部署phpMyadminlab3 部署wordpresslab4 编译安装php-Xcache加速器lab5 fcgi实现lamp lab1 静态.动态资 ...
- Linux系统调用:进程的终止
之前总结了Linux的系统创建,主要是fork()函数和vfork()函数,最近总结了Linux进程的终止,主要的调用是_exit()和exit(). 先看看两个函数的原型以及各自属于的头文件,可以发 ...
- ajax提交数组至后台,无法获取值得问题
$(".delAll_btn").click(function(){ var checkStatus = table.checkStatus('userList'), data = ...
- 洛谷P1886--滑动窗口(单调队列模板)
https://www.luogu.org/problemnew/show/P1886 单调队列的操作上比普通队列多了可以从尾端出队 单调队列保持队内元素单调递增/递减,以保证队首元素为最小/最大元素 ...
- java面试问题收集(2)
1 Integer int相等问题 Integer对象和int比较的时候会有一个拆箱的过程,始终相等 Integer和new Integer对象不会相等,引用不同 两个Integer对象比较,Inte ...
- JS canvas 画板 撤销
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...