基于注解和xml配置的SSM(Spring+SpringMVC+Mybatis)项目详细配置
本文内容纲要:
- 第一步、配置pom.xml- 第二步、dao层配置
- 第三步:service层配置
- 第四步:controller层配置
第一步、配置pom.xml
在一个ssm项目中,可能需要用到的依赖比较多,在这里先列举出来:
<!-- 属性配置 --><properties>
<!-- 设置项目的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 设置java的版本为1.8-->
<java.version>1.8</java.version>
<!-- 源码编译的版本为1.8-->
<maven.compiler.source>1.8</maven.compiler.source>
<!-- 目标字节码的版本为1.8-->
<maven.compiler.target>1.8</maven.compiler.target>
<!-- 指定编译器版本为1.8-->
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<!-- 依赖的版本号 -->
<spring.version>5.1.5.RELEASE</spring.version>
<junit.version>4.12</junit.version>
<mysql.version>5.1.47</mysql.version>
<mybatis.version>3.5.2</mybatis.version>
<mybatis.spring.version>2.0.3</mybatis.spring.version>
<druid.version>1.1.20</druid.version>
<project.version>1.0-SNAPSHOT</project.version>
<servlet.version>4.0.1</servlet.version>
<jackson.version>2.10.0</jackson.version>
<pagehelper.version>5.1.10</pagehelper.version>
<logback.version>1.2.3</logback.version>
</properties>
<!-- 添加依赖 -->
<dependencyManagement>
<dependencies>
<!-- 测试 -->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- mysql驱动 -->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- spring -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring jdbc -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- druid连接池 -->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- 事务管理 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- mybatis整合插件 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<!-- Jackson -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- servlet -->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<!-- 分页插件 -->
<!-- pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<!-- 日志框架 -->
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- 日志 -->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
</dependencyManagement>
第二步、dao层配置
在dao层中,主要就是配置连接池,mybatis和分页插件
1、创建包:
创建如下:
2、实现业务类:
City.java:
public class City { private String cityId;
private String cityName;
private String cityCode;
private String province;
}
CityDao.java:
public interface CityDao { /**
* 分页,获取城市信息
* @param pageNum 第几页(从0开始)
* @param pageSize 每页几条
* @return
*/
List<City> cityInfo(@Param("pageNum") Integer pageNum, @Param("pageSize") Integer pageSize);
/**
* 获取指定城市信息
* @param cityId 城市id
* @return
*/
City getCity(String cityId);
}
3、创建xml配置文件和mapper映射文件
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:mybatis="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd">
<!-- 启用注解相关的后置处理器,这样才可以在代码中使用Spring提供的相关注解 -->
<!-- <context:annotation-config /> -->
<!-- 配置包扫描,也就是扫描哪些包下带有注解的类,将其纳入ioc容器管理,
base-package属性将会扫描当前包以及子包下所有的类
注意:当配置了component-can,那么就不需要再配置annotation-config,
因为component-scan已经包含了-->
<context:component-scan base-package="edu.nf.xml" >
<context:exclude-filter type="aspectj" expression="edu.nf.xml.controller"/>
</context:component-scan>
<!-- 配置数据源,这里使用druid连接池,(alibaba)开源,所有的连接池都会实现了DataSource接口的规范,
下面就是将druid与spring整合,将连接池纳入spring容器中管理。
注意:druid是可以单独使用,并不一定要整合到spring中,只是通常用到Spring框架都会与数据源进行整合 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 设置数据库的连接属性 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&encoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<!-- 连接池属性配置 -->
<!-- 连接池最大连接池数量 -->
<property name="maxActive" value="200"/>
<!-- 初始化连接池时的连接数量 -->
<property name="initialSize" value="2"/>
<!-- 最小连接数量 -->
<property name="minIdle" value="5"/>
<!-- 获取连接的等待时间,单位:毫秒 -->
<property name="maxWait" value="60000"/>
<!-- 连接保持空闲而不被驱逐的最小时间(在规定时间内如果连接未被使用,则被驱逐连接池,直到最小连接数量) -->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<!-- 检测连接,如果检测到连接空闲时间大于timeBetweenEvictionRunsMillis的值,
则关闭物理连接 -->
<property name="timeBetweenEvictionRunsMillis" value="6000"/>
<!-- 申请连接时检测,如果空余时间大于timeBetweenEvictionRunsMillis指定的时间,
就执行validationQuery检测连接是否有效 -->
<property name="testWhileIdle" value="true"/>
<!-- 伪sql语句,用于检查连接是否有用 -->
<property name="validationQuery" value="select 1"/>
<!-- 申请连接时执行validationQuery检测连接是否有用,默认true,建议设置false,提高性能 -->
<property name="testOnBorrow" value="false"/>
<!-- 归还连接时是否检测连接是否可用 -->
<property name="testOnReturn" value="false"/>
<!-- 是否缓存PreparedStatement,MySQL或Oracle建议关闭 -->
<property name="poolPreparedStatements" value="false"/>
</bean>
<!-- 整合mybatis,配置SqlSessionFactoryBean,它将负责创建SqlSessionFactory交由容器管理 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 给实体包下的类定义默认的别名 -->
<property name="typeAliasesPackage" value="edu.nf.ch04.entity"/>
<!-- 指定mapper映射目录 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
<!-- 配置分页插件-->
<property name="plugins">
<!-- 配置分页插件的拦截器 -->
<bean class="com.github.pagehelper.PageInterceptor">
<!-- 配置拦截器属性 -->
<property name="properties">
<props>
<!-- 指定数据库方言 -->
<prop key="helperDialect">mysql</prop>
<!-- 分页参数注解支持-->
<prop key="supportMethodsArguments">true</prop>
<!-- 分页合理化-->
<prop key="rowBoundsWithCount">true</prop>
</props>
</property>
</bean>
</property>
</bean>
<!-- 指定扫描的dao接口包,
mybatis插件会根据这些接口自动创建相应的实现类,
底层基于动态代理来创建dao接口的实现类 -->
<mybatis:scan base-package="edu.nf.xml.dao"/>
</beans>
CityServiceMapper.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">
<mapper namespace="edu.nf.xml.dao.CityDao">
<resultMap id="cityMap" type="edu.nf.xml.entity.City">
<id column="city_id" property="cityId"/>
<result column="city_name" property="cityName"/>
<result column="city_code" property="cityCode"/>
<result column="province" property="province"/>
</resultMap>
<select id="cityInfo" resultMap="cityMap">
select city_id, city_name, city_code, province from city_info
</select>
<select id="getCity" resultMap="cityMap" parameterType="String">
select city_id, city_name, city_code, province from city_info where city_id = #{cityId}
</select>
</mapper>
到这里,dao层已经基本配置完毕,现在开始配置service层和controller层
第三步:service层配置
service层主要做事务管理和aop切面
1、创建包:
2、实现业务类:
CityService.java
public interface CityService { /**
* 分页,获取城市信息
* @param pageNum 第几页(从0开始)
* @param pageSize 每页几条
* @return
*/
PageInfo<City> cityInfo(@Param("pageNum") Integer pageNum, @Param("pageSize") Integer pageSize);
/**
* 获取指定城市信息
* @param cityId 城市id
* @return
*/
City getCity(String cityId);
}
CityServiceImpl.java:实现CityService接口,dao会在运行时动态生成生成代理实现类而注入
@Service@Transactional(rollbackFor = DataAccessException.class)
public class CityServiceImpl implements CityService {
@Autowired
private CityDao dao;
/**
* 分页:获取城市信息
* @param pageNum 第几页(从0开始)
* @param pageSize 每页几条
* @return 返回分页信息
*/
@Override
public PageInfo<City> cityInfo(Integer pageNum, Integer pageSize) {
try {
List<City> list = dao.cityInfo(pageNum, pageSize);
PageInfo pageInfo = new PageInfo(list);
return pageInfo;
} catch (Exception e) {
e.printStackTrace();
throw new DataAccessException("获取城市列表失败");
}
}
/**
* 获取指定城市信息
* @param cityId 城市id
* @return
*/
@Override
public City getCity(String cityId) {
try {
return dao.getCity(cityId);
} catch (Exception e) {
e.printStackTrace();
throw new DataAccessException("获取城市信息失败");
}
}
}
DataAccessException.java:自定义异常类,继承自RunTimeException
public class DataAccessException extends RuntimeException { public DataAccessException() {
super();
}
public DataAccessException(String message) {
super(message);
}
public DataAccessException(String message, Throwable cause) {
super(message, cause);
}
}
CityAspect.java:切面类(spring-study ch11-ch14)
public class UserServiceAspect { /**
* 前置通知
* @param jp 连接点,通过这个连接点可以获取目标方法
*/
public void before(JoinPoint jp){
System.out.println("前置通知,目标方法参数:" + jp.getArgs()[0]);
}
/**
* 环绕通知
* @param pjp 连接点,可以获取目标方法参数以及方法信息以及调用目标方法等等
*/
public Object around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕通知前。。。");
//获取目标方法的的Method对象
MethodSignature ms = (MethodSignature)pjp.getSignature();
Method method = ms.getMethod();
System.out.println("当前调用的目标方法:" + method.getName());
//调用目标方法
Object returnVal = pjp.proceed();
System.out.println("环绕通知后。。。");
return returnVal;
}
/**
* 后置通知
* @param returnVal 目标方法的返回值
*/
public void afterReturning(String returnVal){
System.out.println("后置通知,返回参数:" + returnVal);
}
/**
* 异常通知
* @param e 目标方法产生的异常对象
*/
public void afterThrowing(Throwable e){
System.out.println("异常通知,异常信息:" + e.getMessage());
}
/**
* 最终通知
*/
public void after(){
System.out.println("最终通知");
}
}
要在applicationContext.xml配置文件中添加以下配置:
<!-- 定义切面 --><bean id="cityAspect" class="edu.nf.xml.service.aspect.CityAspect"/>
<!-- 配置aop,基于AspectJ -->
<aop:config>
<aop:pointcut id="myPointcut" expression="execution(* edu.nf.xml.service.impl.CityServiceImpl.*(..))"/>
<aop:aspect ref="cityAspect">
<!-- 装配通知,method对应通知的方法名,pointcut-ref引用上面定义的切入点的id
如果不同的通知想使用不同的切入点,那么使用pointcut属性进行的自定义 -->
<!-- 前置通知 -->
<aop:before method="before" pointcut-ref="myPointcut"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="myPointcut"/>
<!-- 后置通知,returnVal属性指定后置通知方法的参数名(参数名称要一致) -->
<aop:after-returning method="afterReturning" pointcut-ref="myPointcut" returning="returnVal"/>
<!-- 异常通知,throwing属性指定异常通知方法的参数名(名称要一致) -->
<aop:after-throwing method="afterThrowing" pointcut-ref="myPointcut" throwing="e"/>
<!-- 最终通知 -->
<aop:after method="after" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
3、添加配置:
在applicationContext.xml配置文件中添加以下配置:
<!-- 装配事务管理器 --><bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 启用事务注解处理器 -->
<tx:annotation-driven transaction-manager="txManager"/>
4、测试:
CityTest.java,在test模块中创建测试类:
public class CityTest { @Test
public void testListCity(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
CityService service = context.getBean("cityService", CityService.class);
PageInfo<City> pageInfo = service.cityInfo(0, 5);
List<City> list = pageInfo.getList();
list.forEach(city -> System.out.print(city.getCityName() + "++"));
}
}
运行结果:
第四步:controller层配置
controller主要有处理请求的方法,全局异常处理,拦截器等与springmvc相关的配置
1、创建包和类,及web构面
2、实现业务类:
ControllerAspect.java:全局异常处理,在service层中可能回抛出DataAccessException异常,在这个类中可以处理:
@ControllerAdvice("edu.nf.xml.controller")public class ControllerAspect {
@ExceptionHandler(DataAccessException.class)
@ResponseBody
public ResponseVO handleDataAccessException(DataAccessException e){
ResponseVO vo = new ResponseVO();
vo.setCode(500);
vo.setMessage(e.getMessage());
return vo;
}
}
LoginInterceptor.java:拦截器(springmvc-study ch10*),这里是用作登录拦截,在写拦截器类前需要添加配置信息:
<!-- 配置拦截器 --><mvc:interceptors>
<!-- 可以配置多个拦截器 -->
<mvc:interceptor>
<!-- 指定哪些url是需要被拦截的 -->
<mvc:mapping path="/***"/>
<!-- 配出哪些请求不需要被拦截 -->
<mvc:exclude-mapping path="/login.html"/>
<mvc:exclude-mapping path="/user_login"/>
<mvc:exclude-mapping path="/js/**"/>
<!-- 配置自定义的拦截器 -->
<bean class="edu.nf.xml.controller.interceptor.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
public class LoginInterceptor implements HandlerInterceptor {
/**
* 调用controller方法之前调用
* @param request
* @param response
* @param handler 目标控制器实例
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("调用controller方法前。。。");
HttpSession session = request.getSession();
if(session.getAttribute("user") == null){
//如果没登录,则重定向回登录页面
response.sendRedirect("login.html");
//返回false,阻止后面的方法执行
return false;
}
return true;
}
/**
* 再调用controller方法之后执行,但未返回ModelAndView时执行
* 注意:只有再preHandle方法返回true的情况下才会执行
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("调用controller方法之后。。。");
}
/**
* 方法返回后,视图响应之前调用此方法,在返回ModelAndView后执行
* 注意:这个方法只有在preHandle方法返回true的时候才能调用
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("响应视图。。。");
}
}
CityController.java:请求处理器
@RestController@RequestMapping("/city")
public class CityController extends BaseController {
@Autowired
private CityService service;
/**
* 查询城市列表
* @param pageNum
* @param pageSize
* @return
*/
@GetMapping("/city")
public ResponseVO listCity(Integer pageNum, Integer pageSize){
PageInfo<City> pageInfo = service.cityInfo(pageNum, pageSize);
System.out.println(pageInfo.getList());
return success(pageInfo);
}
/**
* 获取城市信息
* @param cityId
* @return
*/
@GetMapping("/${cityId}")
public ResponseVO cityInfo(@PathVariable("cityId") String cityId){
City city = service.getCity(cityId);
System.out.println(city);
return success(city);
}
}
3、添加配置
dispatcher-serverlt.xml:在controller层中,主要做servlet的配置
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描,只负责扫描controller中的类 -->
<context:component-scan base-package="edu.nf.xml.controller"/>
<!-- mvc注解 -->
<mvc:annotation-driven/>
<!-- 静态资源 -->
<mvc:default-servlet-handler/>
<!-- 内部视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 方式一:导入applicationContext.xml配置文件 -->
<!-- <import resource="applicationContext.xml"/>-->
</beans>
添加了web构面后,在web/WEB-INF目录下就会有一个web.xml配置文件,在这里配置DispatcherServlet和applicationContext.xml
<!-- 配置一个上下文监听器,这个是由spring提供的 注意:监听器会优先于Servlet初始化,因此当监听器初始化一个配置文件时,
会创建一个ioc容器,这个容器就是主容器,而下面通过DispatcherServlet创建的容器
就会自动设置为当前容器的子容器,这就是父子容器的概念,当我们要从容器中获取一个bean对象时,
先从子容器中查找,如果没有则到父容器中查找,反过来,父容器是不能访问子容器的内容。-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- spring提供的字符编码过滤器 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<!-- 将request和response的编码保持一致 -->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置核心控制器 servlet-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
4、测试:
使用ajax异步请求,测试获取城市列表请求:
发送请求:
<script> $(function(){
$.ajax({
url:'city/list_city',
data: {'pageNum': 0, 'pageSize': 5},
type:'post',
success: function(result){
console.log(result);
}
})
})
</script>
结果:
本文内容总结:第一步、配置pom.xml,第二步、dao层配置,第三步:service层配置,第四步:controller层配置,
原文链接:https://www.cnblogs.com/zhangcaihua/p/12803270.html
以上是 基于注解和xml配置的SSM(Spring+SpringMVC+Mybatis)项目详细配置 的全部内容, 来源链接: utcz.com/z/296236.html