SpringMVC

学习流程图:

四个学习模块:

1、SpringMVC入门

2、请求与响应

3、rest风格

 

4、ssm整合

 

5、拦截器

第一章、SpringMVC入门

1、简介

 SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架。

           

SpringMVC的开发步骤:

                            ① 导入SpringMVC相关坐标

                            ② 配置SpringMVC核心控制器DispathcerServlet

                            ③ 创建Controller类和视图页面

                            ④ 使用注解配置Controller类中业务方法的映射地址

                            ⑤ 配置SpringMVC核心文件 spring-mvc.xml

                            ⑥ 客户端发起请求测试 

2、SpringMVC入门案例

 

1、导入servlet-api与spring-webmvc依赖坐标

<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.1.RELEASE</version></dependency>

2、创建SpringMVC控制器类(等同于Servlet接受请求与响应)

@Controller //定义spring的bean
public class UserController {@RequestMapping("/save")//    设置当前操作的访问URL路径@ResponseBody    //设置以下的方法是执行响应的方法
//    定义具体的处理请求操作,向外返回JSON数据public String save(){System.out.println("此处是处理请求的方法");return "{'module':'springmvc'}";}
}

3、创建spring配置类,扫描bean

//创建spring配置类,扫描controller对应的bean
@Configuration
@ComponentScan("com.itheima.controller")
public class SpringmvcConfig {
}

4、初始化Servlet容器,加载配置类,设置请求方法

创建一个web容器并加载spring配置类完成注册;设置请求映射路径,直接”/“表示全部

 //定义一个Servlet容器启动的配置类,在里面加载spring的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//让Tomcat能够加载SpringMVC容器的配置@Overrideprotected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();ctx.register(SpringmvcConfig.class);return ctx;}
//设置哪些请求归属SpringMVC处理@Overrideprotected String[] getServletMappings() {return new String[]{"/"};//设置所有请求归属SpringMVC处理}@Override //加载spring配置类的protected WebApplicationContext createRootApplicationContext() {return null;}
}

三个实现方法详解:

5、总结:

<基本目录>

<常用注解>

@Controller //类注解:将该类定义为spring的bean;

@RequestMapping("/save")// 方法注解:写在方法上面,设置当前方法的访问URL路径,         可类比  Servlet开发中web.xml配置的servlet-mapping标签作用;

@ResponseBody //方法注解:设置以下的方法的返回值作为响应体数据反馈给浏览器;

3、SpringMVC工作流程分析

《1》容器初始化 (ServletContext对象看做Web程序实例化对象)

《2》单次请求

4、controller加载控制

SpringmvcConfig配置类和SpringConfig配置类功能一样,就是扫描bean,只是扫描的范围不同。但是存在着重复扫描加载,那bean就不晓得听谁话了!

《1》问题:

 《2》解决方案:

方案二中SpringConfig配置类

@Configuration
//@ComponentScan({"com.itheima.dao","com.itheima.service"})//设定精确包扫描范围
@ComponentScan(value = "com.itheima",excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Controller.class)
)
//解释:我去扫描包com.itheima里面的所有的包,设置过滤器,按照注解排除,排除掉指定classes的包public class SpringConfig {}

SpringMvcConfig配置类

@Configuration
@ComponentScan("com.itheima.controller")
public class SpringMvcConfig {
}

Servlet容器配置类 ServletContainersInitConfig :加载Spring与SpringMVC容器

public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {//    springMVC容器加载配置@Overrideprotected WebApplicationContext createServletApplicationContext() {AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();ctx.register(SpringMvcConfig.class);return ctx;}
//    Spring容器加载配置@Overrideprotected WebApplicationContext createRootApplicationContext() {AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();ctx.register(SpringConfig.class);return ctx;}@Overrideprotected String[] getServletMappings() {return new String[]{"/"};}
}

5、PostMan

网页调试与发送http请求的插件。

