JSD-2204-MyBatis小结-SLF4j日志-SpringMVC-Day05

这篇博客总结了MyBatis的使用,包括配置、POJO规范和SQL映射。此外,介绍了SLF4j日志框架的基本应用和日志级别。最后,探讨了Spring MVC的基础配置、请求处理和注解使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.关于Mybatis小结

  • 【理解】Mybatis主要解决了:简化数据库编程
  • 【了解】使用Mybatis时需要添加依赖:mysql-connector-javamybatis-spring-boot-startermybatis + mybatis-spring + spring-context + spring-jdbc + 数据库连接池)
  • 【掌握】在配置类上使用@MapperScan配置接口所在的包,并在application.properties中配置XML文件的位置
  • 【了解】在application.properties配置连接数据库的参数
  • 【掌握】POJO的规范:属性私有化,实现Serializable,全属性的Setters & Getters,hashCode()equals()、存在无参数的构造方法
    • toString()并不是规范所要求的
  • 【掌握】抽象方法的设计原则
    • 返回值类型:增删改使用int,查询使用可以装得下结果的类型即可
    • 方法名称:自定义,不要重载,最好参考规范
    • 参数列表:取决于需要执行的SQL语句中的参数,当参数较多时,应该封装
  • 【掌握】在XML中配置SQL
    • 此XML文件不是凭空创建的,应该从别处复制粘贴得到(此XML顶部的声明不易于手动编写)
    • 每个XML文件都必须使用<mapper>作为根节点,且配置namespace属性,此属性的值是对应的接口的全限定名
    • 区分使用<insert><delete><update><select>节点
      • <delete><update>可以浑为一谈
      • 在不考虑获取自动编号的值的情况,<insert><delete><update>都可以浑为一谈
    • <insert><delete><update><select>这些节点都必须配置id属性,取值为对应的抽象方法的名称
    • <insert>可以配置useGeneratedKeyskeyProperty属性,用于获取自动编号的id
    • <select>必须配置resultTyperesultMap其中的某1个(二选一)
    • 使用<foreach>可以实现对参数的遍历,可以实现批量删除、批量插入、批量修改……
    • 使用<set>结合<if>实现按需更新数据
    • 使用<sql>封装SQL语句片段,并使用<include>调用
    • 使用<resultMap>指导Mybatis封装查询结果

2.使用SLF4j日志

日志可以用于在程序执行过程中,向控制台或文件或数据库等位置输出一些自定义的信息。

注意:在开发实践中,不要在src/main/java下的任何类中使用System.out.println()的方式进行输出,除非你确定这些信息是一定要被任何人都可以看到的!

spring-boot-starter(此依赖项是几乎所有带有spring-boot-starter依赖项的子级依赖)的依赖项中,默认已经集成了SLF4j日志框架。

日志是有显示级别的,根据日志信息的重要程度,从低到高分别是:

  • trace:跟踪信息
  • debug:调试信息
  • info:一般信息
  • warn:警告信息
  • error:错误信息

默认的显示级别是info,则只会显示此级别及更重要的日志信息。

在Spring Boot项目的application.properties中,可以添加配置,以指定日志的显示级别:

logging.level.包名=日志的显示级别

例如,可以配置为:

logging.level.cn.tedu.csmall.product=info

在添加了Lombok框架的Spring Boot项目中,可以在任何类上添加@Slf4j注解,则在当前类中就可以使用名为log的变量来调用方法,实现日志的输出,例如:

@Slf4j
@SpringBootTest
public class Slf4jTests {

    @Test
    void testSlf4j() {
        log.trace("这是一条【trace】级别的日志");
        log.debug("这是一条【debug】级别的日志");
        log.info("这是一条【info】级别的日志");
        log.warn("这是一条【warn】级别的日志");
        log.error("这是一条【error】级别的日志");
    }

}

可以看到,log变量可以调用trace()debug()info()warn()error()方法,将输出对应级别的日志。

