1、框架介绍
1.1 SpringMVC框架
SpringMVC是一款基于MVC架构模式的轻量级Web框架,其目的是将Web开发模块化,对整体架构进行解耦,简化Web开发流程。SpringMVC基于请求驱动,即使用请求一响应模型。由于SpringMVC遵循MVC架构规范,因此分层开发数据模型层(Model)、响应视图层(View)和控制器层(Controller),可以让开发者设计出结构规整的Web层。
1.2 Spring框架
Spring的出现改变了Java世界。它的目标是使现有的JavaEE技术更易用和促进良好的编程习惯。它是一个轻量级的框架,渗透了JavaEE技术的方方面面。它主要作为依赖注入容器和AOP实现存在。还提供了声明事务、对DAO层的支持等简化开发的功能。Spring还可以很方便地与Struts、Hibernate、MyBatis等技术集成。
1.3 MyBatis框架
MyBatis是Apache的一个Java开源项目,是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生信息,将接口和Java的POJO(Plain Ordinary Java Object,普通的Java对象)映射成数据库中的记录。MyBatis的特点是,采用配置文件动态管理SQL语句,并含有输入映射、输出映射机制以及数据库连接池配置的持久层框架。
2、导入相关框架包
使用Maven进行项目的构建,pom.xml文件的配置如下:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.2.3.RELEASE</spring.version>
<logging.log4j.version>2.13.0</logging.log4j.version>
<dbcp.pool.version>2.7.0</dbcp.pool.version>
<jackson.version>2.10.2</jackson.version>
</properties>
<dependencies>
<!-- servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Spring框架 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- SpringMVC框架 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- MyBatis框架 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!-- MyBatis与Spring整合 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!-- MySQL的JDBC数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<!-- DBCP数据库连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>${dbcp.pool.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>${dbcp.pool.version}</version>
</dependency>
<!-- Log4j2日志记录框架 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${logging.log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${logging.log4j.version}</version>
</dependency>
<!-- JUnit5单元测试框架 -->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.6.0</version>
<scope>test</scope>
</dependency>
<!-- JSTL标签库 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jstl-impl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- jackson依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- 文件的上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
3、构建项目结构
如何使用IDEA与Maven创建JavaWeb项目并部署Tomcat服务:
请点击浏览本博客的文章:《使用IDEA和Maven创建JavaWeb项目并部署Tomcat服务》
创建JavaWeb项目,并构建项目结构,如下图:
(1)项目结构
在项目的src/main/java目录中,创建如下目录与文件:
包 | 说明 | 类型 | 创建类/接口 |
---|---|---|---|
com.pjb.ssm.entity | 实体层 | 类 | UserInfo.java |
com.pjb.ssm.dao | 数据库访问接口层 | 接口 | UserDao.java |
com.pjb.ssm.service | 业务逻辑接口层 | 接口 | UserService.java |
com.pjb.ssm.service.impl | 业务逻辑接口层 | 类 | UserServiceImpl.java |
com.pjb.ssm.model | 模型层 | 类 | UserModel.java |
com.pjb.ssm.util | 公共方法层 | 类 | UtilHelper.java |
com.pjb.ssm.controller | 控制器层 | 类 | UserController.java |
(2) 配置文件
在src/main/resources资源目录中,创建如下目录与文件:
文件名称 | 说明 |
---|---|
log4j2.xml | Log4j2日志记录框架的配置文件。 |
db.properties | 数据库连接属性文件。 |
mybatis/mybatis-config.xml | MyBatis全局配置文件。 |
spring/applicationContext.xml | Spring核心配置文件。 |
spring/spring-mvc.xml | SpringMVC配置文件。 |
spring/spring-mybatis.xml | Spring与MyBatis整合配置文件。 |
mapping/UserMapper.xml | MyBatis与数据对象的Mapper映射文件。 |
3.1 实体层(Entity层)
在com.pjb.ssm.entity包中,创建UserInfo.java(用户信息持久化类)。
UserInfo.java(用户信息实体类)代码如下:
package com.pjb.ssm.entity;
/**
* 用户信息实体类
* @author pan_junbiao
**/
public class UserInfo
{
private int userId; //用户编号
private String userName; //用户姓名
private String blogUrl; //博客地址
private int sex; //性别(1:男;2:女;)
private String provinceName; //省份
private String hobby; //兴趣爱好
private String remark; //备注
public int getUserId()
{
return userId;
}
public void setUserId(int userId)
{
this.userId = userId;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public String getBlogUrl()
{
return blogUrl;
}
public void setBlogUrl(String blogUrl)
{
this.blogUrl = blogUrl;
}
public int getSex()
{
return sex;
}
public void setSex(int sex)
{
this.sex = sex;
}
public String getProvinceName()
{
return provinceName;
}
public void setProvinceName(String provinceName)
{
this.provinceName = provinceName;
}
public String getHobby()
{
return hobby;
}
public void setHobby(String hobby)
{
this.hobby = hobby;
}
public String getRemark()
{
return remark;
}
public void setRemark(String remark)
{
this.remark = remark;
}
}
3.2 数据库访问层(Dao层)
在项目的数据库访问层中使用MyBatis动态代理。
(1)在配置文件目录(/resources/mapping目录)中创建SQL配置文件UserMapper.xml,注意其中namespace中的路径为即将创建的mapper代理接口的路径。
<?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.pjb.ssm.dao.UserDao">
<!-- 查询用户 -->
<select id="getUserById" parameterType="int" resultType="userInfo">
SELECT * FROM tb_user WHERE user_id = #{userId}
</select>
<!-- 新增用户 -->
<insert id="addUser" parameterType="userInfo">
INSERT INTO tb_user(user_name,blog_url,sex,province_name,hobby,remark)
VALUES(#{userName},#{blogUrl},#{sex},#{provinceName},#{hobby},#{remark});
</insert>
<!-- 修改用户 -->
<update id="updateUser" parameterType="userInfo">
UPDATE tb_user SET user_name=#{userName},blog_url=#{blogUrl},sex=#{sex},province_name=#{provinceName},hobby=#{hobby},remark=#{remark}
WHERE user_id = #{userId}
</update>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
DELETE FROM tb_user WHERE user_id = #{userId}
</delete>
</mapper>
(2)编写Mapper代理接口,在com.pjb.ssm.dao包中,创建UserDao.java(用户信息数据库访问接口)。
package com.pjb.ssm.dao;
import com.pjb.ssm.entity.UserInfo;
/**
* 用户信息数据库访问接口
* @author pan_junbiao
**/
public interface UserDao
{
/**
* 查询用户
*/
public UserInfo getUserById(int userId);
/**
* 新增用户
*/
public int addUser(UserInfo userInfo);
/**
* 修改用户
*/
public int updateUser(UserInfo userInfo);
/**
* 删除用户
*/
public int deleteUser(int userId);
}
3.3 业务逻辑层(Service层)
(1)在com.pjb.ssm.service包中,创建UserService.java(用户信息业务逻辑接口)。
package com.pjb.ssm.service;
import com.pjb.ssm.entity.UserInfo;
/**
* 用户信息业务逻辑接口
* @author pan_junbiao
**/
public interface UserService
{
/**
* 查询用户
*/
public UserInfo getUserById(int userId);
/**
* 新增用户
*/
public int addUser(UserInfo userInfo);
/**
* 修改用户
*/
public int updateUser(UserInfo userInfo);
/**
* 删除用户
*/
public int deleteUser(int userId);
}
(2)在com.pjb.ssm.service.impl包中,创建UserServiceImpl.java(用户信息业务逻辑类),该类实现UserService接口。
package com.pjb.ssm.service.impl;
import com.pjb.ssm.dao.UserDao;
import com.pjb.ssm.entity.UserInfo;
import com.pjb.ssm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 用户信息业务逻辑类
* @author pan_junbiao
**/
@Service
public class UserServiceImpl implements UserService
{
@Autowired
private UserDao userDao;
/**
* 查询用户
*/
public UserInfo getUserById(int userId)
{
return userDao.getUserById(userId);
}
/**
* 新增用户
*/
public int addUser(UserInfo userInfo)
{
return userDao.addUser(userInfo);
}
/**
* 修改用户
*/
public int updateUser(UserInfo userInfo)
{
return userDao.updateUser(userInfo);
}
/**
* 删除用户
*/
public int deleteUser(int userId)
{
return userDao.deleteUser(userId);
}
}
3.4 公共方法层(Util层)
在com.pjb.ssm.util包中,创建UtilHelper.java(公共处理类)。
package com.pjb.ssm.util;
/**
* 公共处理类
* @author pan_junbiao
*/
public class UtilHelper
{
/**
* 将数组转换成为字符串
*
* @param arr 字符串数组
* @param symbol 连接符号
* @return 字符串
*/
public static String arrToStr(String[] arr, String symbol)
{
// 实例化StringBuffer
StringBuffer sb = new StringBuffer();
// 判断arr是否为有效数组
if (arr != null && arr.length > 0)
{
// 遍历数组
for (String s : arr)
{
// 将字符串追加到StringBuffer中
sb.append(s);
// 将字符串追加到StringBuffer中
sb.append(symbol);
}
// 判断字符串长度是否有效
if (sb.length() > 0)
{
// 截取字符
sb = sb.deleteCharAt(sb.length() - 1);
}
}
// 返回字符串
return sb.toString();
}
}
3.5 模型层(Model层)
在com.pjb.ssm.model包中,创建UserModel.java(用户信息模型类)。
package com.pjb.ssm.model;
/**
* 用户信息模型类
* @author pan_junbiao
**/
public class UserModel
{
private int userId; //用户编号
private String userName; //用户姓名
private String blogUrl; //博客地址
private int sex; //性别(1:男;2:女;)
private String provinceName; //省份
private String hobbyStr; //兴趣爱好(字符串)
private String[] hobbyArray; //兴趣爱好(数组)
private String remark; //备注
public int getUserId()
{
return userId;
}
public void setUserId(int userId)
{
this.userId = userId;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public String getBlogUrl()
{
return blogUrl;
}
public void setBlogUrl(String blogUrl)
{
this.blogUrl = blogUrl;
}
public int getSex()
{
return sex;
}
public void setSex(int sex)
{
this.sex = sex;
}
public String getProvinceName()
{
return provinceName;
}
public void setProvinceName(String provinceName)
{
this.provinceName = provinceName;
}
public String getHobbyStr()
{
return hobbyStr;
}
public void setHobbyStr(String hobbyStr)
{
this.hobbyStr = hobbyStr;
}
public String[] getHobbyArray()
{
return hobbyArray;
}
public void setHobbyArray(String[] hobbyArray)
{
this.hobbyArray = hobbyArray;
}
public String getRemark()
{
return remark;
}
public void setRemark(String remark)
{
this.remark = remark;
}
}
3.6 控制器层(Controller层)
在com.pjb.ssm.controller包中,创建UserController.java(用户信息控制器)。
package com.pjb.ssm.controller;
import com.pjb.ssm.entity.UserInfo;
import com.pjb.ssm.model.UserModel;
import com.pjb.ssm.service.UserService;
import com.pjb.ssm.util.UtilHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
/**
* 用户信息控制器
* @author pan_junbiao
**/
@Controller
@RequestMapping("user")
public class UserController
{
@Autowired
private UserService userService;
/**
* 用户注册页面
*/
@RequestMapping("toUserRegisterView")
public String toUserRegisterView()
{
return "/user_register.jsp";
}
/**
* 新增用户
*/
@RequestMapping("addUser")
public ModelAndView addUser(UserModel userModel)
{
ModelAndView modelAndView = new ModelAndView();
//参数验证
if (userModel.getUserName() == null || userModel.getUserName().equals(""))
{
modelAndView.addObject("message","参数错误");
modelAndView.setViewName("/error.jsp");
return modelAndView;
}
//将Model对象转换为实体对象
UserInfo userInfo = new UserInfo();
userInfo.setUserName(userModel.getUserName());
userInfo.setBlogUrl(userModel.getBlogUrl());
userInfo.setSex(userModel.getSex());
userInfo.setProvinceName(userModel.getProvinceName());
userInfo.setHobby(UtilHelper.arrToStr(userModel.getHobbyArray(), ";"));
userInfo.setRemark(userModel.getRemark());
//调用业务逻辑层方法,执行新增操作
int resultExecute = userService.addUser(userInfo);
//返回结果页面
if(resultExecute>0)
{
modelAndView.addObject("message","新增用户成功");
modelAndView.setViewName("/success.jsp");
}
else
{
modelAndView.addObject("message","新增用户失败");
modelAndView.setViewName("/error.jsp");
}
return modelAndView;
}
/**
* 用户详情页面
*/
@RequestMapping("toUserDetailView")
public ModelAndView toUserDetailView(@RequestParam(value="user_id",defaultValue="0") int userId)
{
ModelAndView modelAndView = new ModelAndView();
//获取用户信息
UserInfo userInfo = userService.getUserById(userId);
if(userInfo==null)
{
modelAndView.addObject("message","未找到用户信息");
modelAndView.setViewName("/error.jsp");
return modelAndView;
}
//用户实体对象转换为Model对象
UserModel userModel = new UserModel();
userModel.setUserId(userInfo.getUserId());
userModel.setUserName(userInfo.getUserName());
userModel.setBlogUrl(userInfo.getBlogUrl());
userModel.setSex(userInfo.getSex());
userModel.setProvinceName(userInfo.getProvinceName());
userModel.setHobbyStr(userInfo.getHobby());
userModel.setRemark(userInfo.getRemark());
//返回结果
modelAndView.addObject("userModel",userModel);
modelAndView.setViewName("/user_detail.jsp");
return modelAndView;
}
}
4、项目配置文件
4.1 log4j2.xml 配置文件
在资源目录(resources目录)中,创建名称为 log4j2.xml 的配置文件,用于配置Log4j2日志功能,具体配置信息如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- log4j2 配置文件 -->
<!-- 日志级别 trace<debug<info<warn<error<fatal -->
<configuration status="debug">
<!-- 自定义属性 -->
<Properties>
<!-- 日志格式(控制台) -->
<Property name="pattern1">[%-5p] %d %c - %m%n</Property>
<!-- 日志格式(文件) -->
<Property name="pattern2">
==========================%n 日志级别:%p%n 日志时间:%d%n 所属类名:%c%n 所属线程:%t%n 日志信息:%m%n
</Property>
<!-- 日志文件路径 -->
<Property name="filePath">logs/myLog.log</Property>
</Properties>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${pattern1}"/>
</Console>
<RollingFile name="RollingFile" fileName="${filePath}"
filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout pattern="${pattern2}"/>
<SizeBasedTriggeringPolicy size="5 MB"/>
</RollingFile>
</appenders>
<loggers>
<root level="debug">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFile"/>
</root>
</loggers>
</configuration>
4.2 db.properties属性文件
在资源目录(resources目录)中,创建db.properties数据库连接配置文件,配置包含数据库的驱动,数据库的连接地址,登录名、登录密码、数据库连接池信息。具体配置信息如下:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_admin?useSSL=false&
jdbc.username=root
jdbc.password=123456
dbcp.pool.maxTotal=10
dbcp.pool.maxIdle=5
4.3 MyBatis配置
创建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>
<!-- 全局配置参数 -->
<settings>
<!-- 指定 MyBatis 所用日志的具体实现,未指定时将自动查找 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 开启自动驼峰命名规则(camel case)映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启延时加载开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 将积极加载改为消极加载(即按需加载),默认值就是false -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 打开全局缓存开关(二级环境),默认值就是true -->
<setting name="cacheEnabled" value="true"/>
<!-- 开启自动驼峰命名规则(camel case)映射 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 别名定义 -->
<typeAliases>
<package name="com.pjb.fms.entity"/>
</typeAliases>
</configuration>
4.4 Spring配置
4.4.1 Spring核心配置文件(applicationContext.xml)
创建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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- 该配置文件暂时为空 -->
</beans>
4.4.2 Spring与MyBatis整合配置文件(spring-mybatis.xml)
创建spring-mybatis.xml配置文件,在其中加载数据库连接配置文件“db.properties”中的数据,建立数据源,配置sqlSessionFactory会话工厂对象,具体配置信息如下:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- 1.加载用于数据库配置的属性文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 2.包扫描:entity,dao,service -->
<context:component-scan base-package="com.pjb.ssm.entity,com.pjb.ssm.dao,com.pjb.ssm.service"/>
<!-- 3.dataSource数据源,使用DBCP数据库连接池 -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<!-- 数据库驱动名称 -->
<property name="driverClassName" value="${jdbc.driver}"/>
<!-- 数据库连接底座 -->
<property name="url" value="${jdbc.url}"/>
<!-- 登录数据库的用户名 -->
<property name="username" value="${jdbc.username}"/>
<!-- 登录数据库的密码 -->
<property name="password" value="${jdbc.password}"/>
<!-- 连接池的最大数据库连接数,设置默认值0表示无限 -->
<property name="maxTotal" value="${dbcp.pool.maxTotal:0}"/>
<!-- 最大空闲数,即数据库连接的最大空闲时间。当超过空闲时间时,数据库连接将被标记为不可用,然后被释放,设置默认值0表示无限 -->
<property name="maxIdle" value="${dbcp.pool.maxIdle:0}"/>
</bean>
<!-- 4.配置SqlSessionFactory对象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
<!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
<!-- 扫描entity包 使用别名 -->
<property name="typeAliasesPackage" value="com.pjb.ssm.entity" />
<!-- 扫描sql配置文件:mapper需要的xml文件 -->
<property name="mapperLocations" value="classpath:mapping/*.xml" />
</bean>
<!-- 5.事务管理 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 事务通知 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="all*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 配置事务的代理 -->
<aop:config>
<!-- 定义一个切面 -->
<aop:pointcut id="allManagerMethod" expression="execution(* com.pjb.ssm.service.impl.*.*(..))"/>
<!-- 将事务通知与切面组合 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
</aop:config>
<!-- 6.配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
<!-- 给出需要扫描Dao接口包 -->
<property name="basePackage" value="com.pjb.ssm.dao" />
</bean>
</beans>
4.4.3 SpringMVC配置文件(spring-mvc.xml)
创建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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- 配置SpringMVC -->
<!-- 1.开启SpringMVC注解模式(设置注解映射器、注解适配器) -->
<mvc:annotation-driven />
<!-- 2.静态资源默认servlet配置
(1)加入对静态资源的处理:js,gif,png
(2)允许使用"/"做整体映射
-->
<mvc:default-servlet-handler/>
<!-- 3.内部资源视图解析器,prefix为空,方便跟参数url?id=xxx -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages"/>
<property name="suffix" value=""/>
</bean>
<!-- 4.使用扫描配置,对某一个包下的所有类进行扫描,找出所有使用@Controller注解的Handler控制器类 -->
<context:component-scan base-package="com.pjb.ssm.controller"></context:component-scan>
<!-- 多类型文件解析器、文件上传 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为1MB -->
<property name="maxUploadSize" value="1048576"/>
</bean>
</beans>
4.5 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_4_0.xsd"
version="4.0">
<!-- 自定义Spring主配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/*.xml</param-value>
</context-param>
<!-- 使用ContextLoaderListener初始化Spring容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- SpringMVC前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!-- 中文乱码过滤器 -->
<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>
<!-- 默认页面 -->
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
5、综合实例
【实例】使用SSM框架,实现用户信息的增删改查操作。
Web层和Test层的项目结构如下:
在MySQL数据库中创建 tb_user(用户信息数据表),脚本如下:
-- 判断数据表是否存在,存在则删除
DROP TABLE IF EXISTS tb_user;
-- 创建“用户信息”数据表
CREATE TABLE IF NOT EXISTS tb_user
(
user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号',
user_name VARCHAR(50) NOT NULL COMMENT '用户姓名',
blog_url VARCHAR(50) NOT NULL COMMENT '博客地址',
sex CHAR(2) DEFAULT '2' COMMENT '性别(1:男;2:女;)',
province_name VARCHAR(20) COMMENT '省份',
hobby VARCHAR(50) COMMENT '兴趣爱好',
remark VARCHAR(50) COMMENT '备注'
) COMMENT = '用户信息表';
5.1 新增用户信息
执行结果如下:
(1)首页:
(2)用户注册页面:
(3)操作成功页面
程序代码:
(1)在UserController.java(用户信息控制器类)中编写进入用户注册页面和执行新增用户操作的方法。
@Autowired
private UserService userService;
/**
* 用户注册页面
*/
@RequestMapping("toUserRegisterView")
public String toUserRegisterView()
{
return "/user_register.jsp";
}
/**
* 新增用户
*/
@RequestMapping("addUser")
public ModelAndView addUser(UserModel userModel)
{
ModelAndView modelAndView = new ModelAndView();
//参数验证
if (userModel.getUserName() == null || userModel.getUserName().equals(""))
{
modelAndView.addObject("message","参数错误");
modelAndView.setViewName("/error.jsp");
return modelAndView;
}
//将Model对象转换为实体对象
UserInfo userInfo = new UserInfo();
userInfo.setUserName(userModel.getUserName());
userInfo.setBlogUrl(userModel.getBlogUrl());
userInfo.setSex(userModel.getSex());
userInfo.setProvinceName(userModel.getProvinceName());
userInfo.setHobby(UtilHelper.arrToStr(userModel.getHobbyArray(), ";"));
userInfo.setRemark(userModel.getRemark());
//调用业务逻辑层方法,执行新增操作
int resultExecute = userService.addUser(userInfo);
//返回结果页面
if(resultExecute>0)
{
modelAndView.addObject("message","新增用户成功");
modelAndView.setViewName("/success.jsp");
}
else
{
modelAndView.addObject("message","新增用户失败");
modelAndView.setViewName("/error.jsp");
}
return modelAndView;
}
(2)创建 index.jsp(首页)。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
<meta name="author" content="pan_junbiao的博客">
</head>
<body>
<h1>首页</h1>
<a href="user/toUserRegisterView.action">用户注册</a></br>
<a href="user/toUserDetailView.action?user_id=1">用户详情</a>
</body>
</html>
(3)创建 user_register.jsp(用户注册页面)。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>用户注册</title>
<meta name="author" content="pan_junbiao的博客">
</head>
<body>
<style>
table{border-top: 1px solid #000000; border-left: 1px solid #000000; border-collapse: collapse;}
th, td{border-bottom: 1px solid #000000; border-right: 1px solid #000000; padding: 5px 10px;}
select{width: 100px; padding: 3px;}
.txtBox{padding: 3px;width: 300px;font-size: 16px;}
</style>
<form action="${pageContext.request.contextPath}/user/addUser.action" method="post" name="myForm">
<table align="center">
<caption>用户注册</caption>
<tr>
<th>用户姓名:</th>
<td>
<input class="txtBox" type="text" name="userName" value="pan_junbiao的博客"/>
</td>
</tr>
<tr>
<th>博客地址:</th>
<td>
<input class="txtBox" type="text" name="blogUrl" value="https://blog.csdn.net/pan_junbiao"/>
</td>
</tr>
<tr>
<th>性别:</th>
<td>
<input id="male" name="sex" type="radio" value="1" checked="checked"/>
<label for="male">男</label>
<input id="female" name="sex" type="radio" value="2"/>
<label for="female">女</label>
</td>
</tr>
<tr>
<th>省份:</th>
<td>
<select name="provinceName">
<option value="">请选择</option>
<option value="广东省">广东省</option>
<option value="江苏省">江苏省</option>
<option value="安徽省">安徽省</option>
</select>
</td>
</tr>
<tr>
<th>兴趣爱好:</th>
<td>
<input id="lq" name="hobbyArray" type="checkbox" value="篮球">
<label for="lq">篮球</label>
<input id="zq" name="hobbyArray" type="checkbox" value="足球">
<label for="zq">足球</label>
<input id="ymq" name="hobbyArray" type="checkbox" value="羽毛球">
<label for="ymq">羽毛球</label>
<input id="ppq" name="hobbyArray" type="checkbox" value="乒乓球">
<label for="ppq">乒乓球</label>
<input id="yy" name="hobbyArray" type="checkbox" value="游泳">
<label for="yy">游泳</label>
</td>
</tr>
<tr>
<th>备注信息:</th>
<td>
<input class="txtBox" type="text" name="remark" value="您好,欢迎访问 pan_junbiao的博客"/>
</td>
</tr>
<!-- 以下是提交、取消按钮 -->
<tr>
<td colspan="2" style="text-align: center; padding: 5px;">
<input type="submit" value="提交" />
<input type="reset" value="重置" />
</td>
</tr>
</table>
</form>
</body>
</html>
(4)创建 success.jsp(操作成功页面)。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>操作成功</title>
<meta name="author" content="pan_junbiao的博客">
</head>
<body>
<h1>恭喜,操作成功!</h1>
<span style="color:red"><%=request.getAttribute("message") == null ? "" : request.getAttribute("message")%></span>
</body>
</html>
(5)创建 error.jsp(操作失败页面)。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>操作失败</title>
<meta name="author" content="pan_junbiao的博客">
</head>
<body>
<h1>对不起,操作失败!</h1>
<span style="color:red"><%=request.getAttribute("message") == null ? "" : request.getAttribute("message")%></span>
</body>
</html>
5.2 获取用户信息
执行结果如下:
程序代码:
(1)在UserController.java(用户信息控制器类)中编写获取用户信息的方法。
/**
* 用户详情页面
*/
@RequestMapping("toUserDetailView")
public ModelAndView toUserDetailView(@RequestParam(value="user_id",defaultValue="0") int userId)
{
ModelAndView modelAndView = new ModelAndView();
//获取用户信息
UserInfo userInfo = userService.getUserById(userId);
if(userInfo==null)
{
modelAndView.addObject("message","未找到用户信息");
modelAndView.setViewName("/error.jsp");
return modelAndView;
}
//用户实体对象转换为Model对象
UserModel userModel = new UserModel();
userModel.setUserId(userInfo.getUserId());
userModel.setUserName(userInfo.getUserName());
userModel.setBlogUrl(userInfo.getBlogUrl());
userModel.setSex(userInfo.getSex());
userModel.setProvinceName(userInfo.getProvinceName());
userModel.setHobbyStr(userInfo.getHobby());
userModel.setRemark(userInfo.getRemark());
//返回结果
modelAndView.addObject("userModel",userModel);
modelAndView.setViewName("/user_detail.jsp");
return modelAndView;
}
(2)创建 user_detail.jsp(用户详情页面)。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>用户详情</title>
<meta name="author" content="pan_junbiao的博客">
<style>
table { border-collapse: collapse;}
table,table tr th, table tr td { border:1px solid #000000; padding: 5px 10px;}
</style>
</head>
<body>
<body>
<table align="center">
<caption>用户信息</caption>
<tr>
<th>用户编号</th>
<td>${userModel.userId}</td>
</tr>
<tr>
<th>用户姓名</th>
<td>${userModel.userName}</td>
</tr>
<tr>
<th>博客地址</th>
<td>${userModel.blogUrl}</td>
</tr>
<tr>
<th>性别</th>
<td>${userModel.sex==1?"男":"女"}</td>
</tr>
<tr>
<th>省份</th>
<td>${userModel.provinceName}</td>
</tr>
<tr>
<th>兴趣爱好</th>
<td>${userModel.hobbyStr}</td>
</tr>
<tr>
<th>备注信息</th>
<td>${userModel.remark}</td>
</tr>
</table>
</body>
</body>
</html>
5.3 修改用户和删除用户
执行修改用户和删除用户操作,使用Junit5框架进行测试,在com.pjb.ssm.test包中,创建UserTest.java(用户业务测试类)。
package com.pjb.ssm.test;
import com.pjb.ssm.entity.UserInfo;
import com.pjb.ssm.service.UserService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 用户业务测试类
* @author pan_junbiao
**/
public class UserTest
{
private ApplicationContext applicationContext;
private UserService userService;
@Before
public void setUp() throws Exception
{
//初始化Spring容器(上下文对象)
applicationContext = new ClassPathXmlApplicationContext("classpath:spring/spring-mybatis.xml");
//获取Bean对象
userService = (UserService) applicationContext.getBean("userServiceImpl");
}
@After
public void tearDown() throws Exception
{
System.out.println("测试完成!");
}
/**
* 修改用户
*/
@Test
public void updateUser()
{
UserInfo userInfo = new UserInfo();
userInfo.setUserId(1);
userInfo.setUserName("pan_junbiao的博客");
userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");
userInfo.setSex(2);
userInfo.setProvinceName("广东省");
userInfo.setHobby("篮球;足球;羽毛球;乒乓球;游泳");
userInfo.setRemark("您好,欢迎访问 pan_junbiao的博客");
//调用业务逻辑层方法,执行修改操作
int result = userService.updateUser(userInfo);
//打印结果
if(result>0)
{
System.out.println("修改成功");
}
else
{
System.out.println("修改失败");
}
}
/**
* 删除用户
*/
@Test
public void deleteUser()
{
//调用业务逻辑层方法,执行删除操作
int result = userService.deleteUser(1);
//打印结果
if(result>0)
{
System.out.println("删除成功");
}
else
{
System.out.println("删除失败");
}
}
}
5.4 日志功能
测试Log4j2日志记录功能,在com.pjb.ssm.test包中,创建LogTest.java(日志功能测试类)。
package com.pjb.ssm.test;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* 日志功能测试类
* @author pan_junbiao
**/
public class LogTest
{
Logger logger = LogManager.getLogger(LogTest.class);
@Before
public void setUp() throws Exception
{
logger.info("测试开始@Before");
}
@After
public void tearDown() throws Exception
{
logger.info("测试结束@After");
}
@Test
public void writeLogInfo()
{
logger.trace("trace level");
logger.debug("debug level");
logger.info("info level");
logger.warn("warn level");
logger.error("error level");
logger.fatal("fatal level");
}
}
执行结果:
源代码下载:https://github.com/kevinpanjunbiao/SSM
原文地址:https://blog.csdn.net/pan_junbiao/article/details/104511047