作用:常用于接口测试。

第二章、请求与响应

1、请求映射路径

在类上统一设置当前控制器方法请求访问路径前缀。

@Controller
@RequestMapping("/user") //访问路径前缀 ,目的是区别不同的controller类
public class UserController {@RequestMapping("/save") //具体的方法的请求路径@ResponseBodypublic String save(){System.out.println("此处是usercontroller类中的save方法");return "{'我要吃饭了':'真的好饿'}";}@RequestMapping("/delete")@ResponseBodypublic  String delete(){System.out.println("此处是us二controller内的delete方法");return "{'我真的要饿死了':'一点也不好玩'";}}

 

2、请求参数

直接在方法内写入形式参数即可。在发出请求的时候输入参数就会传入。

《1、普通参数》

请求url(?表示接下来的是参数  使用&分隔不同的参数)

http://localhost:8080/springMVC_02_bean_load_war/commonParam?name=我是你爹 & age=100

        方法写入形参

URL中参数名方法内的形参名会自动映射,相同则直接传参。 如果不匹配使用@RequestParam(”里面写上前端的对应的名称“)

 @RequestMapping("/commonParam")@ResponseBodypublic String commonParam(String name,int age,String text){System.out.println("接收到的普通参数name是:=============》" + name);System.out.println("接收到的普通参数age是:=============》" + age);System.out.println("接收到的普通参数text是:=============》" + text);return "{'module':'commonParam'}";}

        post请求参数乱码处理

在 Web容器配置类ServletContainersInitConfig类中使用过滤器处理

//乱码处理 重写getServletFilters()方法@Overrideprotected Filter[] getServletFilters() {CharacterEncodingFilter filter = new CharacterEncodingFilter();filter.setEncoding("UTF-8");return new Filter[] {filter};}

post请求方法----参数在请求体

《2、POJO参数》

实际开发中,是接收大量参数组成一个实体类

定义一个实体类,声明属性、toString()以及setter()&getter()

将此实体类对象作为方法内的 形参

 //POJO参数@RequestMapping("/pojoParam")@ResponseBodypublic String pojoParam(User user){System.out.println("pojo参数传递user --》" + user);return "{'module':'pojo param'}";}

基于本框架,前端页面传的所有参数属性,会自动根据名称和实体类的属性匹配、赋值。

《3、POJO嵌套》

对应引用类型传参,正常在后端就正常定义实体类就行了。

但在前端传参的时候,aa.bb 前者是引用对象实例,后者是传参属性

《4、数组参数》

对于数组参数,只需要在前端传参时将名称全部写为数组名即可。

//数组参数@RequestMapping("/arrayParam")@ResponseBodypublic  String arrayParam(String[] arr){System.out.println("数组参数传递为:" + Arrays.toString(arr));return "{'module':'arrayparam'";}

《5、集合参数》

//集合参数@RequestMapping("/listParam")@ResponseBodypublic  String listParam(@RequestParam List<String> likes){System.out.println("数组参数传递为:" + likes);return "{'module':'arrayparam'";}

3、日期类型参数传递

 

4、JSON数据传参

基本四步骤:

1、添加依赖坐标 --> 2、SpringMVC配置类添加注解  --> 3、注意前端传参改为JSON数据 --> 4、方法内形参前添加注解 @RequestBody(接收json数据)

在SpringMVC配置类SpringMvcConfig中添加注解 实现前端JSON数据可以转化为被后端接收的数据

@EnableWebMvc //开启由JSON数据转换为List集合数据

《1、集合参数:json格式》 

//集合参数 JSON数据格式@RequestMapping("/listParamForJson")@ResponseBody       //由于传过来的JSON数据在请求体内,所以参数要使用RequestBody注解public  String listParamForJson(@RequestBody List<String> likes){System.out.println("数组参数传递为:" + likes);return "{'module':'list common for json param'}";}

《2、pojo参数:json格式》