各级别的方法均重载了多次,通常使用的方法是:

  • trace(String message)
  • trace(String message, Object... args)

提示:其它各级别的方法也有以上方式的重载。

使用以上第2个方法时,可以在第1个参数的字符串中使用{}作为占位符,表示某变量,然后,从第2个参数开始,依次表示各{}占位符对应的值即可,例如:

@Test
void testSlf4j() {
    int a = 1;
    int b = 2;
    log.debug("a=" + a + ", b=" + b + ", a+b=" + (a + b));
    log.debug("a={}, b={}, a+b={}", a, b, a + b);
}

另外,使用trace(String message, Object... args)这类方法来输出日志时,日志框架会对第1个参数String message进行缓存,执行效率远高于使用System.out.println()且拼接字符串的效果。

3.Spring MVC框架

3.1Spring MVC框架的作用

Spring MVC主要解决了接收请求、响应结果及相关的问题。

3.2基础配置

在Spring Boot项目中,添加spring-boot-starter-web依赖项,即可添加Spring MVC框架所需的依赖!

提示:如果使用的不是Spring Boot项目,当需要使用Spring MVC框架时,需要添加的依赖项是spring-webmvc

提示:只需要将原有的spring-boot-starter改为spring-boot-starter-web即可。

提示:在创建工程时,如果勾选了Web,本质上也是添加spring-boot-starter-web依赖项,另外,还会在src/main/resources下自动创建statictemplates文件夹。

一旦添加了spring-boot-starter-web,当启动Spring Boot项目时,会自动启动Tomcat,并将此项目部署到Tomcat上。

Spring Boot启动Tomcat时,默认占用8080端口,可以在application.properties中通过server.port属性来修改端口号,例如:

# 服务端口
server.port=9080

3.3使用Spring MVC框架接收请求

Spring MVC需要自定义控制器类,在类中使用方法来接收请求。

关于控制器类:必须在项目的根包之下,且添加@Controller注解。

关于处理请求的方法:

  • 请求路径:需要添加@RequestMapping系列注解来配置路径
  • 访问权限:应该使用public
  • 返回值类型:按需设计
  • 方法名称:自定义
  • 参数列表:按需设计

简单的接收请求如下:

package cn.tedu.csmall.product.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 处理相册数据相关请求的控制器
 *
 * @author java@tedu.cn
 * @version 0.0.1
 */
@Slf4j
@Controller
public class AlbumController {

    public AlbumController() {
        log.info("创建控制器:AlbumController");
    }

    // http://localhost:9080/a
    @RequestMapping("/a")
    public String xx() {
        log.info("开始处理请求……");
        return null;
    }

}

提示:启动项目后,可以在浏览器或任何可以发出请求的软件中访问 http://localhost:9080/a ,目前会提示500错误,在服务器端的控制台可以看到日志的输出,且每提交一次以上路径的请求,日志都会输出一次,反映为:每次提交请求,以上方法都会自动运行。

3.4响应正文

在处理请求的方法上添加@ResponseBody注解,则表示当前方法处理完请求后,将响应正文

提示:如果没有使用响应正文的做法,则处理请求的方法的返回值表示某个视图组件。

当方法的返回值类型是String时,响应正文就会将返回的字符串将作为HTML源代码直接响应到客户端去!

还可以把@ResponseBody添加在控制器类上,则当前控制器类中所有处理请求的方法都将响应正文。

另外,还可以使用@RestController取代@Controller@ResponseBody

关于@RestController的源代码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}

可以看到,@RestController使用@Controller@ResponseBody作为其元注解,则同时具有这2个元注解的特点!

所以,@RestController的效果为:

  • 当前类是一个控制器类
  • 当前类中所有处理请求的方法都将响应正文
    • 除非某些方法使用了其它特殊的配置

@RequestMapping

@RequestMapping的主要作用是配置“请求路径”与“处理请求的方法”的映射关系。

