搭建spring+springmvc+mybatis+maven项目(2)
搭建spring+springmvc+mybatis+maven项目(2)
在 搭建spring+springmvc+mybatis+maven项目(1) 中我们搭建了基本的maven环境,并且可以运行项目接着就开始配置spring,springmvc,mybatis等
1.首先目录结构如下
因为上次没有在model-web模块中添加对model-common的依赖,所以这次我们在model-web的pom文件中先添加一下对model-common的依赖
<dependencies>
<dependency>
<groupId>club.jiajiajia.model</groupId>
<artifactId>model-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
加入依赖以后,然后再在文件中加入以上配置文件,下边讨论一下各自的作用
1.1.web.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd">
<!-- 加载spring和mybatis的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 使用ContextLoaderListener初始化Spring容器 -->
<!--若没有指定其他参数,默认查找的配置文件位置是:/WEB-INF/applicationContext.xml -->
<listener>
<description>Spring容器加载监听器</description>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置springmvc核心控制器 -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<description>spring MVC 配置文件路径</description>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-mvc.xml</param-value>
</init-param>
<!-- 启动动优先级,越小越早加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Servlet访问的路径映射,所有的访问都必须经过调度用的前置控制器 -->
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--编码过滤器 -->
<filter>
<description>字符集过滤器</description>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<description>字符集编码</description>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<!-- 路径映射 -->
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 过滤静态资源 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.txt</url-pattern>
</servlet-mapping>
<!-- 负责将web应用根目录以webAppRootKey上下文参数指定的属性名添加到系统参数中 -->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>root</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.util.WebAppRootListener
</listener-class>
</listener>
<!-- 欢迎页面 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
web.xml中主要配置了一些springmvc的过滤器,核心控制器,监听等,和编码过滤器,过滤静态资源以及系统参数等
按照web.xml的配置以及加载顺序,首先加载applicationContext.xml文件
1.2.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 扫描service、去掉对controller的扫描 -->
<context:component-scan base-package="club.jiajiajia.model.*">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- jdbc配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- ========================================配置数据源========================================= -->
<!-- 3.配置C3P0数据源 destroy-method="close"-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--驱动类名 -->
<property name="driverClass" value="${mysql.driver}" />
<!-- url -->
<property name="jdbcUrl" value="${mysql.url}" />
<!-- 用户名 -->
<property name="user" value="${mysql.user}" />
<!-- 密码 -->
<property name="password" value="${mysql.password}" />
<!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 -->
<property name="acquireIncrement" value="${mysql.acquireIncrement}"></property>
<!-- 初始连接池大小 -->
<property name="initialPoolSize" value="${mysql.initialPoolSize}"></property>
<!-- 连接池中连接最小个数 -->
<property name="minPoolSize" value="${mysql.minPoolSize}"></property>
<!-- 连接池中连接最大个数 -->
<property name="maxPoolSize" value="${mysql.maxPoolSize}"></property>
</bean>
<!-- ========================================针对myBatis的配置项============================== -->
<!-- 4.配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 实例化sqlSessionFactory时需要使用上述配置好的数据源以及SQL映射文件 -->
<!-- 数据源 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<property name="dataSource" ref="dataSource" />
<!-- sql映射文件路径 -->
<!-- 自动扫描com/demo/mapping/目录下的所有SQL映射的xml文件, 省掉Configuration.xml里的手工配置
value="classpath:com/demo/mapping/*.xml"指的是classpath(类路径)下com.demo.mapping包中的所有xml文件 -->
<property name="mapperLocations" value="classpath:club/jiajiajia/model/*/dao/*.xml" />
</bean>
<!-- 5.配置扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 扫描com.demo.dao这个包以及它的子包下的所有映射接口类 -->
<property name="basePackage" value="club.jiajiajia.model.*.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<!-- ========================================配置事务============================== -->
<!-- 6.声明式事务管理 -->
<!--定义事物管理器,由spring管理事务 -->
<bean name="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="add*" propagation="REQUIRED" />
<tx:method name="append*" propagation="REQUIRED" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="modify*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="repair" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="search*" propagation="REQUIRED" read-only="true" />
<tx:method name="datagrid*" propagation="REQUIRED" read-only="true" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- 配置aop -->
<aop:config>
<!-- 定义在club.jiajiajia.model包、以及子包下的service包和service的所有子包里的任意类的任意方法的执行 -->
<aop:pointcut id="transactionPointcut" expression="execution (* club.jiajiajia.model..service..*.*(..))" />
<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
</aop:config>
</beans>
applicationContext.xml配置文件中,主要的作用有->
1.加载service层的对象,并加入到ioc容器、
2.配置并加载c3p0数据源,以及配置和加载mybatis的相关容器、
3.配置事务管理器
其中用到了jdbc.properties文件,封装了数据库的一些链接信息
1.3.jdbc.properties
#local
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
mysql.user=root
mysql.password=******
mysql.acquireIncrement=5
mysql.initialPoolSize=10
mysql.minPoolSize=5
mysql.maxPoolSize=20
还用到了mybatis-config.xml文件,用与配置mybatis的其他的相关配置,比如给实体类其别名等
1.4.mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="club.jiajiajia.model.*.entity"/>
</typeAliases>
</configuration>
加载完 applicationContext.xml 文件以后就会加载applicationContext-mvc.xml配置文件,加载psringmvc的相关配置
1.5.applicationContext-mvc.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 静态资源的请求,转由Web应用服务器默认的Servlet处理 -->
<mvc:default-servlet-handler/>
<!-- 开启扫描注解 -->
<mvc:annotation-driven />
<!-- 扫描controller、并去掉对service的扫描、否则会对事务管理器产生毁灭性影响 -->
<context:component-scan base-package="club.jiajiajia.model.*">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
</context:component-scan>
<!-- springmvc上传文件配置 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="102400000"></property>
</bean>
<!-- 过滤静态资源 -->
<mvc:resources mapping="/resources/**" location="/resources/"/>
<mvc:resources mapping="/static/**" location="/static/"/>
<!-- 配置视图管理器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
applicationContext.xml文件的主要作用是
1.加载controller层中的对象,加入ioc容器,
2.进行springmvc上传文件的相关配置
3.过滤静态资源
4.配置视图管理器
最后log4j.properties文件配置日志信息
1.6.log4j.properties
log4j.logger.com.mchange.v2=ERROR
log4j.rootLogger=debug,stdout,DEBUG,INFO,WARN,ERROR
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%m%n
log4j.appender.DEBUG=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DEBUG.File=C:/logger/debug.log
log4j.appender.DEBUG.Append=true
log4j.appender.DEBUG.Threshold=DEBUG
log4j.appender.DEBUG.layout=org.apache.log4j.PatternLayout
log4j.appender.DEBUG.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
log4j.appender.DEBUG.filter.F1=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.DEBUG.filter.F1.LevelMin=DEBUG
log4j.appender.DEBUG.filter.F1.LevelMax=DEBUG
log4j.appender.INFO=org.apache.log4j.DailyRollingFileAppender
log4j.appender.INFO.File=C:/logger/info.log
log4j.appender.INFO.Append=true
log4j.appender.INFO.Threshold=INFO
log4j.appender.INFO.layout=org.apache.log4j.PatternLayout
log4j.appender.INFO.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
log4j.appender.INFO.filter.F1=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.INFO.filter.F1.LevelMin=INFO
log4j.appender.INFO.filter.F1.LevelMax=INFO
log4j.appender.WARN=org.apache.log4j.DailyRollingFileAppender
log4j.appender.WARN.File=C:/logger/warn.log
log4j.appender.WARN.Append=true
log4j.appender.WARN.Threshold=WARN
log4j.appender.WARN.layout=org.apache.log4j.PatternLayout
log4j.appender.WARN.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
log4j.appender.WARN.filter.F1=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.WARN.filter.F1.LevelMin=WARN
log4j.appender.WARN.filter.F1.LevelMax=WARN
log4j.appender.ERROR=org.apache.log4j.DailyRollingFileAppender
log4j.appender.ERROR.File=C:/logger/error.log
log4j.appender.ERROR.Append=true
log4j.appender.ERROR.Threshold=ERROR
log4j.appender.ERROR.layout=org.apache.log4j.PatternLayout
log4j.appender.ERROR.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
log4j.appender.ERROR.filter.F1=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.ERROR.filter.F1.LevelMin=ERROR
log4j.appender.ERROR.filter.F1.LevelMax=ERROR
这些配置文件配置完毕以后,启动项目
2.接下来进行全面测试阶段
为了方便加入了一个类封装所有的返回结果如下
package club.jiajiajia.model.common.util;
import java.io.Serializable;
/***
* 封装返回的数据
* @author LENOVO
*/
public class MyAjaxResult implements Serializable{
private static final long serialVersionUID = 1L;
private String msg;
private Object data;
// 200成功,300异常,500严重错误
private Integer code;
public MyAjaxResult() {
}
public MyAjaxResult(String msg, Object data, Integer Code) {
this.msg = msg;
this.data = data;
this.code = Code;
}
public static MyAjaxResult success(Object data){
return new MyAjaxResult("成功",data, 200);
}
public static MyAjaxResult success(Object data, String msg){
return new MyAjaxResult(msg, data,200);
}
public static MyAjaxResult success(String msg){
return new MyAjaxResult(msg, null,200);
}
public static MyAjaxResult fail_500(String msg){
return new MyAjaxResult(msg, null,500);
}
public static MyAjaxResult fail_300(String msg){
return new MyAjaxResult(msg, null,300);
}
public String getMsg() {
return msg;
}
public Object getData() {
return data;
}
public Integer getCode() {
return code;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setData(Object data) {
this.data = data;
}
public void setStatus(Integer Code) {
this.code = Code;
}
}
2.1.日志测试
package club.jiajiajia.model.common.controller;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import club.jiajiajia.model.common.util.MyAjaxResult;
@Controller
@RequestMapping("/test")
public class Test {
Logger l=Logger.getLogger(Test.class);
/**
* 测试日志
* @return
*/
@RequestMapping("/logger")
@ResponseBody
public MyAjaxResult re() {
l.debug("debug");
l.info("info");
l.warn("warn");
l.error("error");
return MyAjaxResult.success("ok");
}
}
访问路径:http://localhost/model-web/test/logger
控制台打印,说明springmvc配置ok
再看日志文件也是ok
2.2.视图管理器测试
@RequestMapping("/index")
public String index() {
return "index";
}
访问:http://localhost/model-web/test/index
成功跳转页面,ok
2.3.事务管理器测试
目录结构:
实体类
package club.jiajiajia.model.common.entity;
public class Users {
public Users(String username, String password, String email, String sex) {
super();
this.username = username;
this.password = password;
this.email = email;
this.sex = sex;
}
private Integer id;
private String username;
public Users() {
super();
// TODO Auto-generated constructor stub
}
public Users(Integer id, String username) {
super();
this.id = id;
this.username = username;
}
private String password;
private String email;
private String sex;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
controller层
@Autowired
private UserService userService;
@RequestMapping("/test")
@ResponseBody
public MyAjaxResult test() {
try {
userService.adduser(new Users("username","password","email","sex"),
new Users("username2","password2","email2","sex2"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return MyAjaxResult.fail_300("error");
}
return MyAjaxResult.success("ok");
}
service
package club.jiajiajia.model.common.service;
import club.jiajiajia.model.common.entity.Users;
public interface UserService {
public void adduser(Users u,Users u2);
}
serviceimpl
package club.jiajiajia.model.common.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import club.jiajiajia.model.common.dao.UserMapper;
import club.jiajiajia.model.common.entity.Users;
import club.jiajiajia.model.common.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public void adduser(Users u,Users u2) {
// TODO Auto-generated method stub
userMapper.adduser(u);
userMapper.adduser(u2);
}
}
mapper
package club.jiajiajia.model.common.dao;
import club.jiajiajia.model.common.entity.Users;
public interface UserMapper {
public int adduser(Users u);
}
<?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" >
<mapper namespace="club.jiajiajia.model.common.dao.UserMapper" >
<insert id="adduser" parameterType="club.jiajiajia.model.common.entity.Users">
INSERT INTO users(id,username,password,email,sex) VALUES(#{id},#{username},#{password},#{email},#{sex});
</insert>
</mapper>
运行:执行 http://localhost/model-web/test/test
执行成功
{"msg":"ok","data":null,"code":200}
然后把数据清空
修改UserServiceImpl,人为制造异常 int a=1/0
package club.jiajiajia.model.common.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import club.jiajiajia.model.common.dao.UserMapper;
import club.jiajiajia.model.common.entity.Users;
import club.jiajiajia.model.common.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public void adduser(Users u,Users u2) {
// TODO Auto-generated method stub
userMapper.adduser(u);
int a=1/0;
userMapper.adduser(u2);
}
}
如果没有事务管理器,第一个addUser(u)会执行成功,并且插入一条数据,如果事务管理器配置成功以后,数据库中应该不会有数据(回滚)。
重启项目以后 执行 http://localhost/model-web/test/test
执行结果:
{"msg":"error","data":null,"code":300}
后台会报异常
刷新数据库后发现数据库中没有数据
成功回滚
事务管理器测试也是ok的
测试完毕
项目的基本配置完成