 //pojo参数:json格式@RequestMapping("/pojoParamForJson")@ResponseBody       //由于传过来的JSON数据在请求体内,所以参数要使用RequestBody注解-把请求体内的json数据塞到参数中public  String pojoParamForJson(@RequestBody User user){System.out.println("数组参数传递为:" + user);return "{'module':'list common for json param'}";}

《3、集合对象参数:json格式》

//集合pojo参数:json格式@RequestMapping("/listpojoParamForJson")@ResponseBody       //由于传过来的JSON数据在请求体内,所以参数要使用RequestBody注解-把请求体内的json数据塞到参数中public  String listpojoParamForJson(@RequestBody List<User> list){System.out.println("数组参数传递为:" + list);return "{'module':'list common for json param'}";}

 

5、响应

@ResponseBody 作用:设置当前控制器返回值为响应体

响应页面--返回页面文件名

//响应页面、跳转页面@RequestMapping("/toJumpPage")public String toJumpPage(){System.out.println("成功跳转页面");return "page.jsp";}

响应数据--文本数据

文本数据要放在响应体内!!!使用 @ResponseBody 标明!!!1

//    响应文本数据@RequestMapping("/toText")@ResponseBodypublic String toText(){System.out.println("响应返回文本数据");return "Response text";}

响应数据--json数据

json数据要放在响应体内


//    响应pojo对象@RequestMapping("toJsonPOJO")@ResponseBodypublic User toJsonPOJO(){System.out.println("响应返回json对象数据");User user = new User();user.setName("我是你大爷的太祖宗");user.setAge(100);return user;}//    响应pojo对象@RequestMapping("toJsonlistPOJO")@ResponseBodypublic List<User> toJsonlistPOJO(){System.out.println("响应返回json对象数据");User user1 = new User();user1.setName("我是你大爷的太太太太太太祖宗");user1.setAge(100);User user2 = new User();user2.setName("我是你大爷的怎嫩嗯嗯嗯嗯嗯嗯嗯嗯祖宗");user2.setAge(500);User user3 = new User();user3.setName("我是你大爷的顺丰到付大幅度太祖宗");user3.setAge(1000);List<User> users = new ArrayList<>();users.add(user1);users.add(user2);users.add(user3);return users;}

 HttpMessageConverter接口:将文本类型、集合等数据转换为json数据类型

第三章、REST风格

1、REST简介

REST见文知意,他的目的就是程序员约定俗成的”规范“。也就是主流的代码风格。

《1》REST风格就是描述资源的访问形式

《2》REST 内部通过访问资源时 行为方式 区分资源操作方式。

资源操作方式=资源路径 + 请求方式。

在实际开发中,@RequestMapping 的路径要改为类名 ;并且指定访问方法

@RequestMapping(value = "/users",method = RequestMethod.POST) //具体的方法的请求路径@ResponseBodypublic String save(){System.out.println("此处是usercontroller类中的save方法");return "{'我要吃饭了':'真的好饿'}";}

传参:

value要指定参数路径位置/路径/{参数名};形参要添加@PathVariable 表示参数从路径中得到

@RequestMapping(value = "/users",method = RequestMethod.POST) //具体的方法的请求路径@ResponseBodypublic String save(){System.out.println("此处是usercontroller类中的save方法");return "{'我要吃饭了':'真的好饿'}";}@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)@ResponseBodypublic  String delete(@PathVariable Integer id){System.out.println("此处是us二controller内的delete方法" + id);return "{'我真的要饿死了':'一点也不好玩'";}@RequestMapping(value = "/users",method = RequestMethod.PUT)@ResponseBodypublic  String update(@RequestBody User user){System.out.println("此处是us二controller内的update方法" + user);return "{'module':'erertrgtrt'}";}

以后开发中,基本上都是将数据封装成pojo,然后通过json串传递。

 

2、RESTful入门案例

