Spring综合练习 —— 基于Spring+SpringMVC的后台管理系统Demo案例
2022-08-03 09:57:03
93
{{single.collect_count}}

往期文章

Spring01 —— Spring概念及快速入门
Spring02 —— Spring配置文件详解和依赖注入
Spring03 —— SpringAPI和在Spring中配置数据源
Spring04 —— Spring的注解开发
Spring05 —— Spring集成Junit
Spring06 —— Spring集成web环境
SpringMVC01 —— SpringMVC简介&快速入门
SpringMVC02 —— SpringMVC的各组件详解
SpringMVC03 —— Spring的请求和响应
Spring07 —— Spring JdbcTemplate的相关操作


在之前我们已经学习了Spring和SpringMVC。Spring的每一层都提供了相应的解决方案,web层有SpringMVC,整体Spring有Spring容器和di依赖注入,我们可以将每一层的bean都交由Spring去产生,dao层有Spring jdbctemplate,所以可以基于上述技术做一个案例小练习。
资料下载地址:
https://pan.baidu.com/s/1HuKBWv94S6Scrs9VzpU-vQ?pwd=itch
提取码:itch


一、环境搭建

1、创建一个新的module

在这里插入图片描述

2、导入静态页面

在这里插入图片描述

3、导入依赖坐标

<?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.zhou</groupId><artifactId>spring_ExampleTest</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.32</version></dependency><dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>0.9.1.2</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.0.1</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.2.1</version><scope>provided</scope></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.0</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.9.0</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.3</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.7</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.0.5.RELEASE</version></dependency><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency></dependencies></project>

4、创建包结构

在这里插入图片描述

5、准备数据库环境

在这里插入图片描述

导入成功!

在这里插入图片描述

6、创建实体类

用户实体类

package com.itch.exercise.domain;public class User {private Long id;private String username;private String email;private String password;private String phoneNum;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getPhoneNum() {return phoneNum;}public void setPhoneNum(String phoneNum) {this.phoneNum = phoneNum;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", email='" + email + '\'' +", password='" + password + '\'' +", phoneNum='" + phoneNum + '\'' +'}';}}

角色实体类

package com.itch.exercise.domain;public class Role {private Long id;private String roleName;private String roleDesc;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getRoleName() {return roleName;}public void setRoleName(String roleName) {this.roleName = roleName;}public String getRoleDesc() {return roleDesc;}public void setRoleDesc(String roleDesc) {this.roleDesc = roleDesc;}@Overridepublic String toString() {return "Role{" +"id=" + id +", roleName='" + roleName + '\'' +", roleDesc='" + roleDesc + '\'' +'}';}}

7、创建相关配置文件

1、创建log4j配置文件

在这里插入图片描述

2、创建jdbc.properties

在这里插入图片描述

3、创建applicationContext.xml

在spring的核心配置文件中我们只需要配置数据源和配置jdbc的模板对象

<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--1、加载jdbc.properties--><context:property-placeholder location="classpath:jdbc.properties"/><!--2、配置数据源--><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.driver}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="user" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--3、配置jdbctemplate--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource" /></bean></beans>

4、创建spring-mvc.xml

在spring-mvc.xml文件中我们需要配置springMVC的注解驱动、视图解析器、静态资源访问权限的开放

<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--1、springMVC的注解驱动--><mvc:annotation-driven/><!--2、配置视图解析器--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--前缀--><property name="prefix" value="/pages/"/><!--后缀--><property name="suffix" value=".jsp"/></bean><!-- 3、放行静态资源的访问权限 --><mvc:default-servlet-handler /></beans>

spring和Spring个mvc想集成到web项目中需要配置web.xml

5、web.xml

在web.xml中配置spring的监听器,springMVC的前端控制器

<?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"><!--全局的初始化参数--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><!--Spring的监听器--><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!--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><!--服务器启动时就创建--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>

二、功能实现

2.1、角色列表展示

需求:点击角色管理展示所有角色信息

思路:

①点击角色管理菜单发送请求到服务器端(修改角色管理菜单的url地址)

②创建RoleController和list()方法

③创建RoleService和list()方法

④创建RoleDao和findAll()方法

⑤使用JdbcTemplate完成查询操作

⑥将查询数据存储到modelAndView中

⑦转发到role-list.jsp页面进行展示

dao层

