## 5.11 pojo 放模板 user mapper 写sql语句 要加@Mapper ```java @Mapper //应用程序在运行的时候 会自动地为该接口创建一个 实现类对象(代理对象 ) //并且会自动的将类对象 存入IOC容器中 称为bean对象 public interface UserMapper { @Select("select * from user") public List findAll(); } ``` properties文件写 ```txt spring.application.name=demo #配置数据库的链接信息 spring.datasource.url=jdbc:mysql://localhost:3306/blackhorse # application.properties spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #配置数据库的用户名和密码 spring.datasource.username=root spring.datasource.password=123456 ``` #{参数} 就是占位符 ```java @Select("select * from user") public List findAll(); @Delete("delete from user where id=#{id}") public void delete(int id); @Insert("insert into user(username,password,name,age) values(#{username},#{password},#{name},#{age})") public void insert(User user); @Select("select * from user where username=#{username}and password=#{password}")//对于多参数就要这样@Param public User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password); 这样的 如果是springboot 官方的骨架+mybatis 就可以无视这个 ``` ## 遇到的bug ![image-20250511220320863](C:\Users\33882\AppData\Roaming\Typora\typora-user-images\image-20250511220320863.png) 这个deptService的一直是个空指针 然后 ![image-20250511220353634](C:\Users\33882\AppData\Roaming\Typora\typora-user-images\image-20250511220353634.png) text一下就好了 ## 5.12 ### 初学springboot 终于啊 红豆泥 红豆泥 #### @RestController #### @RequestMapping 与前端的表示相对应的 ![image-20250512161624492](C:\Users\33882\AppData\Roaming\Typora\typora-user-images\image-20250512161624492.png) #### http协议的特点 1.基于TCP协议 面向连接 安全 2. 基于请求-响应模型 一次请求对应的一次相应 3. Http是无状态协议 对于事物的处理没有记忆能力 每次请求相应 都是独立的 因此需要通过会话功能解决问题 ![image-20250512163814933](C:\Users\33882\AppData\Roaming\Typora\typora-user-images\image-20250512163814933.png) ### HttpServeletRequest对象 里面包含了所有的请求信息 ### IOC DI BEAN - **控制反转:** Inversion Of Control,简称**IOC**。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。 - 对象的创建权由程序员主动创建转移到容器(由容器创建、管理对象)。这个容器称为:IOC容器或Spring容器。 - - **依赖注入:** Dependency Injection,简称**DI**。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。 - 程序运行时需要某个资源,此时容器就为其提供这个资源。 - 例:EmpController程序运行时需要EmpService对象,Spring容器就为其提供并注入EmpService对象。 - **bean对象:**IOC容器中创建、管理的对象,称之为:bean对象。 ![image-20250512203014432](C:\Users\33882\AppData\Roaming\Typora\typora-user-images\image-20250512203014432.png) 这是声明Bean的注解 IOC 还需要被组件扫描@CompoenetScan ![image-20250512203517469](C:\Users\33882\AppData\Roaming\Typora\typora-user-images\image-20250512203517469.png) 范围就是启动类的包&子包 所以就是说 有范围的qwq 其实这个@SpringBootApplication这个里面就有@Compoenet ### 多个bean的问题 当拥有多个bean同类型的时候 使用@Primiary @Autowired @Resource 这三个 然后 @Primiary 是按照类型注入的 @Resource是按照名称注入的 ### 如何接受前端的参数 #### @RequestParam注解 接受的是一个参数 ``` * @RequestParam 在请求时 必须有 不然报错 * boolean required() default true; 因为里面有这个 * 除非delete(@RequestParam(value= "id" ,required=false) int id) ``` #### @RequestBody 就是直接 接收的是一个json格式 但是注意格式要一致 #### @PathVariable //通过请求URL直接传递参数 使用{...}来标识该路径参数 需要使用@PathVariable来获取 ```java @GetMapping("depts/{id}")//通过请求URL直接传递参数 使用{...}来标识该路径参数 需要使用@PathVariable来获取 public Result getInfo(@PathVariable("id") Integer id) { System.out.println("查询部门id="+id); return Result.success(); } ``` ### @RequestMapping("/depts") #### 如果这个类的所有操作基本都是基于某个相同的路径的话 那么就可以在类的前面添加这个 ![image-20250512221656963](C:\Users\33882\AppData\Roaming\Typora\typora-user-images\image-20250512221656963.png) ![image-20250512221742472](C:\Users\33882\AppData\Roaming\Typora\typora-user-images\image-20250512221742472.png) ### Logback 日志管理 ``` private static final Logger log= LoggerFactory.getLogger(LogTest.class); ``` 就可以调用log了 ## 5.13 ### 外键 foregin key 可以使一张表的外键关联到另一个表 物理层面的 ```sql ALTER TABLE emp add CONSTRAINT fk_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id) ALTER TABLE 表名 (添加约束) 重命名 外键 要加外键的名字 那个表的名字 ``` ### MultipartFile spring中 ```java if(!file.isEmpty()){ file.transferTo(new File("D:\\images\\" + file.getOriginalFilename())); 这个就是spring中创建的传输文件的类 } ``` 注意:SpringBoot中,文件上传时默认单个文件最大大小为1M 可以在 `application.properties` 进行如下配置: ```YAML spring: servlet: multipart: max-file-size: 10MB max-request-size: 100MB ``` ## 5.14 ### 会话技术 1. Cookie 客户端会话技术 2. Session 服务端会话技术 3. 令牌 (主流??) ### Cookie 饼干 组成部分 响应头:Set-Cookie ```java @GetMapping("/cookie1") public Result Cookie(HttpServletRequest request) {//request 是获取 Cookie[] cookies = request.getCookies(); for(Cookie cookie : cookies){ if(cookie.getName().equals("name")){ System.out.println(cookie.getValue()); } } return Result.success(); } @GetMapping("/cookie2") public Result Cookie2(HttpServletResponse response) {//response 是设置 response.addCookie(new Cookie("name", "zds")); return Result.success(); } ``` **缺点:** 1. 移动端无法使用cookie 2. 用户可以使用cookie 3. cookie无法跨域 ### Session(服务器端) ```java @GetMapping("/session1") public Result session1(HttpSession session) { session.setAttribute("set_session", "zds"); return Result.success(); } @GetMapping("/session2") public Result session2(HttpSession session) { Object set_session = session.getAttribute("set_session"); System.out.println("++++++++"); System.out.println("session:"+set_session.toString()); return Result.success(); } ``` 就是服务器给客户端发送了一个JSESSIONID 这个JSESSIONID 起到的类似于cookie的操作 **优点:** 1. 存储在服务器中 安全啊 **缺点:** - cookie的所有缺点 因为他的底层还是cookie - 服务器集群下 无法直接使用cookie 因为session只是存储在一个服务器上面 ### Cookie与Session的对比 - 安全性:Session 比 Cookie 安全,Session 是存储在服务器端的,Cookie 是存储在客户端的。 - 存取值的类型不同:Cookie 只支持存字符串数据,想要设置其他类型的数据,需要将其转换成字符串,Session 可以存任意数据类型。 - image-20250514202821975 - 有效期不同:Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭(默认情况下)或者 Session 超时都会失效。 - 存储大小不同:单个 Cookie 保存的数据不能超过 4K(Cookie小),Session 可存储数据远高于 Cookie,但是当访问量过多,会占用过多的服务器资源。 ### 签名JWT ##### ~~ps:在某些java版本 好像签名不能用了qwq~~ 已经解决高版本java似乎无法带动jwt 报错 仅需在image-20250514211708673添加即可 ```java javax.xml.bind jaxb-api 2.3.0 io.jsonwebtoken jjwt 0.9.1 ``` 组成: - header 头 记录令牌的类型 签名算法 - payload 荷载 携带一些自定义的信息 - siganture 签名 访问被篡改 保证安全性 #### 生成 jwt.bulider() #### 校验 jwt.parser() ## 5.15 ### Filter 过滤器 ```java @WebFilter("/*")//使用注解 来告诉服务器拦截的那部分的 public class DemoFilter implements Filter {//实现Filter @Override public void init(FilterConfig filterConfig) throws ServletException { Filter.super.init(filterConfig); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("执行了DemoFilter的doFilter方法"); filterChain.doFilter(servletRequest,servletResponse);//放行 程序 } @Override public void destroy() { Filter.super.destroy(); } } ``` - init() 与destory() 已经实现了默认的函数 了 因此我们可以不用去实现它 - @WebFilter("/*") - @ServletCompoenetScan 组件的扫描 可以让程序感知到 Filter的存在 #### 过滤的逻辑 1. 执行放行前的逻辑 2. 放行 3. 访问资源 4. 放行后 #### 过滤器链的运行逻辑 根据字符串的字典序来进行的 ### Interceptor 与Filter类似 #### 实现 ```java package com.example.interceptor;/* *@auther 郑笃实 *@version 1.0 * */ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Component public class DemoInterceptor implements HandlerInterceptor { //在请求处理之前进行调用(Controller方法调用之前) true:继续向下执行,false:中断请求 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return HandlerInterceptor.super.preHandle(request, response, handler); } //在请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后) @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); } //在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要是用于进行资源清理工作) @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { HandlerInterceptor.super.afterCompletion(request, response, handler, ex); } } ``` #### 注册 ```java package com.example.config;/* *@auther 郑笃实 *@version 1.0 * */ import com.example.interceptor.DemoInterceptor; import org.springframework.beans.factory.annotation.Autowired; 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 WebConfig implements WebMvcConfigurer { @Autowired DemoInterceptor demoInterceptor; public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(demoInterceptor).addPathPatterns("/**"); } } ``` ### 两个关系 一般来说 都是显示Filter 之后才是Intercepter intercepter只能拦截spring里面的内容 而filter可以拦截所有的 范围更大 ### AOP(欠) ### Spring Boot 在springboot中有许三个配置文件 .properities .yml .yaml 优先级分别是 **.properities > .yml > .yaml** 但是yml是主流 ### BEAN的作用域 image-20250515155815835 对于Bean来说的话 如果没有指定名字 默认的名字就是类名的小写 Bean的初始化是在**项目开始**的时候就实例化的 一般来说Bean都是单例的 没有存储什么数据 因此不存在线程安全的问题 **对于第三方的Bean 因为无法使用Compoenent 以及相关的衍生注解 因此我们只能使用@Bean 来将其注入到Bean容器中** **注意一旦成为了 那么他的名字就是方法名字 而不是小写** ## 5.22 ```java Optional.ofNullable(tempTagNameSet).orElse(new HashSet<>()); ``` java8的新特性Optional.ofNullable(XX).orElse(XX); 就类似于if else 只要是空 就返回后面那一个