 @RequestMapping(value = "/users",method = RequestMethod.POST) //具体的方法的请求路径@ResponseBodypublic String save(){System.out.println("此处是usercontroller类中的save方法");return "{'我要吃饭了':'真的好饿'}";}@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)@ResponseBodypublic  String delete(@PathVariable Integer id){System.out.println("此处是us二controller内的delete方法" + id);return "{'我真的要饿死了':'一点也不好玩'";}@RequestMapping(value = "/users",method = RequestMethod.PUT)@ResponseBodypublic  String update(@RequestBody User user){System.out.println("此处是us二controller内的update方法" + user);return "{'module':'erertrgtrt'}";}

3、REST快速开发(简化代码)

对于相同的注解、mapping,直接在类前面写。

@RestController = @Controller + @ResponseBody

对于映射直接写请求方法+mapping,需要单独添加参数后面加。

@RestController
@RequestMapping("/books")
public class BookController {@PostMappingpublic String save(@RequestBody Book book) {System.out.println("此处是控制层save方法");return "{'module':'你爹爹的}";}@DeleteMapping("/{id}")public String delete(@PathVariable Integer id) {System.out.println("此处是delete方法接收到id为" + id);return "{'module':'你爹爹的}";}@PutMappingpublic String update(@RequestBody Book book) {System.out.println("此处是控制层update方法更新的数据为" + book );return "{'module':'update'}";}@GetMapping("/{id}")public String getById(@PathVariable Integer id) {System.out.println("此处是控制层得到的id的数据为" + id );return "{'module':'getbyid'}";}

4、案例:基于RESTful页面数据交互

实现功能:前端页面的数据可以提交到后台,后台的数据可以传到前台显示。

对于css、pages、js等静态资源,应当是由Tomcat服务器直接传送,而不要被SpringMVC拦截,所以要单独设置配置类一旦扫描到指定的资源就放行。

没有解决SpringMVC拦截静态资源 API都是原样子写的咋就不行了呢》?》

第四章、SSM整合

1、SSM整合

企业开发停下来做测试:

业务层写完进行junit测试;控制层写完使用postman进行测试前后端数据交互。

配置事务三部曲:

1、开启注解式事务驱动

在SpringConfig配置类中添加 @EnableTransactionManagement

2、配置事务管理器

在jdbcConfig配置类中

@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){DataSourceTransactionManager ds = new DataSourceTransactionManager();ds.setDataSource(dataSource);return ds;}

3、配置事务,把事务配到接口上

业务层接口内上方添加     @Transactional

2、表现层数据封装

返回数据,可能是空、报错、返回数据、返回消息等多种数据格式。

于是数据封装成统一格式。包含三个信息:code、data、msg。

根据code判断返回结果的        请求方法以及正误

根据code是否进行获取data以及msg。

创建含有不同属性的构造方法,针对不同请求方法返回不同结果

public Result() {}public Result(Integer code,Object data) {this.data = data;this.code = code;}public Result(Integer code,Object data, String msg) {this.data = data;this.code = code;this.msg = msg;}

创建状态码类,以便针对前端确认        请求方法及正误

public class Code {public static final Integer SAVE_OK = 20011;public static final Integer DELETE_OK = 20021;public static final Integer UPDATE_OK = 20031;public static final Integer GET_OK = 20041;public static final Integer SAVE_ERR = 20010;public static final Integer DELETE_ERR = 20020;public static final Integer UPDATE_ERR = 20030;public static final Integer GET_ERR = 20040;}

返回结果实例:(get id= 11)

 将最终返回结果都封装成指定的格式

