SSM 整合
在SSM 框架中, Spring MVC 用于web层相当于Controller 处理请求并做出响应
MyBatis 作为持久层框架,可以自由的控制SQL 更加简单的完成数据库操作
Spring 的依赖注入可以减少代码的耦合,可以装配 Bean,另外其 AOP、事务管理尤其方便,
同时,Spring 可以将各层进行整合。
表现层 springMVC ——>业务层 service接口——>持久层 MyBatis ——>mysql
spring 将各层进行整合
通过spring 管理持久层的 mapper(相当于 dao 接口)
通过spring管理业务层 service service中可以调用 mapper 接口
spring 进行事务控制
通过spring 管理表现层Handler,Handler中可以调用 service 接口
mapper、service、Handler都是 javabean
准备数据库
create database ssm;
use ssm;
create table user(
-> id int primary key auto_increment,
-> username varchar(20),
-> password varchar(20),
-> sex varchar(10),
-> age int
-> );
随便插入一条测试数据
insert into user(username,password,sex,age)
values('xiaoxie','1234','male',22);
新建各层的包
entity 一系列POJO,各种实体类
mapper 相当于dao层 其下包括 Mapper 接口和 Mapper 配置文件,通过 SQL 语句的映射完成 CRUD 操作
service 由一系列业务逻辑对象组成,放置各种 service 接口
service.impl 是 service 的具体实现
controller 由一系列控制器组成,处理用户请求并作出响应
接下来添加相关依赖包,如spring、mybatis等。打开pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.shiyanlou</groupId>
<artifactId>SpringMVCTest</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>SpringMVCTest Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.5.RELEASE</version>
<scope>test</scope>
</dependency>
<!--commons 包-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!--数据库包依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--日志包依赖-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
<exclusions>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!--aspectj 包依赖-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
<!--Spring 依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--数据校验-->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
<!-- 文件上传下载 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<!--jetty maven 插件,为 maven 提供运行 web 程序的能力-->
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.12.v20180830</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
<webApp>
<contextPath>/</contextPath>
</webApp>
</configuration>
</plugin>
</plugins>
</build>
</project>
entity 层 实体类 User.java
package com.test.entity;
/**
* @author pangxie
* @2020/7/20
*/
public class User
{
private Integer id; //用户 id
private String username; //用户名
private String password; //密码
private String sex; //性别
private Integer age; //年龄
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 getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
在包 mapper 下建一个 UserMapper.java
package com.test.mapper;
import com.test.entity.User;
import java.util.List;
/**
* @author pangxie
* @2020/7/21
*/
public interface UserMapper
{
// 用户登录查询
User selectLogin(User user);
//查询全部用户
List<User> selectAllUser();
//新增用户
void addUser(User user);
//更新用户
void updateUser(User user);
//删除用户
void deleteUser(Integer id);
}
在src/main/resources下建立一个mappers文件夹,并在其中建立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.test.mapper.UserMapper">
<!--自定义结果集 返回所需要的数据-->
<resultMap id="userResultMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="sex" column="sex" />
<result property="age" column="age"/>
</resultMap>
<!--登录查询-->
<select id="selectLogin" parameterType="User" resultMap="userResultMap">
select *
from user
where username = #{username} and password = #{password}
</select>
<!--查询所有用户-->
<select id="selectAllUser" resultMap="userResultMap">
select *
from user
</select>
<!-- 新增用户 -->
<insert id="addUser" useGeneratedKeys="true" keyProperty="id">
insert into user (username, password, sex, age)
values (#{username}, #{password}, #{sex}, #{age})
</insert>
<!-- 更新用户 -->
<update id="updateUser" parameterType="User">
update user
set username = #{username},
password = #{password},
sex = #{sex},
age = #{age}
where id = #{id}
</update>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="int">
delete
from user
where id = #{id}
</delete>
</mapper>
到这里 DAO 层的代码就写完了 接下来实现 Service 层的代码
在包 service 下建一个 UserService.java 接口文件
package com.test.service;
import com.test.entity.User;
import java.util.List;
/**
* @author pangxie
* @2020/7/21
*/
public interface UserService
{
//用户登录
User login(User user);
//查询全部用户
List<User> selectAllUser();
//新增用户
void addUser(User user);
//更新用户
void updateUser(User user);
//删除用户
void deleteUser(Integer id);
}
在包 service.impl 下建一个类 UserServiceImpl.java ,用来实现 UserService 接口中的方法
package com.test.service;
import com.test.entity.User;
import java.util.List;
/**
* @author pangxie
* @2020/7/21
*/
public interface UserService
{
//用户登录
User login(User user);
//查询全部用户
List<User> selectAllUser();
//新增用户
void addUser(User user);
//更新用户
void updateUser(User user);
//删除用户
void deleteUser(Integer id);
}
到这里 Service 层的代码就写完了 接下来将 Spring 和 MyBatis 进行整合
Spring 整合 MyBatis
在目录 src/main/resources 下新建 MyBatis 配置文件 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>
<!--为 JavaBean 起类别名-->
<typeAliases>
<package name="com.test.entity"/>
</typeAliases>
<!--通过 mapper 接口包加载整个包的映射文件-->
<mappers>
<package name="com.test.mapper"/>
</mappers>
</configuration>
这里没有配置 Mybatis 的运行环境、数据源 那是因为要交给 Spring 进行管理
在目录 src/main/resources 下新建文件 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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">
<!--自动扫描有 Spring 相关注解的类 把这些类注册为 bean-->
<context:component-scan base-package="com.test"/>
<!--配置数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm" />
<property name="username" value="root"/>
<property name="password" value="000000"/>
</bean>
<!--MyBatis 的 SqlSession 的工厂 并引用数据源 扫描 Mybatis 的配置文件-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref = "dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml" />
<property name="mapperLocations" value="classpath*:mappers/**"/>
</bean>
<!-- MyBatis 自动扫描加载 Sql 映射文件/接口-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.test.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!--JDBC 事务管理-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--启用支持 annotation 注解方式事务管理-->
<tx:annotation-driven transaction-manager="txManager"/>
</beans>
该文件用来完成 Spring 和 Mybatis 的整合,主要包括 自动注入,自动扫描 配置数据库等
这里数据源配置信息是写死在文件中,也可以新建 jdbc.properties 文件,然后进行引入
log4j.properties 配置日志
在目录 src/main/resources 下新建日志文件 log4j.properties
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
到这里 Spring 和 MyBatis 的整合完毕
整合完 Spring 和 Mybatis 后 我们要完成 Spring MVC 的整合
在目录 src/test/java 下新建测试类 SpringMybatisTest 测试是否成功
import com.test.entity.User;
import com.test.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
/**
* @author pangxie
* @2020/7/21
* 配置spring和junit整合,junit启动时加载springIOC容器 spring-test,junit
*/
@RunWith(SpringJUnit4ClassRunner.class)
// 告诉junit spring配置文件
@ContextConfiguration({"classpath:applicationContext.xml"})
public class SpringMybatisTest
{
@Autowired
private UserService userService;
//@Test
public void testSelectAllUser()
{
List<User> users = userService.selectAllUser();
for (User us : users)
{
System.out.println(us.toString());
}
}
@Test
public void testAdd()
{
User user = new User();
user.setUsername("Alen");
user.setPassword("abc");
user.setSex("female");
user.setAge(18);
userService.addUser(user);
}
}
测试成功 说明 Spring 和 Mybatis 整合成功
整合完 Spring 和 Mybatis 后 我们要完成 Spring MVC 的整合
在包 controller 下建一个 Controller 类 UserController.java
package com.test.controller;
import com.test.entity.User;
import com.test.service.UserService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
/**
* @author pangxie
* @2020/7/21
* 处理用户请求 Controller
*/
@Controller
public class UserController {
/**
* 自动注入 UserService
**/
@Autowired
private UserService userService;
// 登录
@RequestMapping("/login")
public String login(User user, Model model, HttpSession session) {
User loginUser = userService.login(user);
if (loginUser != null) {
session.setAttribute("user", loginUser);
return "redirect:alluser";
} else {
session.setAttribute("message", "username or password is wrong!");
return "redirect:loginform.jsp";
}
}
// 退出
@RequestMapping(value = "/loginout")
public String loginout(HttpSession session) {
session.invalidate();
return "redirect:loginform.jsp";
}
// 查询所有用户
@RequestMapping("/alluser")
public String selectAllUser(HttpServletRequest request) {
List<User> listUser = userService.selectAllUser();
request.setAttribute("listUser", listUser);
return "userlist";
}
// 跳转至新增用户页面
@RequestMapping("/toadduser")
public String toAddUserPage() {
return "adduser";
}
// 新增用户
@RequestMapping("/adduser")
public String addUser(User user, HttpServletRequest request) {
userService.addUser(user);
List<User> listUser = userService.selectAllUser();
request.setAttribute("listUser", listUser);
return "userlist";
}
// 跳转至更新用户页面
@RequestMapping("/toupdateuser")
public String toUpdateUser(@Param("id") Integer id,
HttpServletRequest request, Model model) {
model.addAttribute("user_id", id);
return "updateuser";
}
// 更新用户
@RequestMapping("/updateuser")
public String updateUser(User user, HttpServletRequest request) {
userService.updateUser(user);
List<User> listUser = userService.selectAllUser();
request.setAttribute("listUser", listUser);
return "userlist";
}
// 删除用户
@RequestMapping("/deleteuser")
public String deleteUser(@Param("id") Integer id, HttpServletRequest request) {
userService.deleteUser(id);
List<User> listUser = userService.selectAllUser();
request.setAttribute("listUser", listUser);
return "userlist";
}
}
开始页面编写
登录页面、用户列表、添加页面、更新页面
配置 spring-mvc.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" xmlns:mvn="http://www.springframework.org/schema/mvc"
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-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd">
<mvn:default-servlet-handler/>
<!--自动扫描该包 Spring MVC 会将包下用 @Controller 注解的类 注册为 Spring 的 context-->
<context:component-scan base-package="com.test.controller"/>
<!--设置默认配置方式-->
<mvc:annotation-driven/>
<!--视图解析器-->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
最后配置 web.xml
<?xml version = "1.0" encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns = "http://java.sun.com/xml/ns/javaee" xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id = "WebApp_ID" version = "3.0">
<display-name>SpringMVCTest</display-name>
<!-- 配置 Spring 核心监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 指定 Spring 的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 定义 Spring MVC 前端控制器 -->
<servlet>
<servlet-name>springMVC</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>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 为 DispatcherServlet 建立映射 -->
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- 编码过滤器 -->
<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>
<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>
<!-- 设置首页 -->
<welcome-file-list>
<welcome-file>loginform.jsp</welcome-file>
</welcome-file-list>
</web-app>
全部完成后开始测试
登录
登陆成功
测试 添加、删除、更新 成功
项目源码地址:https://github.com/pangxiec/SSMTest