1. ssm整合
s: springMVC
s: spring
m: mybatis
上述三个框架合起来,称为ssm,所谓的ssm整合说的就是将三个框架集成起来
前面其实已经做过,spring+mybatis的集成了,这里我们再来回顾一遍,然后在将springMVC集成进来即可。
1.1 集成spring
步骤:
新建maven工程
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mszlu</groupId> <artifactId>ssm</artifactId> <version>1.0-SNAPSHOT</version> <properties> <!-- 项目编译编码--> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- maven编译的jdk版本--> <maven.compiler.encoding>UTF-8</maven.compiler.encoding> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.16.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency> <!--mybatis环境--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.3</version> </dependency> <!--spring整合mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.3</version> </dependency> <!--连接池--> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <!--分页插件坐标--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.2</version> </dependency> <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <!--servlet环境--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> </dependencies> </project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87在resources下新建applicationContext.xml,做为spring的配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--开启bean注解扫描--> <context:component-scan base-package="com.mszlu.ssm"/> </beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14新建UserService.java
package com.mszlu.ssm.service; import org.springframework.stereotype.Service; @Service public class UserService { public void test(){ System.out.println("test...."); } }
1
2
3
4
5
6
7
8
9
10
11
12
13新建APP.java,测试UserService可用
package com.mszlu.ssm; import com.mszlu.ssm.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = context.getBean(UserService.class); userService.test(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.2 Spring集成Mybatis
表结构
CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `age` int(11) NULL DEFAULT NULL, `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL, `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
1
2
3
4
5
6
7package com.mszlu.ssm.pojo; import lombok.Data; @Data public class User { private Long id; private String name; private Integer age; private String email; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16在resources下新建spring-dao的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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig"> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/springboot?characterEncoding=utf8&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="root"/> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="autoCommit" value="true"/> <property name="connectionTimeout" value="5000" /> <property name="idleTimeout" value="60" /> </bean> <!--jdbc的xml配置--> <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"> <constructor-arg name="configuration" ref="hikariConfig"/> </bean> <!--mybatis--> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath*:mapper/*.xml"/> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <props> <prop key="helperDialect">mysql</prop> </props> </property> </bean> </array> </property> </bean> <!--配置mapper接口的扫包路径,目的是代理此接口,生成代理类 注册到spring容器中--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.mszlu.ssm.mapper"/> </bean> </beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42优化,在resources新建jdbc.properties,在spring-dao.xml中引入,将数据库配置提取出来
jdbc.url=jdbc:mysql://localhost:3306/springboot?characterEncoding=utf8&serverTimezone=UTC jdbc.username=root jdbc.password=root jdbc.driverClassName=com.mysql.cj.jdbc.Driver jdbc.autoCommit=true jdbc.connectionTimeout=5000 jdbc.idleTimeout=60
1
2
3
4
5
6
7<context:property-placeholder location="classpath*:*.properties"/> <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig"> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="autoCommit" value="${jdbc.autoCommit}"/> <property name="connectionTimeout" value="${jdbc.connectionTimeout}" /> <property name="idleTimeout" value="${jdbc.idleTimeout}" /> </bean>
1
2
3
4
5
6
7
8
9
10
11在applicationContext.xml中引入spring-dao.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:tx="http://www.springframework.org/schema/tx" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--开启bean注解扫描--> <context:component-scan base-package="com.mszlu.ssm"/> <import resource="spring-dao.xml" /> </beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15新建UserMapper接口,注意要在
com.mszlu.ssm.mapper
包下package com.mszlu.ssm.mapper; import com.mszlu.ssm.pojo.User; public interface UserMapper { User findUser(Long id); }
1
2
3
4
5
6
7
8
9在resources下新建mapper/UserMapper.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="com.mszlu.ssm.mapper.UserMapper"> <select id="findUser" parameterType="long" resultType="com.mszlu.ssm.pojo.User"> select * from user where id=##{id} </select> </mapper>
1
2
3
4
5
6
7
8
9
10在UserService中注入UserMapper,实现查询用户的业务
package com.mszlu.ssm.service; import com.mszlu.ssm.mapper.UserMapper; import com.mszlu.ssm.pojo.User; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class UserService { @Resource private UserMapper userMapper; public void test(){ System.out.println("test...."); } public User getUser(Long id){ return userMapper.findUser(id); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24测试
package com.mszlu.ssm; import com.mszlu.ssm.pojo.User; import com.mszlu.ssm.service.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = context.getBean(UserService.class); User user = userService.getUser(1L); System.out.println(user); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.3 集成SpringMVC
将pom.xml中的package改为war,加入springMVC,就是web工程,同时导入spring-webmvc的依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mszlu</groupId> <artifactId>ssm</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!-- <dependency>--> <!-- <groupId>org.springframework</groupId>--> <!-- <artifactId>spring-context</artifactId>--> <!-- <version>5.2.16.RELEASE</version>--> <!-- </dependency>--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.16.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency> <!--mybatis环境--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.3</version> </dependency> <!--spring整合mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.3</version> </dependency> <!--连接池--> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>3.4.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <!--分页插件坐标--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.2</version> </dependency> <dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <!--servlet环境--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> </project>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81在main的下面,新建webapp目录,和java,resources同级,有个小蓝点标识,证明正确
webapp下新建WEB-INF/web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <!--spring配置文件加载--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--解决post请求乱码--> <filter> <filter-name>CharacterEncodingFilter</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> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--springmvc配置文件加载--> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring-mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <!--/代表拦截所有请求,一般也写做*.do代表只匹配.do后缀的请求--> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43在resources下新建spring-mvc.xml,其中加入mvc相关的配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" 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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--这个不能忘,分开加载spring配置文件,扫包也需要单独配置--> <context:component-scan base-package="com.mszlu.ssm.controller" /> <!--开启mvc的注解支持--> <mvc:annotation-driven/> <!--扫包的配置,在spring配置文件中 已经定义,保证controller在扫包范围内即可--> <!--过滤静态文件--> <mvc:default-servlet-handler /> </beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20新建UserController.java,调用Service,完成根据id获取用户信息的逻辑
package com.mszlu.ssm.controller; import com.mszlu.ssm.pojo.User; import com.mszlu.ssm.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("user") public class UserController { @Autowired private UserService userService; @GetMapping("getUser/{id}") public User findUser(@PathVariable Long id){ return userService.getUser(id); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23测试
pom.xml中添加tomcat7插件, idea右侧maven->plugins->tomcat7 运行
<build> <!--设置插件--> <plugins> <!--具体的插件配置--> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>80</port> <path>/</path> </configuration> </plugin> </plugins> </build>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15浏览器访问 http://localhost/user/getUser/1
1.4 添加事务配置
spring-tx.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:tx="http://www.springframework.org/schema/tx"
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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<tx:annotation-driven proxy-target-class="true"/>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
不要忘了在applicationContext.xml中导入
测试:
@Transactional
public void save(String name,String email,Integer age){
User user = new User();
user.setAge(age);
user.setEmail(email);
user.setName(name);
this.userMapper.save(user);
int i = 10/0;
}
2
3
4
5
6
7
8
9
<insert id="save" parameterType="com.mszlu.ssm.pojo.User" keyProperty="id" useGeneratedKeys="true">
insert into user (name,email,age) values (##{name},##{email},##{age})
</insert>
2
3
@GetMapping("save")
public void save(String name,String email,Integer age){
userService.save(name,email,age);
}
2
3
4
如果数据添加不成功,证明事务生效。
2. 纯注解ssm整合
将web.xml 删除,则tomcat启动的时候不会加载web.xml,同时也不会加载resource下的spring配置文件
web.xml的替代
package com.mszlu.ssm.config; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer; import javax.servlet.DispatcherType; import javax.servlet.FilterRegistration; import javax.servlet.ServletContext; import javax.servlet.ServletException; import java.util.EnumSet; public class WebConfig extends AbstractDispatcherServletInitializer { @Override protected WebApplicationContext createServletApplicationContext() { //加载springmvc的配置文件 AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(SpringMVCConfig.class); return context; } @Override protected String[] getServletMappings() { //dispatchServlet 路径映射 return new String[]{"/"}; } @Override protected WebApplicationContext createRootApplicationContext() { //spring配置文件 AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(SpringConfig.class); return context; } //乱码处理作为过滤器,在servlet容器启动时进行配置,相关内容参看Servlet零配置相关课程 @Override public void onStartup(ServletContext servletContext) throws ServletException { //触发父类的onStartup super.onStartup(servletContext); //1.创建字符集过滤器对象 CharacterEncodingFilter cef = new CharacterEncodingFilter(); //2.设置使用的字符集 cef.setEncoding("UTF-8"); //3.添加到容器(它不是ioc容器,而是ServletContainer) FilterRegistration.Dynamic registration = servletContext.addFilter("characterEncodingFilter", cef); //4.添加映射 registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE), false, "/*"); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53spring的配置文件 SpringConfig.java
package com.mszlu.ssm.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.*; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; @Configuration //开启事务支持 @EnableTransactionManagement(proxyTargetClass = true) //@EnableAspectJAutoProxy 开启aop支持,如果有AOP实现的代码 @ComponentScan("com.mszlu.ssm") //扫包配置 public class SpringConfig { @Bean public DataSourceTransactionManager transactionManager(@Autowired DataSource dataSource){ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); return transactionManager; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23jdbc的配置:
package com.mszlu.ssm.config; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import javax.sql.DataSource; @Configuration @PropertySource("classpath:jdbc.properties") public class JDBCConfig { @Value("${jdbc.url}") private String jdbcUrl; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Value("${jdbc.driverClassName}") private String driverClassName; @Value("${jdbc.autoCommit}") private Boolean autoCommit; @Value("${jdbc.connectionTimeout}") private Integer connectionTimeout; @Value("${jdbc.idleTimeout}") private Integer idleTimeout; @Bean public DataSource dataSource(){ HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setPassword(username); hikariConfig.setUsername(password); hikariConfig.setJdbcUrl(jdbcUrl); hikariConfig.setDriverClassName(driverClassName); hikariConfig.setConnectionTimeout(connectionTimeout); hikariConfig.setAutoCommit(autoCommit); hikariConfig.setIdleTimeout(idleTimeout); return new HikariDataSource(hikariConfig); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43mybatis配置:
package com.mszlu.ssm.config; import com.github.pagehelper.PageInterceptor; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import javax.sql.DataSource; import java.io.IOException; import java.util.Properties; @Configuration public class MybatisConfig { @Bean public SqlSessionFactoryBean sqlSessionFactoryBean(@Autowired DataSource dataSource) throws IOException { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resourceResolver.getResources("classpath*:mapper/*.xml"); sqlSessionFactoryBean.setMapperLocations(resources); //分页插件 PageInterceptor pageInterceptor = new PageInterceptor(); Properties properties = new Properties(); properties.setProperty("helperDialect","mysql"); pageInterceptor.setProperties(properties); sqlSessionFactoryBean.setPlugins(pageInterceptor); return sqlSessionFactoryBean; } @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage("com.mszlu.ssm.mapper"); return configurer; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43springmvc的配置文件SpringMVCConfig.java
package com.mszlu.ssm.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @Configuration @EnableWebMvc //开启mvc的支持 @ComponentScan("com.mszlu.ssm.controller") public class SpringMVCConfig { }
1
2
3
4
5
6
7
8
9
10
11
12启动测试
3. 小知识
上面spring和springMVC的配置是分开的,实际上可以合为一个,保留mvc的配置,将spring的配置写入mvc的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>-->
<!--解决post请求乱码-->
<filter>
<filter-name>CharacterEncodingFilter</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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
注解:
package com.mszlu.ssm.config;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import java.util.EnumSet;
public class WebConfig extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createServletApplicationContext() {
System.out.println("----");
//加载springmvc的配置文件
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
//但是SpringConfig要加入mvc的注解支持
context.register(SpringConfig.class);
return context;
}
@Override
protected String[] getServletMappings() {
//dispatchServlet 路径映射
return new String[]{"/"};
}
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
//乱码处理作为过滤器,在servlet容器启动时进行配置,相关内容参看Servlet零配置相关课程
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
//触发父类的onStartup
super.onStartup(servletContext);
//1.创建字符集过滤器对象
CharacterEncodingFilter cef = new CharacterEncodingFilter();
//2.设置使用的字符集
cef.setEncoding("UTF-8");
//3.添加到容器(它不是ioc容器,而是ServletContainer)
FilterRegistration.Dynamic registration = servletContext.addFilter("characterEncodingFilter", cef);
//4.添加映射
registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE), false, "/*");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
4. Junit测试
导包
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.16.RELEASE</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.7.1</version> <scope>test</scope> </dependency>
1
2
3
4
5
6
7
8
9
10
11
12测试service层代码,在test下面建立service的同包名
编写UserServiceTest.java
package com.mszlu.ssm.service; import com.mszlu.ssm.config.SpringConfig; import com.mszlu.ssm.config.SpringMVCConfig; import com.mszlu.ssm.pojo.User; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.springframework.util.Assert; //注意这里是service的测试,不包含controller测试,所以SpringConfig内不能有EnableWebMVC注解 //但是SpringConfig中扫包的时候 扫到了SpringMVCConfig 所以需要将SpringMVCConfig排除 //理论上 测试的时候 应该在test下面 创建测试使用的配置类 @SpringJUnitConfig(classes = SpringConfig.class) public class UserServiceTest { @Autowired private UserService userService; @Test public void testGetUser(){ User user = userService.getUser(1L); Assertions.assertEquals(50,user.getAge()); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28注意修改SpringConfig.java
package com.mszlu.ssm.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.*; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import javax.sql.DataSource; @Configuration //开启事务支持 @EnableTransactionManagement(proxyTargetClass = true) //@EnableAspectJAutoProxy 开启aop支持,如果有AOP实现的代码 //排除mvc的配置,会影响测试用例的编写 @ComponentScan(value = "com.mszlu.ssm",excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = SpringMVCConfig.class) }) //扫包配置 public class SpringConfig { @Bean public DataSourceTransactionManager transactionManager(@Autowired DataSource dataSource){ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); return transactionManager; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27运行测试
4.1 Mock测试
如果想要对controller进行测试,应该怎么操作呢?
添加依赖
<dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.7.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>3.2.4</version> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.78</version> </dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17写Controller的测试用例
package com.mszlu.ssm.controller; import com.mszlu.ssm.config.SpringJunitConfig; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; //需要单独建立测试spring配置,mvc的配置和spring集成在一起 @SpringJUnitConfig(classes = SpringJunitConfig.class) @WebAppConfiguration public class UserControllerTest { private MockMvc mockMvc; @Autowired private WebApplicationContext webApplicationContext; @BeforeEach public void before(){ mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build(); } @Test public void testGetUser() throws Exception { MvcResult mvcResult = mockMvc.perform( MockMvcRequestBuilders.get("/user/getUser/1") .contentType("application/json;charset=utf8")) .andReturn(); System.out.println(mvcResult.getResponse().getContentAsString()); } @Test public void testSave() throws Exception { MvcResult mvcResult = mockMvc.perform( MockMvcRequestBuilders.get("/user/save") .param("name","zhangsan") .param("age","50") .param("email","aaa")) .andReturn(); System.out.println(mvcResult.getResponse().getContentAsString()); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49package com.mszlu.ssm.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import javax.sql.DataSource; @Configuration //开启事务支持 @EnableTransactionManagement(proxyTargetClass = true) //@EnableAspectJAutoProxy 开启aop支持,如果有AOP实现的代码 @ComponentScan(value = "com.mszlu.ssm") //扫包配置 @EnableWebMvc public class SpringJunitConfig { @Bean public DataSourceTransactionManager transactionManager(@Autowired DataSource dataSource){ DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); return transactionManager; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
5. Redis集成
添加依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.3.0</version> </dependency> <!--依赖的spring版本为5.2.14.RELEASE,需要更改spring版本--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.3.9.RELEASE</version> </dependency>
1
2
3
4
5
6
7
8
9
10
11定义RedisTemplate
package com.mszlu.ssm.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.jedis.JedisClientConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import redis.clients.jedis.JedisPoolConfig; import java.io.Serializable; @Configuration public class RedisConfig { @Bean public RedisTemplate<Serializable, Object> redisTemplate(@Autowired RedisConnectionFactory redisConnectionFactory){ RedisTemplate<Serializable, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>( Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); redisTemplate.setKeySerializer(redisTemplate.getStringSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); //在使用String的数据结构的时候使用这个来更改序列化方式 RedisSerializer<String> stringSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringSerializer ); redisTemplate.setValueSerializer(stringSerializer ); redisTemplate.setHashKeySerializer(stringSerializer ); redisTemplate.setHashValueSerializer(stringSerializer ); return redisTemplate; } @Bean public RedisConnectionFactory redisConnectionFactory(@Autowired JedisPoolConfig jedisPoolConfig){ RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); redisStandaloneConfiguration.setHostName("localhost"); redisStandaloneConfiguration.setPort(6379); JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jedisClientConfigurationBuilder = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder(); jedisClientConfigurationBuilder.poolConfig(jedisPoolConfig); JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration); return jedisConnectionFactory; } /** * 连接池配置信息 * @return */ @Bean public JedisPoolConfig jedisPoolConfig() { JedisPoolConfig poolConfig=new JedisPoolConfig(); //最大连接数 poolConfig.setMaxIdle(200); //最小空闲连接数 poolConfig.setMinIdle(50); poolConfig.setTestOnBorrow(true); poolConfig.setTestOnReturn(true); poolConfig.setTestWhileIdle(true); poolConfig.setNumTestsPerEvictionRun(10); poolConfig.setTimeBetweenEvictionRunsMillis(60000); //当池内没有可用的连接时,最大等待时间 poolConfig.setMaxWaitMillis(10000); //------其他属性根据需要自行添加------------- return poolConfig; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80测试
@Autowired private RedisTemplate redisTemplate; @GetMapping("testRedis") public void testRedis(){ redisTemplate.opsForValue().set("test_ssm","mszlu"); String test_ssm = (String) redisTemplate.opsForValue().get("test_ssm"); System.out.println(test_ssm); }
1
2
3
4
5
6
7
8
9