Springboot后台管理(CRUD)

一:前言

这个就是用springboot实现后台管理(CRUD)的小demo,相比于SSM的配置地狱,springboot的自动配置确实很牛,tomcat都内置,我们想要修改相关的信息只要在yaml配置文件修改就行了,关于Dao层,这个mybatis-plus,quo实是很牛逼,这个连sql都是省略了,但也仅限于单表的sql,复杂的sql语句还得靠mapper.xml中进行书写。总之一句话,你不学SSM,springboot里面很多原理不理解,但是学了springboot,SSM配置起来是真麻烦。

二:用到的相关技术

spingboot(2.6.3)+Mybatis-Plus+Maven+thmeleaf+Mysql
环境是JDK1.8,maven是3.4.1,mysql5.7

三:实现功能流程

  • 在springboot官方文档中找到对应的 场景启动器(starter)
  • 分析其–xxxautoConfigration
  • 然后找到xxxxProperties绑定了配置文件有哪些。
  • 哪些需要修改 还是自定义

四:功能展示

1:登录首页

在这里插入图片描述

2:主页面

在这里插入图片描述

3:展示表单(select)

在这里插入图片描述

4:删除一条记录(delete)

点击删除 会自动删除,同时的话,在那页删除还会自动回到那页,这里就是点击删除 发送这个请求的时候,把当前页的信息也给发送处理的请求的,所以请求里信息会被Controller层处理,处理完请求在把该页信息用到反应请求的路径上。
在这里插入图片描述

5:修改一条记录(Update)

在这里插入图片描述
修改页面:
在这里插入图片描述

6:增加一条记录信息(insert)

在这里插入图片描述
在这里插入图片描述

五:上码

1:导入相关场景启动器

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.wyj</groupId><artifactId>springboot-05-web02</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-05-web02</name><description>springboot-05-web02</description><properties><java.version>11</java.version><repackage.classifier/><spring-native.version>0.11.2</spring-native.version><kotlin.version>1.6.20-M1</kotlin.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--导入jdbc的场景启动器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><!--导入数据库的驱动包  因为我们不知道到底是哪个驱动器  mysql 还是其他的 --><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!--导入Mybatis-Plus的场景--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.jetbrains.kotlin</groupId><artifactId>kotlin-stdlib-jdk8</artifactId><version>${kotlin.version}</version></dependency><dependency><groupId>org.jetbrains.kotlin</groupId><artifactId>kotlin-test</artifactId><version>${kotlin.version}</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes><classifier>${repackage.classifier}</classifier><image><builder>paketobuildpacks/builder:tiny</builder><env><BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE></env></image></configuration></plugin><plugin><groupId>org.springframework.experimental</groupId><artifactId>spring-aot-maven-plugin</artifactId><version>${spring-native.version}</version><executions><execution><id>test-generate</id><goals><goal>test-generate</goal></goals></execution><execution><id>generate</id><goals><goal>generate</goal></goals></execution></executions></plugin><plugin><groupId>org.jetbrains.kotlin</groupId><artifactId>kotlin-maven-plugin</artifactId><version>${kotlin.version}</version><executions><execution><id>compile</id><phase>compile</phase><goals><goal>compile</goal></goals></execution><execution><id>test-compile</id><phase>test-compile</phase><goals><goal>test-compile</goal></goals></execution></executions><configuration><jvmTarget>1.8</jvmTarget></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><executions><execution><id>compile</id><phase>compile</phase><goals><goal>compile</goal></goals></execution><execution><id>testCompile</id><phase>test-compile</phase><goals><goal>testCompile</goal></goals></execution></executions></plugin></plugins></build><repositories><repository><id>spring-releases</id><name>Spring Releases</name><url>https://repo.spring.io/release</url><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>spring-releases</id><name>Spring Releases</name><url>https://repo.spring.io/release</url><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories><profiles><profile><id>native</id><properties><repackage.classifier>exec</repackage.classifier><native-buildtools.version>0.9.9</native-buildtools.version></properties><dependencies><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-launcher</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId><version>${native-buildtools.version}</version><extensions>true</extensions><executions><execution><id>test-native</id><phase>test</phase><goals><goal>test</goal></goals></execution><execution><id>build-native</id><phase>package</phase><goals><goal>build</goal></goals></execution></executions></plugin></plugins></build></profile></profiles></project>

2:yaml配置文件

spring:datasource:url: jdbc:mysql://localhost:3306/smbms?useSSL=trueusername: rootpassword: wyjdriver-class-name: com.mysql.jdbc.Driver#Mybatis-plus配置
mybatis-plus:#全局配置文件的路径config-location: classpath:mybatis/mybatis-config.xml#指明.xml文件的路径mapper-locations: classpath:mybatis/mapper/*.xml

