mybatis使用spring-druid数据源连接池配置log4j打印sql语句以及开启监控平台

杂七杂的杂

作为程序员,开发工程中,一套利于测试或者监控的工具很重要,mybatis默认没有提供log4j的打印sql语句的配置。

这对于开发rest服务,提供接口的开发者而言,是在很不好做,再加上mybatis很灵活,使用脚本动态生成sql语句,因此,有时候真不知道运行的sql是不是我们所期望的,过滤的条件是否起作用。

所幸,德鲁伊监控平台是个不错的选择,在性能方面druid连接池也比spring原生的要好,因此也是很多企业开发的首选数据源配置。

在引言阶段,我们先看看目前我配置的结果是否是你想要的,如果不是你所期望的,就别浪费时间往下面看,毕竟大家都时间有限,没必要花费时间看一些对自己没用的东西。

  • 控制台打印的日志,慎重的告诉你,这种大量打印信息不能用于生产坏境,生产环境中这些信息写到tomcat的日志文件中了{tomcat的目录}/logs/catalina.out,如果访问量很大的时候,一天产生几个GB的日志不是问题–慎用。

[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.Connection: {conn-10001} pool-connect
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.Statement: {conn-10001, pstmt-20025} created. 
select * from t_login_register_st  WHERE 1 = 1   and ltime >= ?  order by ltime desc limit ?, ?
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.Statement: {conn-10001, pstmt-20025} Parameters : [1463414400, 0, 15]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.Statement: {conn-10001, pstmt-20025} Types : [BIGINT, INTEGER, INTEGER]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.Statement: {conn-10001, pstmt-20025} executed. 6.503031 millis. 
select * from t_login_register_st  WHERE 1 = 1   and ltime >= ?  order by ltime desc limit ?, ?
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} open
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Header: [ltime, login_register, register, register_sent_code, register_edit, register_edit_publish, register_edit_succ, login, foget_passwd, foget_passwd_sent_code, login_succ, login_fail, login_succ_normal, login_succ_qq, login_succ_wx, login_succ_wb, login_succ_foget_passwd, login_fail_normal, login_fail_qq, login_fail_wx, login_fail_wb, login_fail_foget_passwd]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1464624000, 604, 216, 117, 113, 109, 106, 931, 59, 9, 790, 150, 279, 148, 254, 93, 32, 117, 9, 26, 2, 2]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1464537600, 639, 241, 132, 125, 121, 114, 998, 40, 11, 844, 130, 312, 168, 268, 87, 24, 107, 5, 18, 2, 2]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1464451200, 674, 322, 175, 170, 160, 155, 1087, 46, 11, 923, 143, 310, 164, 339, 96, 26, 114, 6, 25, 3, 1]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1464364800, 794, 371, 187, 182, 168, 162, 1330, 73, 17, 1153, 178, 307, 257, 455, 120, 34, 137, 11, 25, 6, 3]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1464278400, 670, 295, 169, 162, 154, 118, 1197, 88, 12, 977, 229, 338, 185, 320, 120, 33, 135, 33, 54, 25, 1]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1464192000, 709, 308, 172, 163, 159, 120, 1214, 56, 8, 1065, 292, 383, 196, 349, 122, 30, 148, 54, 78, 30, 1]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1464105600, 666, 285, 153, 148, 141, 139, 1120, 75, 14, 970, 159, 328, 188, 294, 141, 38, 132, 11, 14, 3, 0]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1464019200, 586, 254, 146, 141, 136, 132, 1018, 60, 12, 884, 132, 307, 149, 295, 124, 31, 108, 3, 18, 3, 2]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1463932800, 548, 209, 110, 106, 106, 103, 910, 68, 13, 779, 135, 306, 123, 251, 87, 33, 120, 4, 14, 1, 1]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1463846400, 520, 197, 104, 100, 99, 94, 963, 46, 12, 827, 132, 289, 149, 261, 110, 26, 110, 4, 13, 5, 1]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1463760000, 627, 237, 142, 134, 129, 122, 1190, 80, 23, 999, 173, 348, 182, 304, 137, 45, 137, 11, 22, 3, 2]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1463673600, 678, 280, 150, 144, 133, 128, 1235, 75, 8, 1012, 184, 354, 187, 342, 126, 28, 153, 14, 16, 6, 1]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1463587200, 564, 230, 138, 135, 131, 126, 1063, 53, 11, 901, 122, 337, 161, 274, 116, 27, 102, 3, 15, 3, 4]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1463500800, 552, 212, 119, 112, 108, 106, 986, 46, 6, 833, 134, 332, 146, 254, 92, 23, 122, 6, 5, 1, 2]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} Result: [1463414400, 665, 234, 130, 124, 125, 121, 1165, 65, 13, 979, 159, 409, 143, 303, 116, 33, 145, 4, 6, 3, 2]
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.ResultSet: {conn-10001, pstmt-20025, rs-50025} closed
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.Statement: {conn-10001, pstmt-20025} closed
[03/06/16 11:56:03:003 CST] http-nio-8080-exec-2 DEBUG sql.Connection: {conn-10001} pool-recycle
  • 德鲁伊监控平台的视图:

