1.关于Mybatis小结
- 【理解】Mybatis主要解决了:简化数据库编程
- 【了解】使用Mybatis时需要添加依赖:
mysql-connector-java、mybatis-spring-boot-starter(mybatis+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>可以配置useGeneratedKeys和keyProperty属性,用于获取自动编号的id<select>必须配置resultType或resultMap其中的某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下自动创建static和templates文件夹。
一旦添加了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 |
| /album | list |
| album | /list |
| album | list |
| /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中的value和path是等效的,所以,配置方式也完全相同!另外,之所以有这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种做法可以共存。
甚至,可以按需添加某些特定的参数,例如:HttpServletRequest、HttpServletReponse、HttpSession、其它框架允许的且添加了特定的注解的参数。
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类中的属性可以待定)。
这篇博客总结了MyBatis的使用,包括配置、POJO规范和SQL映射。此外,介绍了SLF4j日志框架的基本应用和日志级别。最后,探讨了Spring MVC的基础配置、请求处理和注解使用。
1869

被折叠的 条评论
为什么被折叠?