    public Result save(@RequestBody Book book) {boolean flag = bookService.save(book);return new Result(flag ? Code.SAVE_OK : Code.SAVE_ERR,flag);}@PutMappingpublic Result update(@RequestBody Book book) {boolean flag = bookService.update(book);return new Result(flag ? Code.UPDATE_OK : Code.UPDATE_ERR,flag);}@DeleteMapping("/{id}")public Result delete(@PathVariable Integer id) {boolean flag = bookService.delete(id);return new Result(flag ? Code.DELETE_OK : Code.DELETE_ERR,flag);}@GetMapping("/{id}")public Result getById(@PathVariable Integer id)  {Book book = bookService.getById(id);Integer code = book != null ? Code.GET_OK : Code.GET_ERR;String msg = book != null ? "" : "数据查询失败,请重试!";return new Result(code,book,msg);}

3、异常处理器

异常要分类处理、放在表现层、使用AOP思想

@RestControllerAdvice  //声明此类为异常处理器类 = @ResponseBody + @Component
public class ProjectExceptionAdvice {@ExceptionHandler(Exception.class) //定义处理的是哪一种异常 括号内为异常种类public Result doException(Exception ex){ //将异常对象传入处理方法内System.out.println("此处已经拦截到异常");return new Result(110,null,"产生异常啦");}
}

4、项目异常处理方案

第一步、针对BussinessException、SystemException写配置类,内容相同。

public class BussinessException extends RuntimeException {private Integer code;public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public BussinessException(String message, Integer code) {super(message);this.code = code;}public BussinessException(String message, Throwable cause, Integer code) {super(message, cause);this.code = code;}

第二步、针对可能出现异常地方处理

public Book getById(Integer id) {if(id == 1){throw new BussinessException(Code.BUSSINESS_ERR,"出现错误了");}//将可能出现的异常进行包装,转换成自定义异常try{int i = 1 / 0;}catch(Exception e){throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器坏;额",e);}return bookDao.getById(id);}

第三步、异常处理器分类三种异常,针对性处理


@RestControllerAdvice  //声明此类为异常处理器类 = @ResponseBody + @Component
public class ProjectExceptionAdvice {@ExceptionHandler(SystemException.class) //定义处理的是哪一种异常 括号内为异常种类public Result doSystemExceptionn(SystemException ex){ //将异常对象传入处理方法内//记录日志//发送消息给运维//发送邮件给开发人员 ex对象发送return new Result(ex.getCode(),null,ex.getMessage());}@ExceptionHandler(BussinessException.class) //定义处理的是哪一种异常 括号内为异常种类public Result doBussinessException(BussinessException ex){ //将异常对象传入处理方法return new Result(ex.getCode(),null,ex.getMessage());}//其他异常@ExceptionHandler(Exception.class) //定义处理的是哪一种异常 括号内为异常种类public Result doException(Exception ex){ //将异常对象传入处理方法内System.out.println("此处已经拦截到异常");return new Result(SYSTEM_UNKNOW_ERR,null,"系统繁忙请稍后!");}
}

5、案例:SSM整合标准开发

至于处理SpringMVC拦截静态资源,就利用api处理。

把下面这个类在SpringMvcConfig配置类中扫描到就好了

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");registry.addResourceHandler("/css/**").addResourceLocations("/css/");registry.addResourceHandler("/js/**").addResourceLocations("/js/");registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");}
}

也就是页面操作-----前端没学 没法做喽

第五章、拦截器

1、拦截器概念

 

2、入门案例

《1、》制作拦截器功能类

将功能类写在controller下,SpringMVC扫描controller时可以直接扫描到

重写API三个方法

@Component
public class ProjectInterceptor implements HandlerInterceptor {public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("ProjectInterceptor...");return true;
//此处若返回false则终止原始方法的执行,接下来的所有都不执行了}public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...");}public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion...");}
}

《2、》配置拦截器的执行位置

也就是去确定在执行什么请求时执行拦截器

在SpringMvcSupport配置类中重写API ProjectInterceptor 的方法 addInterceptors

来确定要拦截的请求路径

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");registry.addResourceHandler("/css/**").addResourceLocations("/css/");registry.addResourceHandler("/js/**").addResourceLocations("/js/");registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");}@Autowiredprivate ProjectInterceptor projectInterceptor;protected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");}
}

3、拦截器参数

 

4、拦截器工作流程分析

5、拦截器链

 

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

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

相关文章

vscode调教配置:快捷修复和格式化代码

配置vscode快捷键&#xff0c;让你像使用idea一样使用vscode&#xff0c;我们最常用的两个功能就是格式化代码和快捷修复&#xff0c;所以这里修改一下快捷修复和格式化代码的快捷键。 在设置中&#xff0c;找到快捷键配置&#xff1a; 然后搜索&#xff1a;快捷修复 在快捷键…

即时通讯开发中的性能优化技巧

即时通讯开发在如今的数字化社会中扮演着重要角色&#xff0c;然而&#xff0c;随着用户对即时通讯应用的需求不断增长&#xff0c;开发者们面临着使其应用保持高性能和可靠性的挑战。本文将探讨即时通讯开发中关键的性能优化技巧&#xff0c;帮助开发者们提升应用的用户体验和…

基于Java的OA办公管理系统,Spring Boot框架,vue技术,mysql数据库,前台+后台,完美运行,有一万一千字论文。

基于Java的OA办公管理系统&#xff0c;Spring Boot框架&#xff0c;vue技术&#xff0c;mysql数据库&#xff0c;前台后台&#xff0c;完美运行&#xff0c;有一万一千字论文。 系统中的功能模块主要是实现管理员和员工的管理&#xff1b; 管理员&#xff1a;个人中心、普通员工…

c语言每日一练(13)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;上学期间将看学业情况更新。 五道选择题&#xff1a; 1、程序运行的结果…

图文详解PhPStudy安装教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 官方下载 请在PhPStudy官方网站下载安装文件&#xff0c;官方链接如下&#xff1a;https://m.xp.cn/linux.html&#xff1b;图示如下&#xff1a; 请下载PhPStudy安装文件…

SpringCloudAlibaba Gateway(一)简单集成

SpringCloudAlibaba Gateway(一)简单集成 随着服务模块的增加&#xff0c;一定会产生多个接口地址&#xff0c;那么客户端调用多个接口只能使用多个地址&#xff0c;维护多个地址是很不方便的&#xff0c;这个时候就需要统一服务地址。同时也可以进行统一认证鉴权的需求。那么服…

golong基础相关操作--一

package main//go语言以包作为管理单位&#xff0c;每个文件必须先声明包 //程序必须有一个main包 // 导入包&#xff0c;必须要要使用 // 变量声明了&#xff0c;必须要使用 import ("fmt" )/* * 包内部的变量 */ var aa 3var ss "kkk"var bb truevar …

使用Python对数据的操作转换

1、列表加值转字典 在Python中&#xff0c;将列表的值转换为字典的键可以使用以下代码&#xff1a; myList ["name", "age", "location"] myDict {k: None for k in myList} print(myDict) 输出&#xff1a; {name: None, age: None, loca…

EasyExcel导出模板实现下拉选(解决下拉超过50个限制)

学习地址&#xff1a;https://d9bp4nr5ye.feishu.cn/wiki/O3obweIbgi2Rk1ksXJncpClTnAfB站视频&#xff1a;https://www.bilibili.com/video/BV1H34y1T7Lm 先来看看最终实现效果&#xff0c;如果效果是你想要的&#xff0c;再看看实现逻辑。 EasyExcel本身是支持设置下拉校验的…

小程序中如何给会员卡设置到期时间

通过设置会员卡到期时间&#xff0c;可以有效地管理会员卡的使用周期&#xff0c;提供更好的会员服务体验。下面将介绍一种常见的给会员卡设置到期时间的方法。 1. 找到指定的会员卡。在管理员后台->会员管理处&#xff0c;找到需要设置到期时间的会员卡。也支持对会员卡按…

OS 内存分区和分页 多级页表与快表

每个进程的PCB都有一个LDT 内存紧缩不实用&#xff0c;所需时间太长 类似于段表&#xff0c;存在页表 但是不连续需要的空间太多了&#xff0c;太麻烦了 多级页表&#xff1a;类比于书的章目录和节目录 构建页目录 每个页目录号指向4M的地址 快表是寄存器&#xff0c;很昂…

《Python入门到精通》webbrowser模块详解,Python webbrowser标准库,Python浏览器控制工具

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;小白零基础《Python入门到精通》 webbrowser模块详解 1、常用操作2、函数大全webbrowser.open() 打开浏览器webbro…

应急三维电子沙盘数字孪生系统

一、简介应急三维电子沙盘数字孪生系统是一种基于虚拟现实技术和数字孪生技术的应急管理工具。它通过将真实世界的地理环境与虚拟世界的模拟环境相结合&#xff0c;实现了对应急场景的模拟、分析和决策支持。该系统主要由三维电子沙盘和数字孪生模型两部分组成。三维电子沙盘是…

机器学习基础16-建立预测模型项目模板

机器学习是一项经验技能&#xff0c;经验越多越好。在项目建立的过程中&#xff0c;实 践是掌握机器学习的最佳手段。在实践过程中&#xff0c;通过实际操作加深对分类和回归问题的每一个步骤的理解&#xff0c;达到学习机器学习的目的 预测模型项目模板 不能只通过阅读来掌握…

YII项目在Docker中运行缓慢

缓慢问题分析 请求YII的api时间请求原生查询时间win10 上运行docker上的php api异常慢ubuntu 中拉代码git报错 请求YII的api时间 请求原生查询时间 win10 上运行docker上的php api异常慢 链接阿里数据的 入口直接返回的 网上有说是docker的dns解析慢&#xff1b; 也有说是…

C语言:大小端字节序存储

一、大小端字节序存储介绍 大端字节序存储模式&#xff1a;把一个数据低位字节处的数据存放在高地址处&#xff0c;数据高位字节处的数据存放在低地址处 小端字节序存储模式&#xff1a;把一个数据低位字节处的数据存放在低地址处&#xff0c;数据高位字节处的数据存放在高地址…

极限五分钟,在宝塔中用 Docker 部署升讯威在线客服系统

最近客服系统成功经受住了客户现场组织的压力测试&#xff0c;获得了客户的认可。 客户组织多名客服上线后&#xff0c;所有员工同一时间打开访客页面疯狂不停的给在线客服发消息&#xff0c;系统稳定无异常无掉线&#xff0c;客服回复消息正常。消息实时到达无任何延迟。 本文…

【一对一学习小组】2023年有三AI-CV高阶-项目实战组发布,超过30个案例,60小时项目实战+2大基础方向专栏+3本书赠送...

2023年有三AI-CV高阶-项目实战组正式发布&#xff01;有三AI已经推出了CV初-中-高级培养计划&#xff08;原名有三AI-CV季划&#xff09;&#xff0c;这是我们的终身计算机视觉学习小组。 该培养计划具有以下特点&#xff1a; 【系统性】配套有非常完备的理论与实践 【永久性】…

ssm+vue乐购游戏商城系统源码和论文

ssmvue乐购游戏商城系统源码和论文115 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 随着社会的发展&#xff0c;游戏品种越来越多&#xff0c;计算机的优势和普及使得乐购游戏商城系统的开发成为必需…

SQL查询本年每月的数据

--一、以一行数据的形式&#xff0c;显示本年的12月的数据&#xff0c;本示例以2017年为例&#xff0c;根据统计日期字段判断&#xff0c;计算总和&#xff0c;查询语句如下&#xff1a;selectsum(case when datepart(month,统计日期)1 then 支付金额 else 0 end) as 1月, sum…