public interface RoleDao {public List<Role> findAllRole();}
public class RoleDaoImpl implements RoleDao {// 通过set注入jdbctemplateprivate JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}public List<Role> findAllRole() {// 定义sqlString sql = "select * from sys_role";// 执行sqlList<Role> roleList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Role>(Role.class));return roleList;}}

service层

public interface RoleService {public List<Role> findAllRole();}
public class RoleServiceImpl implements RoleService {// 通过set注入RoleDaoprivate RoleDao roleDao;public void setRoleDao(RoleDao roleDao) {this.roleDao = roleDao;}public List<Role> findAllRole() {return roleDao.findAllRole();}}

controller层

@Controller@RequestMapping("/role")public class RoleController {// 注入RoleService@Autowiredprivate RoleService roleService; @RequestMapping("/list")public ModelAndView listRole(){List<Role> roleList = roleService.findAllRole();System.out.println(roleList);ModelAndView modelAndView = new ModelAndView();// 设置模型modelAndView.addObject("roleList",roleList);// 设置视图modelAndView.setViewName("role-list");// 返回ModelAndViewreturn modelAndView;}}

前端代码

修改侧边栏得到请求路径

在这里插入图片描述

前端页面数据展示 role-list.jsp

引入jstl

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

在这里插入图片描述


配置相关文件

配置spring-mvc.xml开启组件扫描

<!-- 4、开启组件扫描 只扫描controller层 --><context:component-scan base-package="com.itch.test.controller" />

配置applicationContext.xml

<!--配置RoleDao--><bean id="roleDao" class="com.itch.test.dao.impl.RoleDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean><!--配置RoleService--><bean id="roleService" class="com.itch.test.service.impl.RoleServiceImpl"><property name="roleDao" ref="roleDao" /></bean>

部署测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

刷新页面

在这里插入图片描述

2.2、添加角色

需求:点击新建 创关键一个新的角色

在这里插入图片描述

dao层

/** * 添加角色 * @param role */public void saveRole(Role role);
public void saveRole(Role role) {String sql = "insert into sys_role values(null,?,?)";jdbcTemplate.update(sql,role.getRoleName(),role.getRoleDesc());}

service层

/** * 添加角色 * @param role */public void saveRole(Role role);
public void saveRole(Role role) {roleDao.saveRole(role);}

controller层

controller层调用service层进行保存 重定向到list进行查询

@RequestMapping("/save")public String save(Role role){roleService.saveRole(role);return "redirect:/role/list";}

前端代码

在这里插入图片描述

全局乱码过滤器

由于是使用post请求方式,所以存在乱码问题,配置全局乱码过滤器

<!--全局乱码过滤器--><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></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

部署测试

在这里插入图片描述

2.3、删除角色

需求:点击删除按钮删除该角色

dao层

/** * 删除角色 * @param id 根据id删除角色 */public void deleteRole(int id);
public void deleteRole(int id) {String sql = "delete from sys_role where id = ?";jdbcTemplate.update(sql,id);}

service层

/** * 删除角色 * @param id */public void deleteRole(int id);
public void deleteRole(int id) {roleDao.deleteRole(id);}

controller层

@RequestMapping("/delete")public String delete(String id){int rid = Integer.parseInt(id);roleService.deleteRole(rid);return "redirect:/role/list";}

前端代码

在这里插入图片描述

部署测试

在这里插入图片描述

2.4、用户列表展示

需求:点击用户管理查询数据库 展示所有用户信息

思路:

①点击用户管理菜单发送请求到服务器端(修改用户管理菜单的url地址)

②创建UserController和list()方法

③创建UserService和list()方法

④创建UserDao和fifindAll()方法

⑤使用JdbcTemplate完成查询操作

⑥将查询数据存储到modelAndView中

⑦转发到user-list.jsp页面进行展示

编码:

dao层

public interface UserDao {/** * 查询所有用户 * @return */public List<User> findAllUser();}
public class UserDaoImpl implements UserDao {// 注入jdbctemplateprivate JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}public List<User> findAllUser() {String sql = "select * from sys_user";List<User> userList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class));return userList;}}

service层

public interface UserService {/** * 查找所有用户 * @return */public List<User> findAllUser();}
public class UserServiceImpl implements UserService {// 注入userDaoprivate UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}public List<User> findAllUser() {return userDao.findAllUser();}}

controller层

@Controller@RequestMapping("/user")public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/list")public ModelAndView list(){List<User> userList = userService.findAllUser();ModelAndView modelAndView = new ModelAndView();modelAndView.addObject("userList",userList);modelAndView.setViewName("user-list");return modelAndView;}}

配置文件

在spring核心配置文件application.xml中添加如下配置:

<!--配置userDao--><bean id="userDao" class="com.itch.test.dao.impl.UserDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean><!--配置userService--><bean id="userService" class="com.itch.test.service.impl.UserServiceImpl"><property name="userDao" ref="userDao" /></bean>

前端代码

在这里插入图片描述

在这里插入图片描述

部署测试

在这里插入图片描述

发现问题:用户具有的角色我们并不能够查出来,所以查询用户的时候关联查询出该用户所具有的所有角色信息,需要完善查询用户的service层代码

所以我们需要在业务层UserService中向每一个User封装角色信息roles

dao层处理简单业务 service层处理复杂业务

【1】给User实体类添加roles属性

在这里插入图片描述

【2】在UserService中完善代码

public List<User> findAllUser() {List<User> userList = userDao.findAllUser();// 封装每一个user的roles数据for (User user : userList) {Long id = user.getId();//获得每个用户的id// 将id作为参数查询出当前用户对应的具有的角色信息 根据userId查询出roleId 再根据roleId查询出角色信息List<Role> roles = roleDao.findRolesById(id);// 将roles设置到useruser.setRoles(roles);}return userList;}

这里我们需要在UserService中也注入roleDao,注意在配置文件中进行相应的注入。

在这里插入图片描述

【3】在RoleDao中添加根据id查询角色信息

 /** * 根据id查询角色 * @param id * @return */public List<Role> findRolesById(Long id);
 public List<Role> findRolesById(Long id) {List<Role> roleList = null;try {String sql = "SELECT * FROM sys_role r,sys_user_role ur WHERE ur.`roleId` = r.`id` AND ur.`userId` = ?";roleList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Role>(Role.class), id);} catch (DataAccessException e) {e.printStackTrace();}return roleList;}

【4】修改前端代码

在这里插入图片描述

【5】部署测试

在这里插入图片描述

2.5、添加用户

第一步:查询角色信息展示

在这里插入图片描述

新建用户时,点击新建按钮先去到添加用户的页面user-add.jsp,在添加用户页面需要展示可供选择的角色信息,因此来到添加页面时需要查询所有的角色信息并展示。所以第一步需要查询出角色信息而不是直接跳转到新增个用户页面

dao层

在之前的角色管理中我们已经写了查询所有角色的dao实现,所以我们只需要使用就行

controller层

在userController中新增一个方法,是为了查询角色并展示到页面

@RequestMapping("/saveUserUI")public ModelAndView saveUserUI(){ModelAndView modelAndView = new ModelAndView();List<Role> roleList = roleService.findAllRole();modelAndView.addObject("roleList",roleList);modelAndView.setViewName("user-add");return modelAndView;}

前端代码

在这里插入图片描述

在这里插入图片描述

测试

在这里插入图片描述

第二步:添加用户功能实现

添加用户,需要向sys_user表中存放数据,也需要向sys_user_role表中存放数据

所以需要接收的参数一个是user 一个是选择的角色id们,添加用户时用户分配的角色信息应存储到中间表sys_user_role表中,需要用户的id,角色的id,而角色的id由前台页面点选的,用户的id应该是在保存操作由mysql主键自动生成的,那如何获取mysql自增的主键值呢?

controller层

@RequestMapping("/saveUser")public String saveUser(User user,Long[] roleIds){userService.addUser(user,roleIds);return "redirect:/user/list";}

service层

public void addUser(User user, Long[] roleIds) {// 1、向sys_user表中存储数据 该方法的返回值是自增生成的主键idLong userId = userDao.addUser(user);// 2、向sys_user_role关系中间表中存储多条数据 映射用户id和角色userDao.saveUserRoleRelation(userId,roleIds);}

这里发现在存放数据到sys_user表的时候,由于后续需要使用到自动生成的主键id,所以需要返回自动生成的主键id,那么关键问题就在于怎样返回自动生成的主键id呢?

其实jdbctemplate有一个API可以帮助我们返回生成的主键id,这个API相对比较复杂
通过自定义底层的preparestatement开启返回自动生成的主键id
所以dao层的代码编写如下;

dao层

添加用户的dao层操作:

public Long addUser(final User user) {// 1、创建PrepareStatementCreatorPreparedStatementCreator creator = new PreparedStatementCreator(){public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {// 使用原始的jdbc完成一个preparestatement的创建String sql = "isnert into sys_user values(?,?,?,?,?)";PreparedStatement preparedStatement = connection.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);preparedStatement.setObject(1,null);preparedStatement.setString(2,user.getUsername());preparedStatement.setString(3,user.getEmail());preparedStatement.setString(4,user.getPassword());preparedStatement.setString(5,user.getPhoneNum());return preparedStatement;}};// 2、创建keyHolderGeneratedKeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update(creator,keyHolder);// 3、通过keyholder获得生成的主键long userId = keyHolder.getKey().longValue();return userId;}

添加用户月角色映射的dao层操作:

public void saveUserRoleRelation(Long userId, Long[] roleIds) {// 向关系表中保存用户id对应的角色idfor (Long roleId : roleIds) {jdbcTemplate.update("insert into sys_user_role values(?,?)",userId,roleId);}}

部署测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.6、删除用户

需求:点击删除按钮删除该用户

思路:

①点击用户列表的删除按钮,发送请求到服务器端

②编写UserController的del()方法

③编写UserService的del()方法

⑤编写UserDao的delUserRoleRel()方法

⑥跳回当前用户列表页面

完成用户的删除操作,不仅要删除用户表数据,同时需要将用户和角色的关联表数据进行删除

dao层

/** * 删除用户* @param userId */public void deleteUser(Long userId);/** * 删除用户与角色的关系 * @param userId */public void deleteRelation(Long userId);
public void deleteUser(Long userId) {String sql = "delete from sys_user where id = ?";jdbcTemplate.update(sql, userId);}public void deleteRelation(Long userId) {String sql = "delete from sys_user_role where userId = ?";jdbcTemplate.update(sql,userId);}

service层

public void deleteUser(Long uid);
public void deleteUser(Long uid) {// 要先删除关系表userDao.deleteRelation(uid);// 再删除user表userDao.deleteUser(uid);}

controller层

@RequestMapping("/delete/{uid}")public String deleteUser(@PathVariable("uid") Long id){userService.deleteUser(id);return "redirect:/user/list";}

前端代码:

在这里插入图片描述

部署测试

在这里插入图片描述

在这里插入图片描述

回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}