在配置请求路径时,建议的做法是:在类和方法上分别添加此注解进行配置,在类上的配置值会和每个方法的配置值组合起来,形成完整的请求路径,所以,类上的配置值是一个“统一的URL前缀”,便于和其它控制器需要处理请求路径进行区分。

在配置请求路径时,如果配置值是有效值,则值两侧的/并不是必须的,例如:

类上的配置值方法上的配置值
/album/list
/albumlist
album/list
albumlist
/album//list
/album/list
album//list
album/list

以上所有配置的组合都是等效的!建议使用第1种或第4种。

除了配置请求路径以外,@RequestMapping注解还可以配置:

  • method:用于限制请求方式
  • produces:用于配置响应头中的文档类型

3.5关于注解的源代码

注解的源代码中,都使用了@Target作为其元注解,此注解的作用是声明当前注解可以添加在哪些位置,以@RequestMapping为例,上面就配置了:

@Target({ElementType.TYPE, ElementType.METHOD})

在注解的源代码内部,声明了此注解可以配置哪些属性,及属性的值,在@RequestMapping为例,其代码中包括:

@AliasFor("path")
String[] value() default {};

以上代码中:

  • value():表示此注解可以配置名为value的属性
  • String[]:表示此value属性的值类型是String[]
  • default {}:表示此value属性的默认值是{}(空数组)
  • @AliasFor("path"):表示此value属性与当前注解中的path属性是等效的

基于以上声明,可以:

@RequestMapping(value = {"value1", "value2", "value3"})

在所有注解中,value属性都是默认的属性,在配置此属性时,如果注解只配置这1个属性,则可以不必显式指定属性名,即:

@RequestMapping(value = {"value1", "value2", "value3"})
@RequestMapping({"value1", "value2", "value3"})

以上2种配置方式是完全等效的!

并且,在所有注解中,如果要配置的属性的值类型是数组,但是,只需要配置1个值时(数组中只有1个元素),可以不必使用{}将值框住,例如:

@RequestMapping(value = {"value1"})
@RequestMapping(value = "value1")

所以,综合看来,

@RequestMapping(value = {"value1"})
@RequestMapping(value = "value1")
@RequestMapping({"value1"})
@RequestMapping("value1")

以上4种配置是完全等效的!

@RequestMapping中的valuepath是等效的,所以,配置方式也完全相同!另外,之所以有这2个完全等效的属性,因为value使用简便,但是,每个注解都可以有value属性,所以,这个属性名称并不一定具有良好的可读性,所以,Spring MVC框架就另设计了path属性,当开发者追求简便时,使用value即可,追求代码的可读性时,则可以使用path属性。

需要注意:如果注解中需要配置多个属性,则每个属性值都必须显式的指定属性名,例如:

@RequestMapping(name = "xxx", "/list")

以上做法是错误的!!!

正确的配置方式如下:

@RequestMapping(name = "xxx", value = "/list")

以上配置中,即使是value属性,也必须显式的指定属性名!

@RequestMapping还定义了method属性:

RequestMethod[] method() default {};

此属性的作用是限制为某种请求方式,例如配置为:

@RequestMapping(value = "/add-new", method = RequestMethod.POST)

以上代码表示/add-new路径只能使用POST方式来提交请求,如果使用其它请求方式,将响应405错误。

如果没有配置method属性,则所有请求方式都是支持的!

为了简化约束请求方式,Spring MVC还提供了以下注解:

  • @GetMapping
  • @PostMapping
  • 其它

3.6接收请求参数

在Spring MVC中,可以在处理请求的方法的参数列表中,按需添加所需的请求参数(需要客户端提交什么参数,就在方法的参数列表中写什么参数)。

