1.项目截图
2 整合Log4j
1 编写lo g4j属性文件
可以参考官方网站,也可以直接中网上下载后进行修改
log4j.properties文件
#log4j.rootLogger=DEBUG,CONSOLE,DATABASE,FILE
log4j.rootLogger=DEBUG,CONSOLE,FILE
log4j.addivity.org.apache=true
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=INFO,ERROR、WARN、INFO、DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.Encoding=GBK
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://192.168.7.103:3306/mysql?useUnicode=true&characterEncoding=UTF-8
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=abc@123
log4j.appender.DATABASE.Threshold=INFO,ERROR、WARN、INFO、DEBUG
log4j.appender.DATABASE.sql=INSERT INTO LOG4J(stamp,thread, infolevel,class,messages) VALUES ('%d{yyyy-MM-dd HH:mm:ss}', '%t', '%p', '%l', '%m')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=/Users/mark_lic/apps/tomcat/apache-tomcat-7.0.81/logs/SpringMVC
log4j.appender.A1.Encoding=GBK
log4j.appender.A1.Threshold=INFO,ERROR、WARN、INFO、DEBUG
log4j.appender.A1.DatePattern='.'yyyy-MM-dd
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L : %m%n
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=/Users/mark_lic/apps/tomcat/apache-tomcat-7.0.81/logs/SpringMVC/file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.Encoding=GBK
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=INFO,ERROR、WARN、INFO、DEBUG
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.CONSOLE_FILE.Encoding=GBK
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=INFO,ERROR、WARN、INFO、DEBUG
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# File 输出 一天一个文件,输出路径可以定制,一般在根路径下
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=log.txt
log4j.appender.R.MaxFileSize=500KB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n
3.整合Myibatis
1编写Myibatis属性文件
该属性文件(myibatis.properties)中的属性配置取决你选择的数据库连接池,这里选择的是druid
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.31.168:3306/mysql?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=abc@123
jdbc.initialSize=2
jdbc.maxActive=10
jdbc.minIdle=0
jdbc.maxWait=60000
jdbc.validationQuery=SELECT 1
jdbc.testOnBorrow=true
jdbc.testOnReturn=true
jdbc.testWhileIdle=true
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=25200000
jdbc.removeAbandoned=true
jdbc.removeAbandonedTimeout=1800
jdbc.logAbandoned=true
jdbc.poolPreparedStatements=false
jdbc.maxPoolPreparedStatementPerConnectionSize=20
jdbc.filters=stat,wall,log4j
jdbc.defaultAutoCommit=true
2 配置数据源以及事务
myibatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!-- 引入配置文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:myibatis/myibatis.properties" />
</bean>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" init-method="init">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 初始化连接大小 -->
<property name="initialSize" value="${jdbc.initialSize}" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="${jdbc.maxActive}" />
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${jdbc.minIdle}" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${jdbc.maxWait}" />
<!-- 用来验证数据库连接的查询语句,这个查询语句必须是至少返回一条数据的SELECT语句 -->
<property name="validationQuery" value="${jdbc.validationQuery}"></property>
<!-- 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个.建议设置为true
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串 -->
<property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
<!-- 指明是否在归还到池中前进行检验,建议设置为true
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串 -->
<property name="testOnReturn" value="${jdbc.testOnReturn}" />
<!-- 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.建议设置为true
注意: 设置为true后如果要生效,validationQuery参数必须设置为非空字符串 -->
<property name="testWhileIdle" value="${jdbc.testWhileIdle}" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位.如果设置为非正数,则不运行空闲连接回收器线程-->
<property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒.连接在池中保持空闲而不被空闲连接回收器线程
(如果有)回收的最小时间值,单位毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />
<!-- 打开removeAbandoned功能 标记是否删除泄露的连接,如果他们超过了removeAbandonedTimout的限制.
如果设置为true, 连接被认为是被泄露并且可以被删除时,关闭数据库连接
false:如果空闲时间超过removeAbandonedTimeout. 关闭数据库连接
设置为true可以为写法糟糕的没有关闭连接的程序修复数据库连接.-->
<property name="removeAbandoned" value="${jdbc.removeAbandoned}" />
<!-- 泄露的连接可以被删除的超时值, 单位秒.1800秒,也就是30分钟 -->
<property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}" />
<!-- 关闭abanded连接时输出错误日志 当Statement或连接被泄露时是否打印程序的stack traces日志。
被泄露的Statements和连接的日志添加在每个连接打开或者生成新的Statement,因为需要生成stack trace-->
<property name="logAbandoned" value="${jdbc.logAbandoned}" />
<!-- 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。 -->
<property name="poolPreparedStatements" value="${jdbc.poolPreparedStatements}" />
<!-- 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true
在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100 -->
<property name="maxPoolPreparedStatementPerConnectionSize" value="${jdbc.maxPoolPreparedStatementPerConnectionSize}" />
<!-- 这里配置提交方式,默认就是TRUE,可以不用配置 -->
<property name="defaultAutoCommit" value="${jdbc.defaultAutoCommit}" />
<!-- 监控数据库 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:
监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall-->
<property name="filters" value="${jdbc.filters}" />
<!--
如果配置了proxyFilters,此配置可以不配置
druid.stat.mergeSql=true 合并执行的相同sql,避免因为参数不同而统计多条sql语句
druid.stat.slowSqlMillis=10000 用来配置SQL慢的标准,执行时间超过slowSqlMillis的就是慢 -->
<property name="connectionProperties" value="druid.stat.mergeSql=true;druid.stat.slowSqlMillis=10000" />
<property name="proxyFilters">
<list>
<ref bean="stat-filter" />
<ref bean="log-filter" />
</list>
</property>
</bean>
<!-- 慢SQL记录-->
<bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">
<property name="mergeSql" value="true" />
<property name="slowSqlMillis" value="10000" />
<property name="logSlowSql" value="true" />
</bean>
<bean id="log-filter" class="com.alibaba.druid.filter.logging.Log4jFilter">
<property name="resultSetLogEnabled" value="false" />
<property name="statementExecutableSqlLogEnable" value="true" />
</bean>
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath*:com/mark/blog/mapping/*.xml"></property>
</bean>
<!-- DAO接口所在包名,Spring会自动查找其下的类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mark.dao.impl" />
<!--该处采用的是byname注入SessionFactory,不涉及对象的创建
避免properties属性没有替换时,创建sqlSessionFactory
即避免dataSource中url,username等属性 not found-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
<!-- 配置druid监控spring jdbc -->
<bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor" />
<bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="patterns">
<list>
<value>com.mark.blog.service.impl.*</value>
<value>com.mark.blog.dao.impl.*</value>
</list>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 事务传播特性配置 -->
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="query*" read-only="true" />
</tx:attributes>
</tx:advice>
<!-- 配置拦截service -->
<aop:config>
<aop:advisor advice-ref="transactionAdvice" pointcut="execution(* com.mark.blog.*impl.*.*(..))"/>
</aop:config>
</beans>
3 整合Myibatis和druid
druid wiki:https://github.com/alibaba/druid/wiki
需要在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">
<!--welcome pages-->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Spring和mybatis的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:myibatis/myibatis-config.xml</param-value>
</context-param>
<!-- druid -->
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<!-- 用户名 -->
<param-name>loginUsername</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<!-- 密码 -->
<param-name>loginPassword</param-name>
<param-value>admin</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
</web-app>
4 整合Spring Component
该步骤主要是扫描package下Spring conponent(Service,controller,dao)配置文件applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--启用spring的一些annotation -->
<context:annotation-config/>
<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
<context:component-scan base-package="com.mark">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<context:component-scan base-package="com.mark">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
<context:component-scan base-package="com.mark">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>
<!--HandlerMapping 无需配置,springmvc可以默认启动-->
<!--静态资源映射-->
<!--本项目把静态资源放在了WEB-INF的statics目录下,资源映射如下-->
<mvc:resources mapping="/css/**" location="/statics/css/"/>
<mvc:resources mapping="/js/**" location="/statics/js/"/>
<mvc:resources mapping="/image/**" location="/statics/image/"/>
<!-- 配置注解驱动 可以将request参数与绑定到controller参数上 -->
<mvc:annotation-driven/>
<!-- 对模型视图名称的解析,即在模型视图名称添加前后缀(如果最后一个还是表示文件夹,则最后的斜杠不要漏了) 使用JSP-->
<!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用html)- -->
<bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/views/"/><!--设置JSP文件的目录位置-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
5 编写myibatis sqlmap xml
编写符合业务的sql(UserMapping.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace:必须与对应的接口全类名一致
id:必须与对应接口的某个对应的方法名一致
-->
<mapper namespace="com.mark.blog.entity.User">
<select id="getAllUser" resultType="com.mark.blog.entity.User">
select host,Db from db where Db = 'sys'
</select>
</mapper>
6 编写各层实现逻辑
实体类(entity)
public class User {
private String host;
private String db;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getDb() {
return db;
}
public void setDb(String db) {
this.db = db;
}
@Override
public String toString() {
return "HOST: " + this.host + "DB: " + this.db;
}
}
Controller
@Controller
@RequestMapping(value = "/")
public class HelloController {
private final static Log logger = LogFactory.getLog(HelloController.class);
@Resource
private IUserService userService;
@RequestMapping(value = "hello.do")
public String handlerHello() {
logger.debug("Hello World" + userService.queryUser());
return "hello";
}
}
Service
public interface IUserService {
public User queryUser();
}
@Service(value = "userService")
public class UserServiceImpl implements IUserService {
@Resource
private IUserDao userDao;
public User queryUser() {
return userDao.queryUser();
}
}
DAO
BaseDao引入理由:
1.异常信息:
2.mybatis-spring-1.1.1没有问题,但是采用mybatis-spring-1.2.0+
运行出错:Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
从SqlSessionDaoSupport 这个类的源码中可以看出,原因是mybatis-spring-1.2.0+
中取消了自动注入SqlSessionFactory 和 SqlSessionTemplate
解决方案:因为我们dao层是继承于一个dao基类,所以只要在这个基类中注入任意一个属性即可。SqlSessionFactory在spring配置文件中已经配置。
public class BaseDao extends SqlSessionDaoSupport {
@Resource
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory){
super.setSqlSessionFactory(sqlSessionFactory);
}
}
public interface IUserDao {
public User queryUser();
}
@Repository(value = "userDao")
public class UserDaoImpl extends BaseDao implements IUserDao {
public User queryUser() {
return getSqlSession().selectOne("getAllUser");
}
}
7 编写JSP页面
<html>
<body>
<h2>Hello World!</h2>
<form method="get" action="hello.do">
<input type="submit" value="Submit"/>
</form>
</body>
</html>
8.测试是否OK
1 查看日志
启动tomcat查看日志
...... DEBUG com.mark.blog.controller.HelloController - Hello WorldHOST: localhostDB: sys
2.查看Druid
在浏览器中输入http://IP:Port/druid/weburi.html