《mybatis使用spring-druid数据源连接池配置log4j打印sql语句以及开启监控平台》

图一 SQL监控

《mybatis使用spring-druid数据源连接池配置log4j打印sql语句以及开启监控平台》

图二 URI监控

重要的话,重复一遍,如果目前所写对现在的你没用,就算以后可能会用到,你也没必要细看下面所述,到此你已经花费了很多时间了,时间是金钱,伤不起。

如果你坚持要看到这里,请收藏吧!

spring加载properties键值对

其实与spring的配置基本没多大关系,但是因为其加载了数据库的基本信息,所以两个合在一起看一下。

spring-applicationContext.xml的部分配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/task
        http://www.springframework.org/schema/task/spring-task.xsd
        http://code.alibabatech.com/schema/dubbo
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
    ">

    <task:annotation-driven/>

    <context:annotation-config/>

    <context:component-scan base-package="cn.test.*"/>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
        <property name="ignoreResourceNotFound" value="true"/>
        <property name="locations">
            <list>
                <!-- 越靠后越有效,取到最后一个有效的未知 -->
                <value>classpath:conf/properties/*.properties</value>
            </list>
        </property>
    </bean>
</beans>

properties文件的部分配置:

mysql.host=127.0.0.1 #你的数据库主机
mysql.port=3306
mysql.database=test # 你的数据库
mysql.user=test # 数据库登录用户
mysql.pwd=123456 # 数据库登录密码

mybatis.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <!-- 开启事务注解驱动,管理事务-->
    <tx:annotation-driven transaction-manager="txManager"/>

    <!-- 在dao层可以使用@Trantional注解管理事务,spring会将注解了事务的类中的所有操作视为事务来管理 -->
    <bean id="txManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"/>
    </bean>

    <!-- ******前面的这些都是今天的重点,下面是重点的开始,我们配置的数据源是德鲁伊druid数据源,这个才是重点****** -->
    <!-- ========================================================-->
    <!-- 使用druid作为数据源连接池-->
    <bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource"
          init-method="init" destroy-method="close" >
          <!-- 数据库的配置,host:主机名,port:端口,database:数据库 -->
        <property name="url" value="jdbc:mysql://${mysql.host}:${mysql.port}/${mysql.database}?characterEncoding=utf8" />
        <!-- 连接数据的用户名-->
        <property name="username" value="${mysql.user}" />
        <!-- 连接数据库的密码-->
        <property name="password" value="${mysql.pwd}" />
        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="1" />
        <property name="minIdle" value="1" />
        <property name="maxActive" value="20" />

        <!-- 配置获取连接等待超时的时间 -->
        <property name="maxWait" value="30000" />

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="60000" />

        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="300000" />

        <property name="testWhileIdle" value="true" />

        <!-- 这里建议配置为TRUE,防止取到的连接不可用 -->
        <property name="testOnBorrow" value="true" />
        <property name="testOnReturn" value="false" />

        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
        <property name="poolPreparedStatements" value="false" />

        <!-- 验证连接有效与否的SQL,不同的数据配置不同 -->
        <property name="validationQuery" value="select 1 " />

        <!-- ******重要的配置:监控统计拦截的filters,日志记录 *start* ******-->
        <!-- 并在filters属性中配置了log4j,ref中的bean是下面拦截器的配置 -->
        <!-- proxyFilters和filters是组合关系,前者是根据bean配置,后者根据别名配置的-->
        <!-- stat是statfilter的别名,log4j是logFilter的别名-->
        <!-- 监控统计拦截的filters,日志记录,这里开启了stat,wall(sql翻过墙过滤监控),log4j(log4j的监控)配置 -->
        <property name="proxyFilters">
            <list>
                <ref bean="statfilter" />
                <ref bean="logFilter" />
            </list>
        </property>
        <property name="filters" value="wall" />
        <!--  *end* -->
    </bean>

    <!-- 慢SQL记录 *start* -->
    <bean id="statfilter" class="com.alibaba.druid.filter.stat.StatFilter">
        <!-- 开启合并sql -->
        <property name="mergeSql" value="true" />
        <!-- 开启慢查询语句,1秒 -->
        <property name="slowSqlMillis" value="1000" />
        <property name="logSlowSql" value="true" />
    </bean>

    <bean id="logFilter" class="com.alibaba.druid.filter.logging.Log4jFilter">
        <!-- <property name="resultSetLogEnabled" value="false" /> -->
        <!-- <property name="statementExecutableSqlLogEnable" value="true" /> -->
    </bean>
    <!-- 慢SQL记录  *end* -->
    <!-- ========================================================-->
    
    <!-- 事务增强,这里用的是spring提供的特性-->
    <tx:advice id="advice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="select*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="has*" read-only="true"/>
            <tx:method name="count*" read-only="true"/>
            <tx:method name="search*" read-only="true"/>
        </tx:attributes>
    </tx:advice>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource">
            <ref local="datasource"/>
        </property>
    </bean>

    <!-- Session Factory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource"/>
        <!-- 下面configLocation这一句是myabtis的其它配置,比如字段值为null的时候,该字段就不返回了,在实际应用中,如果没有其它配置,可以删掉了-->
        <property name="configLocation" value="classpath:META-INF/spring/configuration.xml"/>
        <!--<property name="mapperLocations" value="classpath:mapper/*mapper.xml"/>-->
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
        <property name="basePackage" value="cn.test.web.mapper"/>
    </bean>
</beans>

上面的配置中,使用<!-- ====== -->包裹的部分时今天配置的重点,其它的配置时开发中的基本配置,也就是说基本的必须配置,不配置不能使用到spring提供的一些特性,当然数据源是必须的配置,但是可以选择spring的数据源连接,不一定是德鲁伊的数据源连接池。

对于配种中看到的<!-- ****** --> 注释的部分更是本文讲的重点,也就是要让程序在控制台打印mybatis的sql语句,这些配置很重要。

<property name="proxyFilters">
    <list>
        <ref bean="statfilter" />
        <ref bean="logFilter" />
    </list>
</property>

这里是以代理模式过滤stat和log的,所以用的两个bean分别是stat监控,log日志记录监控。

<property name="filters" value="stat,wall,log4j" />

这句的配置才是在控制台打印sql的重点,建议平时开发中,打开该配置,上线的时候关闭掉,原因就是上面提到的,写日志很占空间。

关于druid数据源配置属性的列表,请查看后面:druid连接池配置属性列表详解

web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:META-INF/spring/*.xml</param-value>
    </context-param>
    
    <!-- 初始化参数,引入log4j配置-->
    <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>WEB-INF/classes/log4j.xml</param-value>
    </context-param>

    <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>60000</param-value>
    </context-param>

    <!-- 开启德鲁伊stat过滤,WebStatFilter用于采集web-jdbc关联监控的数据,注意放在其它的过滤器以及dispatcher前面,很重哦 -->
    <filter>
        <filter-name>DruidWebStatFilter</filter-name>
        <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
        <init-param>
            <param-name>exclusions</param-name>
            <param-value>/static/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
        </init-param>
        <!-- 下面的所有的init-param可以不用配置,使用默认值即可,如果你有处女座情结,删除即可 -->
        <!-- 缺省sessionStatMaxCount是1000个。你可以按需要进行配置 -->
        <init-param>
            <param-name>sessionStatMaxCount</param-name>
            <param-value>1000</param-value>
        </init-param>
        <!-- druid 0.2.7版本开始支持profile,配置profileEnable能够监控单个url调用的sql列表 -->
        <init-param>
            <param-name>profileEnable</param-name>
            <param-value>true</param-value>
        </init-param>
        <!--
        <init-param>
            <param-name>principalSessionName</param-name>
            <param-value>users.username</param-value>
        </init-param> -->
        
        <!-- 你可以关闭session统计功能 -->
        <!-- 
        <init-param>
            <param-name>sessionStatEnable</param-name>
            <param-value>true</param-value>
        </init-param> -->
    </filter>
    <filter-mapping>
        <filter-name>DruidWebStatFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--this listener must be defined before the spring listener-->
    <listener>
        <listener-class>com.alibaba.dubbo.remoting.http.servlet.BootstrapListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- log4j监听器 -->
    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

    <!-- 德鲁伊监控平台监控器 -->
    <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>
</web-app>

上面加了注解的配置,是本文配置的重点,其它配置不在这里讲解。

<!– 开启德鲁伊stat过滤,WebStatFilter用于采集web-jdbc关联监控的数据–>

<filter>
    <filter-name>DruidWebStatFilter</filter-name>
    <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
    <init-param>
        <param-name>exclusions</param-name>
        <param-value>/static/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>DruidWebStatFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

druid对除了静态资源外底所有路由进行监控,该监控采集web-jdbc关联监控的数据。而前面对数据源监控的配置,大部分是sql监控。

<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>

如果你不希望别人直接查看你的监控,请把查看权限配置加上。如果监控平台被一些不安分的家伙知道,网站面临攻击的可能性就很大,安全性不靠保障,所以建议配置账户信息。

过滤器中的配置,是用来定义我们的监控选项,在以上的监控配置中,上面这段xml代码配置了一个最简单的监控,并采用了大量的默认配置,如果你想使用更丰富的监控配置,可以在druid的github wiki上获取更多的选项,地址:druid Filter 配置

<!– 德鲁伊监控平台监控器 –>

<servlet>
    <servlet-name>DruidStatView</servlet-name>
    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>DruidStatView</servlet-name>
    <url-pattern>/druid/*</url-pattern>
</servlet-mapping>

这个是德鲁伊监控平台提供的servlet web服务,启动服务器后,只需要在浏览器中输入:http://127.0.0.1:8080/druid/即可访问引言里面的几个图。

注意,路由根据自己的情况写,如果你直接在idea中配置的,且idea中没有配置context path的话,可以不用项目名。如果配置了,就用配置的名字,比如配置为test,则应该访问http://127.0.0.1:8080/test/druid/

在eclipse中,需要跟项目名的。假如项目时test0,则应该是http://127.0.0.1:8080/test0/druid/。当然了,如果不是这样的话,聪明的你肯定会尝试几次其它形式的路由访问了。

当然还的注意端口号,我这里面默认用了8080,如果你是8090,就换吧。

重轴戏:log4j.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
    <!-- 注意这里的大小写,配置文件对大小写敏感,主要是后面对该name的引用 -->
    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="[%d{dd/MM/yy hh:mm:ss:sss z}] %t %5p %c{2}: %m%n"/>
        </layout>
    </appender>
    <appender name="rollingFile" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="logs/server.log"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="[%d{MMdd HH:mm:ss SSS\} %-5p] [%t] %c{3\} - %m%n"/>
        </layout>
    </appender>

    <!-- 配置mybatis打印sql语句 -->

<!-- 这是网上看别人说的,我尝试了,加与不加都没关系,有兴趣自己去尝试
    <category name="org.springframework" additivity="false">
        <priority value="DEBUG"/>
        <appender-ref ref="CONSOLE"/>
    </category>

    <category name="org.springframework.orm.ibatis3" additivity="false">
        <priority value="DEBUG"/>
        <appender-ref ref="CONSOLE"/>
    </category>

    <category name="org.apache.ibatis" additivity="false">
        <priority value="DEBUG"/>
        <appender-ref ref="CONSOLE"/>
    </category>

    <category name="java.sql" additivity="false">
        <priority value="DEBUG"/>
        <appender-ref ref="CONSOLE"/>
    </category>-->

    <!-- ++++++++++++++++++++++++ -->
    <!-- druid数据源配置打印日志 start-->
    <logger name="druid.sql">
        <level value="DEBUG"/>
    </logger>
    <logger name="druid.sql.DataSource">
        <level value="DEBUG"/>
    </logger>
    <logger name="druid.sql.Connection">
        <level value="DEBUG"/>
    </logger>
    <logger name="druid.sql.Statement">
        <level value="DEBUG"/>
    </logger>
    <logger name="druid.sql.ResultSet">
        <level value="DEBUG"/>
    </logger>
    <!-- druid数据源配置打印日志 end -->
    <!-- ++++++++++++++++++++++++ -->
    
    <!-- spring提供的数据源打印日志 -->
    <!--
    <logger name="com.springframework" additivity="true">
         <level value="DEBUG"/>
     </logger>
     <logger name="com.ibatis" additivity="true">
         <level value="DEBUG"/>
     </logger>

    <logger name="com.ibatis.common.jdbc.SimpleDataSource" additivity="true">
        <level value="DEBUG"/>
    </logger>
    <logger name="com.ibatis.common.jdbc.ScriptRunner" additivity="true">
        <level value="DEBUG"/>
    </logger>
    <logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate" additivity="true">
        <level value="DEBUG"/>
    </logger>
    <logger name="Java.sql.Connection" additivity="true">
        <level value="DEBUG"/>
    </logger>
    <logger name="java.sql.Statement" additivity="true">
        <level value="DEBUG"/>
    </logger>
    <logger name="java.sql.PreparedStatement" additivity="true">
        <level value="DEBUG"/>
    </logger>
    <logger name="java.sql.ResultSet" additivity="true">
        <level value="DEBUG"/>
    </logger>
    -->
    <root>
        <level value="INFO"/>
        <!-- 注意ref中的大小写,就是前面配置的appender的name -->
        <appender-ref ref="CONSOLE"/>
        <!--<appender-ref ref="rollingFile" />-->
    </root>
</log4j:configuration>

上面的配置看上去很杂,但是有用的配置用了<!-- ++++++++++++++++++++++++-->包裹起来了,其它的配置都是看网上的配置,有些对配置根本没有,有些事spring数据源监控sql的配置,对于德鲁伊,就包裹部分的足够了,说这句话,并不是让你放弃一些基本配置,基本配置永远不能缺少。

druid连接池配置属性列表详解

配置缺省值说明
name配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来。如果没有配置,将会生成一个名字,格式是:”DataSource-” + System.identityHashCode(this)
jdbcUrl连接数据库的url,不同数据库不一样。例如:mysql : jdbc:mysql://10.20.153.104:3306/druid2;oracle : jdbc:oracle:thin:@10.20.149.85:1521:ocnauto
username连接数据库的用户名
password连接数据库的密码。如果你不希望密码直接写在配置文件中,可以使用ConfigFilter。详细看这里:https://github.com/alibaba/dr…
driverClassName根据url自动识别这一项可配可不配,如果不配置druid会根据url自动识别dbType,然后选择相应的driverClassName
initialSize0初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
maxActive8最大连接池数量
maxIdle8已经不再使用,配置了也没效果
minIdle最小连接池数量
maxWait获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
poolPreparedStatementsfalse是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql5.5以下的版本中没有PSCache功能,建议关闭掉。5.5及以上版本有PSCache,建议开启。
maxOpenPreparedStatements-1要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
validationQuery用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
testOnBorrowtrue申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
testOnReturnfalse归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
testWhileIdlefalse建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。timeBetweenEvictionRunsMillis有两个含义:1) Destroy线程会检测连接的间隔时间 2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明
numTestsPerEvictionRun不再使用,一个DruidDataSource只支持一个EvictionRun
minEvictableIdleTimeMillis
connectionInitSqls物理连接初始化的时候执行的sql
exceptionSorter根据dbType自动识别当数据库抛出一些不可恢复的异常时,抛弃连接
filters属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:监控统计用的filter:stat; 日志用的filter:log4j;防御sql注入的filter:wall;合并sql的filter:mergeStat
proxyFilters类型是List<com.alibaba.druid.filter.Filter>,如果同时配置了filters和proxyFilters,是组合关系,并非替换关系

补充说明

前面说过,mybatis配置的时候,可以配置sqlSessionFactory的时候通过configLocation属性可以指定mybatis的一些额外配置。

这里分享一段数据库字段值为null时,不返回字段名,而我们希望的是不管值为什么,字段名都应该返回。配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL MAP Config 3.1//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="callSettersOnNulls" value="true"/>
        <setting name="logImpl" value="LOG4J" />
    </settings>
</configuration>
    原文作者:Joyven
    原文地址: https://segmentfault.com/a/1190000005642328
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