SSM(Spring+Spring MVC+MyBatis)是媲美于 ssm 框架的轻量级 Java EE 框架。在实际项目中,我们采用 SSM 框架进行开发,Spring MVC 用于 Web 层,相当于 Controller,处理请求并作出响应;MyBatis 作为持久层的框架,可以自由的控制 SQL,更加简捷地完成数据库操作;Spring 的依赖注入可以减少代码的耦合,可以装配 Bean,另外其 AOP、事务管理尤其方便,同时,Spring 可以将各层进行整合。
笔者尝试创建动态的 Web 工程整合 SSM 框架,如果想用 Maven 整合,请参考别的博客或自行修改,实现简单的登录和数据增删改查的操作,这里直接上干货。
整合的完整代码已经上传至这里,可以点击下载。
注:Spring MVC 相关 jar 包我已经上传到 这里,可以直接下载,一共包括:Spring 框架 jar 包、 MyBatis 框架 jar 包、MyBatis 整合 Spring 中间件 jar 包、aspectj 框架 jar 包、aopalliance.jar、数据库驱动 jar 包、数据源 c3p0 jar 包、JSTL 标签库 jar 包、单元测试 junit.jar。这些 jar 包在本项目中可能并没有完全用到。
登录 MySQL 后新建一个数据库并取名 ssm
,创建表 user
,并插入一条数据:
mysql> 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) value('gler','123456','male',24);
(1)首先在 Eclipse 里新建一个动态 Web 工程(Dynamic Web Project),命名为 SSM
,并自动生成 web.xml。
(2)将前面下载的 jar 包拷贝到工程的 WebContent/WEB-INF/lib/
目录下。
在 Java Resources/src
下新建各层的包,如图:
在包 gler.ssm.model
下新建类 User.java
, 一个用户具有:id、username、password、sex、age 五个属性,代码如下:
package gler.ssm.model;
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;
}
// 重写了 toString 方法,方便后面的测试
public String toString() {
return "id:" + id + ",username:" + username + ",password:" + password
+ ",sex:" + sex + ",age:" + age;
}
}
在包 gler.ssm.mapper
下建一个 UserMapper.java
接口文件和 UserMapper.xml
。
UserMapper 接口的代码如下:
package gler.ssm.mapper;
import java.util.List;
import gler.ssm.model.User;
public interface UserMapper {
/**
* 用户登录查询
* @param user
* @return User
**/
public User selectLogin(User user);
/**
* 查询全部用户
* @return List
**/
public List selectAllUser();
/**
* 新增用户
* @param user
**/
public void addUser(User user);
/**
* 更新用户
* @param user
**/
public void updateUser(User user);
/**
* 删除用户
* @param id
**/
public void deleteUser(Integer id);
}
UserMapper.xml 的配置如下:
<mapper namespace="gler.ssm.mapper.UserMapper">
<resultMap type="User" id="userResultMap">
<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 层的代码。
注:MyBatis 的配置文件放在整合时在进行处理。
5.1 Service 层接口
在包 gler.ssm.service
下建一个 UserService.java
接口文件,添加如下代码:
package gler.ssm.service;
import java.util.List;
import gler.ssm.model.User;
public interface UserService {
/**
* 用户登录
* @param user
* @return 登录成功返回 User 对象,失败返回 null
**/
User login(User user);
/**
* 查询所有用户
* @return 查询到的所有 User 对象的 list
**/
List selectAllUser();
/**
* 新增用户
* @param user
**/
void addUser(User user);
/**
* 更新用户
* @param user
**/
void updateUser(User user);
/**
* 删除用户
* @param id(用户 id)
**/
void deleteUser(Integer id);
}
5.2 Service 层接口实现类
在包 gler.ssm.service.impl
下建一个类 UserServiceImpl.java
,用来实现 UserService
接口中的方法,添加如下代码:
package gler.ssm.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import gler.ssm.mapper.UserMapper;
import gler.ssm.model.User;
import gler.ssm.service.UserService;
/**
* 将当前类注释为一个 Spring 的 bean
**/
@Service
@Transactional
public class UserServiceImpl implements UserService{
/**
* 自动注入 UserMapper
**/
@Autowired
public UserMapper userMapper;
// 下面是 UserService 接口所有方法的具体实现
@Override
public User login(User user) {
return userMapper.selectLogin(user);
}
@Override
public List selectAllUser() {
List users = userMapper.selectAllUser();
return users;
}
@Override
public void addUser(User user) {
userMapper.addUser(user);
}
@Override
public void updateUser(User user) {
userMapper.updateUser(user);
}
@Override
public void deleteUser(Integer id) {
userMapper.deleteUser(id);
}
}
到这里, Service 层的代码就写完了,接下来将 Spring 和 MyBatis 进行整合。
6.1 MyBatis 配置文件
在目录 Java Resources/src
下新建 MyBatis 配置文件 mybatis-config.xml
,代码如下:
<configuration>
<typeAliases>
<package name="gler.ssm.model" />
typeAliases>
<mappers>
<package name="gler/ssm/mapper" />
mappers>
configuration>
注:在这里,我们没有配置 MyBatis 的运行环境、数据源等,那是因为我们要将这些交给 Spring 进行配置管理。
6.2 applicationContext.xml
在目录 Java Resources/src
下新建文件 applicationContext.xml
,该文件用来完成 Spring 和 MyBatis 的整合,主要包括了自动扫描,自动注入,配置数据库等,内容如下:
<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: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">
<context:component-scan base-package="gler.ssm" />
<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="root" />
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource">property>
<property name="configLocation" value="classpath:mybatis-config.xml" />
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="gler.ssm.mapper">property>
<property name="sqlSessionFactory" ref="sqlSessionFactory">property>
bean>
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource">property>
bean>
<tx:annotation-driven transaction-manager="txManager" />
beans>
在这里,我们将数据源配置信息写死在 applicationContext.xml 中的,也可以新建 jdbc.properties 文件,然后进行引入。
6.3 log4j.properties 配置日志
在目录 Java Resources/src
下新建日志文件 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 就整合完成,下面我们通过一个测试类测试整合是否成功。
在目录 Java Resources/src
下新建包 gler.ssm.test
,并在包中新建测试类 SpringMybatisTest,添加如下代码:
package gler.ssm.test;
import java.util.List;
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 gler.ssm.model.User;
import gler.ssm.service.UserService;
/**
* 配置spring和junit整合,junit启动时加载springIOC容器 spring-test,junit
**/
@RunWith(SpringJUnit4ClassRunner.class)
// 告诉junit spring配置文件
@ContextConfiguration({ "classpath:applicationContext.xml" })
public class SpringMybatisTest {
@Autowired
private UserService userService;
/* @Autowired
private User user;*/
/* @Test
public void testLogin() {
//User user = new User();
user.setUsername("gler");
user.setPassword("123456");
System.out.println(userService.login(user).toString());
}*/
@Test
public void testSelectAllUser() {
List users = userService.selectAllUser();
for (User us : users) {
System.out.println(us.toString());
}
}
/* @Test
public void testAdd() {
//User user = new User();
user.setUsername("user2");
user.setPassword("123456");
user.setSex("female");
user.setAge(25);
userService.addUser(user);
}
@Test
public void testUpdate() {
//User user = new User();
user.setId(3);
user.setUsername("user2");
user.setPassword("123");
user.setSex("female");
user.setAge(30);
userService.updateUser(user);
}
@Test
public void testUpdate() {
int id = 3;
userService.deleteUser(id);
}*/
}
在这里,我们采用 Junit 进行单元测试,分别测试五个方法,这里只演示查询所有用户 testSelectAllUser()
方法,结果如下:
我们 user 表中只有一条数据,可以看到 Spring 和 MyBatis 已经整合成功。
如果想要在测试类中注入 User 对象,需要做两点:
@Autowired
private User user;
@Component
注解@Component
public class User {
private Integer id;
private String username;
private String password;
private String sex;
private Integer age;
......
}
注:但是一般实体类的对象不进行注入,而是由外部传入,这里是为了方便测试。
整合完 Spring 和 MyBatis 后,我们要完成 Spring MVC 的整合。
在包 gler.ssm.controller
下建一个 Controller 类 UserController.java
,代码如下:
package gler.ssm.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
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 gler.ssm.model.User;
import gler.ssm.service.UserService;
/**
* 处理用户请求 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 {
model.addAttribute("message", "username or password is wrong!");
return "loginform";
}
}
// 退出
@RequestMapping(value = "/loginout")
public String loginout(HttpSession session) {
session.invalidate();
return "loginform";
}
// 查询所有用户
@RequestMapping("/alluser")
public String selectAllUser(HttpServletRequest request) {
List 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 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 listUser = userService.selectAllUser();
request.setAttribute("listUser", listUser);
return "userlist";
}
// 删除用户
@RequestMapping("/deleteuser")
public String deleteUser(@Param("id") Integer id, HttpServletRequest request) {
userService.deleteUser(id);
List listUser = userService.selectAllUser();
request.setAttribute("listUser", listUser);
return "userlist";
}
}
9.1 loginform.jsp
在 WebContent/WEB-INF
目录下新建文件夹 jsp
,并在该路径下新建一个 JSP 页面命名为 loginform.jsp,作为登录页面,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login Pagetitle>
head>
<body>
<h4>Login Pageh4>
<form action="login" method="post">
<font color="red">${requestScope.message}font>
<table>
<tr>
<td><label>username:label>td>
<td><input type="text" id="username" name="username" />
tr>
<tr>
<td><label>password:label>td>
<td><input type="password" id="password" name="password" />
tr>
<tr>
<td><input type="submit" value="login" />
tr>
table>
form>
body>
html>
9.2 userlist.jsp
在 WebContent/WEB-INF/jsp
目录下新建一个 JSP 页面命名为 userlist.jsp,作为主页面,代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>ssmtitle>
<style type="text/css">
td {
text-align: center;
width: 100px;
}
style>
head>
<body>
<div align="right">
Welcome,[<font color=red>${sessionScope.user.username}font>] | <a
href="loginout">Exita>
div>
<br>
<center>
<table border="1">
<tbody>
<tr>
<th>idth>
<th>usernameth>
<th>passwordth>
<th>sexth>
<th>ageth>
<th colspan="2" style="">Optionsth>
tr>
<c:if test="${!empty listUser }">
<c:forEach items="${listUser}" var="user">
<tr>
<td>${user.id}td>
<td>${user.username}td>
<td>${user.password}td>
<td>${user.sex}td>
<td>${user.age}td>
<td><a href="toupdateuser?id=${user.id}">modifya>td>
<td><a href="deleteuser?id=${user.id}">deletea>td>
tr>
c:forEach>
c:if>
tbody>
table>
<br>
<a href="toadduser">Add a new usera>
center>
body>
html>
9.3 adduser.jsp
在 WebContent/WEB-INF/jsp
目录下新建一个 JSP 页面命名为 adduser.jsp,作为新增用户页面,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Add Pagetitle>
head>
<body>
<h4>AddUser Pageh4>
<form action="adduser" method="post">
<table>
<tr>
<td><label>username:label>td>
<td><input type="text" id="username" name="username" />
tr>
<tr>
<td><label>password:label>td>
<td><input type="password" id="password" name="password" />
tr>
<tr>
<td><label>sex:label>td>
<td><input type="text" id="sex" name="sex" />
tr>
<tr>
<td><label>age:label>td>
<td><input type="text" id="age" name="age" />
tr>
<tr>
<td><input type="submit" value="add" />
tr>
table>
form>
body>
html>
9.4 updateuser.jsp
在 WebContent/WEB-INF/jsp
目录下新建一个 JSP 页面命名为 updateuser.jsp,作为更新用户页面,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Modify Pagetitle>
head>
<body>
<h4>Modify Pageh4>
<form action="updateuser" method="post">
<table>
<tr>
<td><label>id:label>td>
<td><input type="text" id="id" name="id" value="${user_id}" readonly="readonly"/>
tr>
<tr>
<td><label>username:label>td>
<td><input type="text" id="username" name="username" />
tr>
<tr>
<td><label>password:label>td>
<td><input type="password" id="password" name="password" />
tr>
<tr>
<td><label>sex:label>td>
<td><input type="text" id="sex" name="sex" />
tr>
<tr>
<td><label>age:label>td>
<td><input type="text" id="age" name="age" />
tr>
<tr>
<td><input type="submit" value="modify" />
tr>
table>
form>
body>
html>
在目录 Java Resources/src
下新建 Spring MVC 配置文件 spring-mvc.xml
,代码如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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">
<context:component-scan base-package="gler.ssm.controller" />
<mvc:annotation-driven />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
bean>
beans>
现在我们来到整合的最后一步,配置 web.xml 文件,代码如下:
<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>SSMdisplay-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
context-param>
<servlet>
<servlet-name>springMVCservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring-mvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springMVCservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListenerlistener-class>
listener>
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<welcome-file-list>
<welcome-file>/WEB-INF/jsp/loginform.jspwelcome-file>
welcome-file-list>
web-app>
到这里,SSM 框架就全部整合完毕,接下来我们要进行测试。
在 Tomcat 上启动 SSM 工程:
输入错误的用户名或密码(我们最开始的数据是 username:gler,password:123456)。
当用户名和密码都正确的时候进入首页。
在这里一共只有一条数据。
点击下面的 Add a new user
链接,进入新增用户页面,并填写新增用户的信息。
点击 add
按钮,完整用户的新增操作,可以看到用户新增成功。
点击 id 为 2
的用户记录行的 modify
链接,进入更新用户页面,并填写更新信息。
点击 modify
按钮,完整用户的更新操作,可以看到用户信息更新成功。
点击 id 为 2
的用户记录行的 delete
链接,删除该用户。
点击右上角的 Exit
链接,退出主页到登录页面。
参考链接