当设计了请求参数后:

  • 如果客户端的请求中提交了匹配名称的参数与值,则方法的参数值就是客户端提交的值
  • 如果客户端的请求中没有匹配名称的参数,则方法的参数值是null
  • 如果客户端的请求中有匹配名称的参数却没有值,则方法的参数是空字符串(""

在设计请求参数时,可以按需添加多个参数,且多个参数不区分先后顺序,各参数也可以按需设计为期望的数据类型,例如设计为:

@RequestMapping("/add-new")
public String xx(String name, Integer sort) {
}

在提交的请求中,sort参数必须是可以被转换成Integer的,否则,将出现400错误。

关于400错误:客户端没有按照服务器端的要求来提交请求参数,例如参数类型不可以被成功转换为期望的类型,或服务器要求必须提交某参数却没有提交。

关于Integer类型的请求参数:

  • 如果正确提交了此请求参数与值,则可以正确转换为数值
  • 如果提交的值不能被转换为数值,则400错误
  • 如果提交了此名称的请求参数却没有值,则方法的参数值为null
  • 如果没有提交此名称的请求参数,则方法的参数值为null

当请求参数的数量较多时,还可以将这些请求参数封装到类中,并使用这种类型作为处理请求的方法的参数!通常,建议使用专门的数据类型,而不要使用实体类型!例如:

package cn.tedu.csmall.product.pojo.dto;

import lombok.Data;

import java.io.Serializable;

@Data
public class AlbumAddNewDTO implements Serializable {

    private String name;
    private String description;
    private Integer sort;

}
// 添加相册
// http://localhost:9080/album/add-new?name=XiaoMi
@RequestMapping("/add-new")
public String addNew(AlbumAddNewDTO albumAddNewDTO) {
    log.debug("开始处理请求:{}", albumAddNewDTO);
    return "处理了/album/add-new的请求";
}

所以,在Spring MVC中,接收请求参数可以:

  • 将各个请求参数分别设计为处理请求的方法的参数
  • 将需要接收的请求参数进行封装,然后,使用封装的类型作为处理请求的方法的参数

提示:以上2种做法可以共存。

甚至,可以按需添加某些特定的参数,例如:HttpServletRequestHttpServletReponseHttpSession、其它框架允许的且添加了特定的注解的参数。

5.7RESTful风格

RESTful是一种设计URL的风格。

注意:RESTful既不是规定,也不是规范!

RESTful的典型表现是:将某些具有“唯一性”的参数值作为URL的一部分。

例如:

https://blog.youkuaiyun.com/wl_ss013/article/details/810691
https://blog.youkuaiyun.com/weixfd3811/article/details/11565346

以上URL,如果不采用RESTful风格,可能是:

https://blog.youkuaiyun.com/article/details?username=wl_ss013&id=810691
https://blog.youkuaiyun.com/article/details?username=weixfd3811&id=11565346

所以,如果需要设计“根据id删除相册”的URL,可以设计为:

http://localhost:8080/album/9527/delete

Spring MVC框架对RESTful提供了很好的支持,要实现以上效果,可以在方法上配置为:

@RequestMapping("/{id}/delete")

在处理请求的方法的参数列表中,可以声明与占位符的名称匹配的参数,并添加@PathVariable注解,即可接收到URL中的参数值:

// http://localhost:9080/album/9527/delete
@RequestMapping("/{id}/delete")
public String delete(@PathVariable Long id) {
    log.debug("开始处理删除id={}请求", id);
    return "处理了/" + id + "/delete的请求";
}

提示:如果URL中占位符的名称与方法参数的名称不匹配,可以在@PathVariable注解中配置参数,值为URL中占位符的名称即可,则方法参数的名称就不重要了!例如:

@RequestMapping("/{albumId}/delete")
public String delete(@PathVariable("albumId") Long id) {
    log.debug("开始处理删除id={}请求", id);
    return "处理了/" + id + "/delete的请求";
}

作业

创建出所有12种类型的控制器类,每个类的构造方法中都添加日志来输出,并在这些控制器中都添加“添加数据”的处理(添加处理请求的方法,并要求有DTO类,DTO类中的属性可以待定)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值