3:Pojo

(1):admin

package com.wyj.Pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Admin {private String userName;private String passWord;
}

(2):User

package com.wyj.Pojo;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "userTO")
public class User {//Mybatis-Plus的测试数据private Integer id;private String name;private Integer age;private String email;}

4:mapper

这里继承了BaseMapper,很多sql就不用写了,这里还需要注意 的是,默认的表明是和类名一致的,如过类名和表名不一致的话,需要用注解@TableName 把表名注上

package com.wyj.mapper;import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.wyj.Pojo.User;
import org.apache.ibatis.annotations.Mapper;import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;@Mapper
public interface UserMapper extends BaseMapper<User> {}

5:Service层

(1)Service接口

package com.wyj.Service;import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyj.Pojo.User;
import com.wyj.mapper.UserMapper;import java.util.List;public interface UserService extends IService<User>  {}

(2):Service的实现类

package com.wyj.Service.imp;import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyj.Pojo.User;
import com.wyj.Service.UserService;
import com.wyj.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserServiceImp extends ServiceImpl<UserMapper,User> implements UserService {}

6:Controller层

(1):IndexController

package com.wyj.Controller;import com.wyj.Pojo.Admin;
import com.wyj.Pojo.TextUser;
import com.wyj.Pojo.User;
import com.wyj.Service.imp.TextUserServiceImp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpSession;@Controller
public class IndexController {//设置首页 只要请求是'/'或者是'/login'  我们就会返回首页@RequestMapping(value = {"/","/login"})public String loginPage() {return "login";}@RequestMapping("/let")public String loginPage(Admin admin, HttpSession session, Model model) {if ("wyj".equals(admin.getUserName()) && "123".equals(admin.getPassWord())) {session.setAttribute("loginUser",admin);return "redirect:main.html";//这里重定向的是一个请求所以得重新写一个}else{                            //一般我们return的是一个  html 页面//视图解析器自动给我们加上前缀和后缀model.addAttribute("msg","请输入正确的密码和用户名");return "login";}}@RequestMapping("/main.html")public String showPage() {return "main";}}

(2):TableController

package com.wyj.Controller;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wyj.Pojo.User;
import com.wyj.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;import java.util.List;@Controller
public class TableController {@Autowiredprivate UserService userService;@GetMapping("/basic_table")public String basic_table() {return "table/basic_table";}@GetMapping("/dynamic_table")public String dynamic_table(@RequestParam(value = "pn",defaultValue = "1") Integer pn, Model model) {//List<User> list = userService.getUserList();//构造分页参数Page<User> page = new Page<>(pn, 2);//调用page进行分页Page<User> userPage = userService.page(page, null);long current = userPage.getCurrent();//当前是几页long pages = userPage.getPages();//当前总共的页数long total = userPage.getTotal();//总共的记录数目/条数//获取表当中的数据List<User> records = userPage.getRecords();//这个userPage里面有我们存着的当前页和我们的表中的数据(但这个数据得靠我们自己取出来)model.addAttribute("users",userPage);return "table/dynamic_table";}//删除功能//    @ResponseBody@GetMapping("/delete")public String deleteTable(@RequestParam("id") Integer id,@RequestParam(value = "pn",defaultValue = "1") Integer pn,RedirectAttributes ra) {userService.removeById(id);//这个相当于从前端获取到一个参数  然后就将其加到我们新的重定向的路径上ra.addAttribute("pn",pn);return "redirect:dynamic_table";}//修改一个用户的信息@GetMapping("/update")public String updateTable(@RequestParam("id") Integer id,@RequestParam("name") String name,@RequestParam("age") Integer age,@RequestParam("email") String email,Model model) {User user = new User();//获取到我们要修改用户的信息的id信息user.setId(id);if(name != null) user.setName(name);if(age != null) user.setAge(age);if(email != null) user.setEmail(email);userService.updateById(user);model.addAttribute("msg","修改用户信息成功");return "redirect:dynamic_table";}//增加一个用户@GetMapping("/add_table")public String addTable(@RequestParam("id") Integer id,@RequestParam("name") String name,@RequestParam("age") Integer age,@RequestParam("email") String email) {User user = new User(id, name, age, email);userService.save(user);return "redirect:dynamic_table";}@GetMapping("/editable_table")public String editable_table() {return "table/editable_table";}@GetMapping("/responsive_table")public String responsive_table() {return "table/responsive_table";}@GetMapping("/update_table.html")public String getUpdateTable (Model model,Integer id) {User user = userService.getById(id);model.addAttribute("user",user);return "table/update_table";}//转发到增加用户页面@GetMapping("add_table.html")public String addTable() {return "table/add_table";}}

7:拦截器

package com.wyj.MyLanJie;import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;@Slf4j
public class loginInterceptor implements HandlerInterceptor {/**** 方法处理前:如果返回true 那么就继续往下执行 返回false就不往下执行了** @param request* @param response* @param handler* @return* @throws Exception*//*** preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理之前进行调用,SpringMVC中的Interceptor拦截器是链式的,可以同时存在* 多个Interceptor,然后SpringMVC会根据声明的前后顺序一个接一个的执行,而且所有的Interceptor中的preHandle方法都会在* Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中断的,这种中断方式是令preHandle的返* 回值为false,当preHandle的返回值为false的时候整个请求就结束了。*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session = request.getSession();Object loginUser = session.getAttribute("loginUser");if(loginUser != null) {return true;//放行}request.setAttribute("msg","请先登录");request.getRequestDispatcher("/login").forward(request,response);return false;}@Override//方法执行后public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

这个需要我们自动配置一下,有些页面是放行的有些页面是拦截的

package com.wyj.Config;import com.wyj.MyLanJie.loginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class interceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new loginInterceptor())//将拦截器注册到容器中.addPathPatterns("/**")//设置拦截要求.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**","/aa/**","/let");//放行的要求}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307683.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

保护 .NET Core 项目的敏感信息

我们的项目中几乎都会有配置文件&#xff0c;里面可能会存储一些敏感信息&#xff0c;比如数据库连接字符串、第三方API的AppKey和SecretKey等。对于开源项目&#xff0c;这些敏感信息肯定不能随着源代码一起提交到托管平台。对于网站应用大多都是要部署到有公开IP的服务器上的…

背包(二维数组版和一维数组版)

一:前言 这是动态规划的经典题型&#xff0c;那么我们也是 按照动态规划五步走的策略分析的 确定dp数组的含义以及下标的含义确定dp数组的递推公式确定dp数组的初始化确定dp数组的遍历顺序举例验证&#xff08;如果不是做题可省略&#xff09; 二:二维数组 1:示例 2:dp数组…

Azure App Service 健康检查正式发布

点击上方蓝字关注“汪宇杰博客”原文&#xff1a;Jason Freeberg, Suwat Bodin翻译&#xff1a;汪宇杰导语通过App Service&#xff0c;可以在流量增加时自动将应用程序自动扩展到多个实例。这样可以提高您应用的吞吐量&#xff0c;但是如果其中一个实例发生未捕获的异常怎么办…

Azure Cosmos Db 介绍及演示

Azure Cosmos DB 是 Microsoft 提供的全球分布式多模型数据库服务。Cosmos DB是一种NoSql数据库&#xff0c;但是它兼容多种API。它支持SQL, MongoDB、Cassandra或 Gremlin&#xff0c;你可以挑选自己喜欢的方式进行存储跟访问。主要优势统包式全局分发凭借 Cosmos DB&#xff…

leetcode049. 最后一块石头的重量 II

一:题目 二:上码 class Solution { public:/**思路:1.分析题意只要我们将石头分为尽可能相同的两堆,他们的重量相减后剩余的重量就是最小。 物品的重量为stones[i];物品的价值也为stone[i];temp代表总重量的一半那么我们最终得到的stones[temp]:就是背包容量为temp的最大重量为…

大改革,GNOME 3.x将直接跳到GNOME 40

GNOME 3.38 发布后&#xff0c;GNOME 基金会宣布了用于 GNOME 的新版本控制方案&#xff0c;将于2021年3月发布的下一版 GNOME 将是 GNOME 40。你没看错&#xff0c;版本号直接从现在的 3.x 跳到了 40。以 GNOME 40 为例&#xff0c;其开发周期将包含三个阶段&#xff0c;对应的…

.NET Core + Kubernetes:StatefulSet

在 Kubernetes 中&#xff0c;Pod 资源的控制器 Deployment、Replicaset、Daemonset 等常用于管理无状态应用&#xff0c;它们所管理的 Pod 对应的 IP、名字&#xff0c;启停顺序等都是随机的&#xff0c;Pod 之间也并不存在任何关联关系。而实际情况下&#xff0c;在应用集群部…

python编程中的小问题汇总

前言 本文记录了我在python编程中遇到的各种小问题&#xff0c;持续更新。 1. x x 1 VS x 1 辨析下面这两段代码&#xff1a; >>> x y [1, 2, 3, 4] >>> x [4] >>> x [1, 2, 3, 4, 4] >>> y [1, 2, 3, 4, 4]>>> x y …

都在讨论高并发,结果连并发量、TPS、QPS都分不清

“ 年年岁岁跳槽季&#xff0c;回回必问高并发&#xff01;原因很简单&#xff0c;因为高并发能牵扯出太多问题&#xff0c;接口响应超时、CPU负载升高、GC频繁、死锁、大数据量存储等&#xff0c;能考察求职者的真实情况。而很多人在第一步就倒下了&#xff01;因为对数据化的…

leetcode518. 零钱兑换 II

一:题目 二:上码 class Solution { public:/**思路:1.分析题意这个满足答案的结果有很多种&#xff0c;所以我们可以用动态规划去做,那么题意中我们可以知道的是我们是可以输入一种面值的时候,我们是可以重复输入的&#xff0c;那么这就是背包类型中的完全背包了2.动态规划5步…

跟我一起学.NetCore之选项(Options)核心类型简介

前言.NetCore中提供的选项框架&#xff0c;我把其理解为配置组&#xff0c;主要是将服务中可供配置的项提取出来&#xff0c;封装成一个类型&#xff1b;从而服务可根据应用场景进行相关配置项的设置来满足需求&#xff0c;其中使用了依赖注入的形式&#xff0c;使得更加简单、…

《ASP.NET Core项目开发实战入门》送书活动结果公布

截至2020.09.20 本次送书活动《ASP.NET Core项目开发实战入门》。下面把Top 5的留言截图给大家回顾一下。以下5位同学将获赠书籍一本&#xff1a;小林子鉴静红脸先生阿星Plus以上同学请在2020年9月25日24&#xff1a;00之前加小二微信领取赠书&#xff0c;超过时间视为放弃。小…

二分查找基础概念与经典题目(Leetcode题解-Python语言)二分索引型

二分查找的定义如下&#xff08;引自Wiki&#xff09;&#xff1a; 在计算机科学中&#xff0c;二分查找算法&#xff08;英语&#xff1a;binary search algorithm&#xff09;&#xff0c;也称折半搜索算法&#xff08;英语&#xff1a;half-interval search algorithm&…

Magicodes.IE 2.3重磅发布——.NET Core开源导入导出库

在2.3这一版本的更新中&#xff0c;我们迎来了众多的使用者、贡献者&#xff0c;在这个里程碑中我们也添加并修复了一些功能。对于新特点的功能我将在下面进行详细的描述&#xff0c;当然也欢迎更多的人可以加入进来&#xff0c;再或者也很期待大家来提issues或者PR&#xff0c…

听说用 C# 写 TensorFlow 更高效?

经过半年呕心沥血的努力&#xff0c;SciSharp STACK终于把Tensorflow .NET绑定升级到可以使用 tensorflow 2.3, 新版本最大的优势是实现了Eager模式, 这个特性是让.NET C#/ F#成为机器学习模型开发工具的重要前置条件。NugGet包下载:https://www.nuget.org/packages/TensorFlow…

leetcode279. 完全平方数

一:题目 二:上码 class Solution { public:/**思路:1.分析题意这个就是将一个数分成几个数的和;然而的话,这几个数必须的是完全平方数,我们要求的是最少数量的完全平方数这个满足答案的有好几个;但是我们要求的是最少的数量2.动态规划五步走1>:确定dp数组的含义以及下标的含…

跟我一起学.NetCore之Options实例演示及分析

前言来啦&#xff01;来啦&#xff01;上一节一堆代码&#xff0c;是不是感觉甚是无味啊&#xff1f;没关系&#xff0c;这里结合上一节内容专注举例演示&#xff0c;绝不废话&#xff01;走起~~~~~正文老规矩&#xff0c;一个WebApi项目走起&#xff0c;项目结构如下&#xff…

leetcode139. 单词拆分

一:题目 二:上码 class Solution { public:/**思路:1.分析题意单词就是物品;字符串就是背包;单词能否组成字符串就是在问,物品能不能将背包装满单词可以重复使用那么说明这是一个完全背包2.动态规划五步走1>:确定dp数组的与下标的含义&#xff08;这里用下标i是由我们的遍历…

大数据下的质量体系建设

一、背景大数据、人工智能是当前也是未来几年IT部门的重点建设方向&#xff0c;新的技术可以为业务突破盈利瓶颈&#xff0c;带来新的增长点&#xff0c;同时我们也发现数据中台也频频在最近的企业财报予以体现&#xff0c;相关的技术岗位需求也是供不应求&#xff0c;与之形成…

Pandas中的 transform() 结合 groupby() 用法示例

首先&#xff0c;假设我们有如下餐厅数据集&#xff1a; import pandas as pddf pd.DataFrame({restaurant_id: [101,102,103,104,105,106,107],address: [A,B,C,D, E, F, G],city: [London,London,London,Oxford,Oxford, Durham, Durham],sales: [10,500,48,12,21,22,14] })…