# ssm_project_demo **Repository Path**: sun_se_wang/ssm_project_demo ## Basic Information - **Project Name**: ssm_project_demo - **Description**: vue+spring+springmvc+mybatis模板 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-10-17 - **Last Updated**: 2023-10-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Vue SSM搭建一个简单的Demo前后端分离含增删改查(CRUD)、分页、批量功能 ### 前言 最近想复习一下SSM,所以就搭建了这个小DEMO,轻车熟路,个人认为在只用到SSM框架的前提下,这样做是最简洁的搭建方式了。写这篇博客也是复习的一部分,也想收获些意料之外的XXXX。 ### 用到的技术和开发工具 **前端** - 开发工具:WebStorm - 开发框架:vue + axios + elementUI - 包管理工具: npm - 打包工具:webpack **后端** - 开发工具:IDEA - 开发框架:springMVC + spring + mybatis - 打包工具:maven - 数据库: MySQL ### 需求及功能 - 增删改查(CRUD) - 分页 - 批量删除 - 前后端分离 ### 后台开发环境搭建 File->New->Project…->maven->.......百度 ### 后台代码 1. ssm_project/src/main/resources/applicationContext.xml ```xml ``` 2. ssm_project/src/main/resources/applicationContext-mvc.xml ```xml ``` 3. ssm_project/src/main/resources/mybatis-config.xml ```xml ``` 4. ssm_project/src/main/resources/db.properties ```properties jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssm_example?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true jdbc.username=root jdbc.password=123 ``` 5. ssm_project/src/main/resources/log4j.properties ```properties # Global logging configuration log4j.rootLogger=DEBUG,Console # Console output... log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n log4j.logger.org.apache=INFO ``` 6. ssm_project/src/main/webapp/WEB-INF/web.xml ```xml contextConfigLocation classpath:/applicationContext.xml org.springframework.web.context.ContextLoaderListener characterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 forceEncoding true characterEncodingFilter /* springMVC org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:applicationContext-mvc.xml 1 springMVC / org.springframework.web.context.request.RequestContextListener ``` 7. ssm_project/pom.xml ```xml 4.0.0 com.example ssm_project 0.0.1-SNAPSHOT war org.slf4j slf4j-api 1.7.12 ch.qos.logback logback-core 1.1.1 provided ch.qos.logback logback-classic 1.1.1 provided com.alibaba druid 1.0.25 org.mybatis mybatis 3.3.0 org.mybatis mybatis-spring 1.3.2 taglibs standard 1.1.2 jstl jstl 1.2 com.fasterxml.jackson.core jackson-databind 2.5.4 javax.servlet javax.servlet-api 3.1.0 provided org.springframework spring-core 4.3.14.RELEASE org.springframework spring-beans 4.3.14.RELEASE org.springframework spring-context 4.3.14.RELEASE org.springframework spring-jdbc 4.3.14.RELEASE org.springframework spring-tx 4.3.14.RELEASE org.springframework spring-web 4.3.14.RELEASE org.springframework spring-webmvc 4.3.14.RELEASE org.springframework spring-test 4.3.14.RELEASE mysql mysql-connector-java 5.1.38 runtime org.aspectj aspectjweaver 1.8.9 org.json json 20170516 org.apache.maven.plugins maven-compiler-plugin 1.8 1.8 ``` 8. ssm_project/src/main/java/com/example/pojo/User.java ```java package com.example.pojo; public class User { private String userId;//用户id private String cardType;//证件类型 private String cardNo;//证件号码 private String userName;//用户姓名 private String userSex;//用户性别 private String userAge;//用户年龄 private String userRole;//用户角色 public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getCardType() { return cardType; } public void setCardType(String cardType) { this.cardType = cardType; } public String getCardNo() { return cardNo; } public void setCardNo(String cardNo) { this.cardNo = cardNo; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserSex() { return userSex; } public void setUserSex(String userSex) { this.userSex = userSex; } public String getUserAge() { return userAge; } public void setUserAge(String userAge) { this.userAge = userAge; } public String getUserRole() { return userRole; } public void setUserRole(String userRole) { this.userRole = userRole; } } ``` 9. ssm_project/src/main/resources/mapper/UserMapper.xml ```xml user_id, card_type, card_no, user_name, user_sex, user_age, user_role insert into User() values(#{userId}, #{cardType}, #{cardNo}, #{userName}, #{userSex}, #{userAge}, #{userRole}) delete from user where user_id = #{userId,jdbcType=VARCHAR} delete from user where user_id in #{item,jdbcType=VARCHAR} update user card_no = #{cardNo,jdbcType=VARCHAR}, card_type = #{cardType,jdbcType=VARCHAR}, user_name = #{userName,jdbcType=VARCHAR}, user_sex = #{userSex,jdbcType=VARCHAR}, user_age = #{userAge,jdbcType=VARCHAR}, user_role = #{userRole,jdbcType=VARCHAR} where 1 = 1 and user_id = #{userId,jdbcType=VARCHAR} ``` 10. ssm_project/src/main/java/com/example/mapper/UserMapper.java ```java package com.example.mapper; import java.util.List; import com.example.pojo.User; import org.apache.ibatis.annotations.Param; public interface UserMapper { /** * 分页查询 User * @param startRows 起始页 * @return List */ List queryUserPage(Integer startRows); /** * 分页查询 User 带条件 * @param userName * @param userSex * @param startRows * @return */ List selectUserPage(@Param("userName")String userName, @Param("userSex")String userSex, @Param("startRows")Integer startRows); /** * 查询 User 个数 * @param userName * @param userSex * @return */ Integer getRowCount(@Param("userName")String userName, @Param("userSex")String userSex); /** * 添加 User * @param user * @return 返回码 */ Integer createUser(User user); /** * 根据 userId 删除用户 * @return 返回码 */ Integer deleteUserById(String userId); /** * 根据 userId 批量删除用户 * @param userIds * @return */ Integer deleteUserByIdList(@Param("list") List userIds); /** * 根据 userId 更新用户 * @return 返回码 */ Integer updateUserById(User user); } ``` 11. ssm_project/src/main/java/com/example/service/UserService.java ```java package com.example.service; import java.util.List; import com.example.pojo.User; import org.apache.ibatis.annotations.Param; public interface UserService { /** * 分页查询 User * @param startRows 起始页 * @return List */ List queryUserPage(Integer startRows); /** * 分页查询 User 带条件 * @param userName * @param userSex * @param startRows * @return */ List selectUserPage(@Param("userName")String userName, @Param("userSex")String userSex, @Param("startRows")Integer startRows); /** * 查询 User 个数 * @param userName * @param userSex * @return */ Integer getRowCount(@Param("userName")String userName, @Param("userSex")String userSex); /** * 添加 User * @param user * @return 返回码 */ Integer createUser(User user); /** * 根据 userId 删除用户 * @return 返回码 */ Integer deleteUserById(String userId); /** * 根据 userId 批量删除用户 * @param userIds * @return */ Integer deleteUserByIdList(@Param("list") List userIds); /** * 根据 userId 更新用户 * @return 返回码 */ Integer updateUserById(User user); } ``` 12. ssm_project/src/main/java/com/example/service/impl/UserServiceImpl.java ```java package com.example.service.impl; import java.util.List; import com.example.pojo.User; import org.apache.ibatis.annotations.Param; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.example.mapper.UserMapper; import com.example.service.UserService; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public List queryUserPage(Integer startRows) { return userMapper.queryUserPage(startRows); } @Override public List selectUserPage(String userName, String userSex, Integer startRows) { return userMapper.selectUserPage(userName, userSex, startRows); } @Override public Integer getRowCount(String userName, String userSex) { return userMapper.getRowCount(userName, userSex); } @Override public Integer createUser(User user) { return userMapper.createUser(user); } @Override public Integer deleteUserById(String userId) { return userMapper.deleteUserById(userId); } @Override public Integer deleteUserByIdList(@Param("list") List userIds) { return userMapper.deleteUserByIdList(userIds); } @Override public Integer updateUserById(User user) { return userMapper.updateUserById(user); } } ``` 13. ssm_project/src/main/java/com/example/controller/UserController.java ```java package com.example.controller; import java.util.ArrayList; import java.util.List; import java.util.Random; import com.example.pojo.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.example.service.UserService; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("user") public class UserController { @Autowired private UserService userService; @RequestMapping("/queryUserPage") @ResponseBody public List queryUserPage(Integer page) { int pageNow = page == null ? 1 : page; int pageSize = 5; int startRows = pageSize*(pageNow-1); return userService.queryUserPage(startRows); } @RequestMapping("/selectUserPage") @ResponseBody public List selectUserPage(String userName, String userSex, Integer page) { int pageNow = page == null ? 1 : page; int pageSize = 5; int startRows = pageSize*(pageNow-1); return userService.selectUserPage(userName, userSex, startRows); } @RequestMapping("/getRowCount") @ResponseBody public Integer getRowCount(String userName, String userSex) { return userService.getRowCount(userName, userSex); } @RequestMapping("/createUser") @ResponseBody public Integer createUser(User user) { Random random = new Random(); Integer number = random.nextInt(9000) + 1000; user.setUserId(System.currentTimeMillis() + String.valueOf(number)); return userService.createUser(user); } @RequestMapping("/deleteUserById") @ResponseBody public Integer deleteUserById(String userId) { return userService.deleteUserById(userId); } @RequestMapping(value = "/deleteUserByIdList") @ResponseBody public Integer deleteUserByIdList(String userIdList) { String userIdListSub = userIdList.substring(0, userIdList.length()-1); // String[] userIds = userIdList.split(","); List userIds = new ArrayList(); for (String userIdStr: userIdListSub.split(",")){ userIds.add(userIdStr.trim()); } return userService.deleteUserByIdList(userIds); } @RequestMapping("/updateUserById") @ResponseBody public Integer updateUserById(User user) { return userService.updateUserById(user); } } ``` 14. SQL ```sql -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '', `card_type` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `card_no` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `user_sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `user_age` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `user_role` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`user_id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('15968162087363060', '身份证', '4264465547656467', '过突然', '男', '30', '办事人员和有关人员'); INSERT INTO `user` VALUES ('15968162346981977', '护照', '432532654364654', '规划图', '男', '29', '不便分类的其他从业人员'); INSERT INTO `user` VALUES ('15968162893439470', '身份证', '4354324534532', '具体办1', '男', '31', '农、林、牧、渔、水利业生产人员'); INSERT INTO `user` VALUES ('15968163245457143', '身份证', '43564546576687', '回各家', '男', '34', '未知'); INSERT INTO `user` VALUES ('15968163514764733', '军官证', '7657868', '缺口v4', '女', '23', '不便分类的其他从业人员'); INSERT INTO `user` VALUES ('15968165113694372', '台湾往来大陆通行证', '343214321412433214', '遗体ioy', '女', '48', '生产、运输设备操作人员及有关人员'); INSERT INTO `user` VALUES ('15968165371931786', '港澳居民通行证', '65765887989090909', '垂直发射的', '女', '35', '不便分类的其他从业人员'); INSERT INTO `user` VALUES ('15968941217553030', '身份证', '34354657665768768', '撒撒到', '男', '22', '军人'); INSERT INTO `user` VALUES ('15968943937844616', '身份证', '4454534436565756', '出手大', '女', '31', '不便分类的其他从业人员'); INSERT INTO `user` VALUES ('15968944123869023', '护照', '43225465457657', 'VCD法国', '女', '39', '农、林、牧、渔、水利业生产人员'); INSERT INTO `user` VALUES ('15968953962316864', '身份证', '342354325', '房东是个大帅哥', '女', '33', '商业、服务业人员'); INSERT INTO `user` VALUES ('15968954638794962', '身份证', '343343554654', '撒撒旦', '女', '29', '生产、运输设备操作人员及有关人员'); SET FOREIGN_KEY_CHECKS = 1; ``` **后台到这里就写完了,结构如下:** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810225636464.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW55dXd1eWk=,size_16,color_FFFFFF,t_70) ### 前台开发环境搭建 ![SSM_list](https://img-blog.csdnimg.cn/20200810223437952.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW55dXd1eWk=,size_16,color_FFFFFF,t_70) ### 前台代码 15. vue_project/src/App.vue ```html ``` 16. vue_project/src/main.js ```js // The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue'; import App from './App'; import router from './router'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import qs from 'qs'; import axios from "axios"; Vue.config.productionTip = false; Vue.use(ElementUI); Vue.prototype.axios = axios; Vue.prototype.qs = qs; /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '' }) ``` 17. vue_project/src/components/UserHome.vue ```html ``` 18. vue_project/src/router/index.js ```js import Vue from 'vue'; import Router from 'vue-router'; import HelloWorld from '@/components/HelloWorld' import UserHome from '@/components/UserHome' Vue.use(Router) export default new Router({ routes: [ { path: '/HelloWorld', name: 'HelloWorld', component: HelloWorld }, { path: '/', name: 'UserHome', component: UserHome } ] }) ``` **前台结构如下:** ![前台结构](https://img-blog.csdnimg.cn/20200810225426694.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW55dXd1eWk=,size_16,color_FFFFFF,t_70) ### 前后台整合 vue_project/config/index.js ```js dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: { '/': { target: 'http://localhost:8080', changeOrigin: true, pathRewrite: { '^/': '' } }, '/ws/*': { target: 'ws://127.0.0.1:8080', ws: true } }, // Various Dev Server settings host: 'localhost', // can be overwritten by process.env.HOST port: 8082, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined autoOpenBrowser: false, errorOverlay: true, notifyOnErrors: true, poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- // Use Eslint Loader? // If true, your code will be linted during bundling and // linting errors and warnings will be shown in the console. useEslint: true, // If true, eslint errors and warnings will also be shown in the error overlay // in the browser. showEslintErrorsInOverlay: false, /** * Source Maps */ // https://webpack.js.org/configuration/devtool/#development devtool: 'cheap-module-eval-source-map', // If you have problems debugging vue-files in devtools, // set this to false - it *may* help // https://vue-loader.vuejs.org/en/options.html#cachebusting cacheBusting: true, cssSourceMap: true }, ``` ### 实现效果 **视频** [video(video-Wq1iRAuM-1597070693731)(type-bilibili)(url-https://player.bilibili.com/player.html?aid=499139068)(image-https://ss.csdn.net/p?http://i1.hdslb.com/bfs/archive/2de6a570a4bd4399af72292c671a454784aa0c35.jpg)(title-Vue SSM搭建一个简单的Demo含增删改查(CRUD)、分页、批量功能)] **图片** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810224334554.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW55dXd1eWk=,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810224334582.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW55dXd1eWk=,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810224334558.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW55dXd1eWk=,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810224334563.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW55dXd1eWk=,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810224334553.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW55dXd1eWk=,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810224334550.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW55dXd1eWk=,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200810224334550.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ppYW55dXd1eWk=,size_16,color_FFFFFF,t_70) ### 值得扩展的功能或方向 1. 用户登录拦截功能:前端需要封装一下axios,后端需引入shiro; 2. 增加动态菜单,根据用户角色; 3. excel文件批量导入导出用户数据功能:还没想好用啥插件; 4. 引入富文本编辑器:主要为了再建一张表让业务复杂些; 5. 去大厂的开放平台找点牛逼的API引到project里; ### 结语 有问题请留言 CSDN: 博客园:[https://blog.csdn.net/jianyuwuyi/article/details/107924066](https://blog.csdn.net/jianyuwuyi/article/details/107924066) GitHub:[https://github.com/Aizhuxueliang/ssm_project](https://github.com/Aizhuxueliang/ssm_project)