springboot三

神器之整合通用 Mapper 的开发方法

  通用 mapper 的开发方法是做练习的神器,它是基于 mybatis 的一款 MyBatis 增强插件,可以提供一些常用增、删、改、查的操作,不需要重复写一些常用的 sql。简化操作,精简代码,并且达到代码风格统一的目的。它的出现不是为了替代 mybatis,而是让 mybatis 的开发更方便。
我总结了它的使用过程:
复制代码
添加依赖:
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>4.2.2</version>
</dependency>
使用通用 mapper 的开发方式,采用注解定义映射关系,自动生成常见的 SQL 语句,不需要 xml 映射元文件
/*
1.表名默认使用类名,驼峰转下划线(只对大写字母进行处理),如 TestUser 默认对应的表名为 test_user
2.表名可以使用@Table(name = "tableName")进行指定,对不符合第一条默认规则的可以通过这种方式指定表
名.
3.字段默认和@Column 一样,都会作为表字段,表字段默认为 Java 对象的 Field 名字驼峰转下划线形式.
4.可以使用@Column(name = "fieldName")指定不符合第 3 条规则的字段名
5.使用@Transient 注解可以忽略字段,添加该注解的字段不会作为表字段使用.
6.建议一定是有一个@Id 注解作为主键的字段,可以有多个@Id 注解的字段作为联合主键.
7.默认情况下,实体类中如果不存在包含@Id 注解的字段,所有的字段都会作为主键字段进行使用(这种效率极
低).
8.实体类可以继承使用,可以参考测试代码中的 tk.mybatis.mapper.model.UserLogin2 类.
9.由于基本类型,如 int 作为实体类字段时会有默认值 0,而且无法消除,所以实体类中建议不要使用基本类型.
10.@NameStyle 注解,用来配置对象名/字段和表名/字段之间的转换方式,该注解优先于全局配置 style,可
选值:
normal:使用实体类名/属性名作为表名/字段名
camelhump:这是默认值,驼峰转换为下划线形式
uppercase:转换为大写
lowercase:转换为小写
*/
@Entity //用于声明当前类是一个实体类
@Table(name="tbl_users") // 用于声明当前类所对应的表名称
public class User implements Serializable {
@Id //用于声明标识属性,对应表中的主键
@GeneratedValue(strategy = GenerationType.IDENTITY) 声明主键生成策略
private Long id;
@Column //如果属性名称和列名称不一致,则需要通过@Column 进行配置对应的列名称
private String username;
private String password;
private Date birth;
private Boolean sex;
}
定义 mapper 接口
public interface UserMapper extends BaseMapper<User> {
}
针对 mapper 接口进行注册,一般是依赖自动扫描实现。可以在主类或者配置上添加一个注解配置
SpringBoot 针对 Junit 的单元测试有很好的支持
@SpringBootTest
class CommonMapperApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
}
@Test
void testCreate(){
User user=new User();
user.setUsername("张三丰");
user.setPassword("333333");
user.setSex(true);
int len = userMapper.insertSelective(user);
Assertions.assertEquals(1,len);
}
}
需要控制器调用业务,业务再通过 Mapper 访问数据库,最终返回 JSON 字符串
复制代码

FastJson

jackson 和 fastJson 的对比
有很多人已经习惯于使用阿里巴巴的 fastJson 来做项目中 json 转换的相关工作,比如目前项目中使用的就是阿里的 fastJson关于 fastJson 和 jackson 的对比,网上有很多资料可以查看,主要是根据自己实际项目情况来选择合适的框架。从扩展上来看,fastJson 没有 jackson 灵活,从速度或者上手难度来看,fastJson 可以考虑,项目中目前使用的是阿里的 fastJson,挺方便的。
fastJson 依赖导入
使用 fastJson 需要导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
 
使用 fastJson 处理 null
使用 fastJson 时,对 null 的处理和 jackson 有些不同,需要继承 WebMvcConfigurationSupport 类或者实现WebMvcConfiguration 接口,然后覆盖 configureMessageConverters 方法,在方法中可以选择对要实现 null转换的场景,配置好即可。
复制代码
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class fastJsonConfig extends WebMvcConfigurationSupport {
//使用阿里 FastJson 作为 JSON MessageConverter
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(
SerializerFeature.WriteMapNullValue, // 保留 map 空的字段
SerializerFeature.WriteNullStringAsEmpty, // 将 String 类型的 null 转成""
SerializerFeature.WriteNullNumberAsZero, // 将 Number 类型的 null 转成 0
SerializerFeature.WriteNullListAsEmpty, // 将 List 类型的 null 转成[]
SerializerFeature.WriteNullBooleanAsFalse, // 将 Boolean 类型的 null 转成 false
SerializerFeature.DisableCircularReferenceDetect); // 避免循环引用
converter.setFastJsonConfig(config);
converter.setDefaultCharset(Charset.forName("UTF-8"));
List<MediaType> mediaTypeList = new ArrayList<>();
// 解决中文乱码问题,相当于在 Controller 上的@RequestMapping 中加了个属性 produces ="application/json" mediaTypeList.add(MediaType.APPLICATION_JSON);
converter.setSupportedMediaTypes(mediaTypeList);
converters.add(converter);
}
}
复制代码

 

为大家推荐一个非常好用的测试工具postman

如果直接测试,则需要编写页面和 js 代码才能进行验证,可以使用 postman 避免这些繁琐的操作

 

 

Spring Boot 集成 Swagger 在线接口文档

1. Swagger 简介
1.1 解决的问题
随着互联网技术的发展,现在的网站架构基本都由原来的后端渲染,变成了前后端分离的形态,而且前端技术和后端技术在各自的道路上越走越远。前端和后端的唯一联系变成了 API 接口,所以 API 文档变成了前后端开发人员联系的纽带,变得越来越重要。那么问题来了,随着代码的不断更新,开发人员在开发新的接口或者更新旧的接口后,由于开发任务的繁重,往往文档很难持续跟着更新,Swagger 就是用来解决该问题的一款重要的工具,对使用接口的人来说,开发人员不需要给他们提供文档,只要告诉一个 Swagger 地址,即可展示在线的 API 接口文档,除此之外,调用接口的人员还可以在线测试接口数据,同样地,开发人员在开发接口时,同样也可以利用 Swagger 在线接口文档测试接口数据,这给开发人员提供了便利。
1.2 Swagger 官方
打开 Swagger 官网为 https://swagger.io/
主要掌握在 Spring Boot 中如何导入 Swagger 工具来展现项目中的接口文档。
2. Swagger 的 maven 依赖
使用 Swagger 工具,必须要导入 maven 依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
</dependency>
3. Swagger 配置
使用 Swagger 需要进行配置,Spring Boot 中对 Swagger 的配置非常方便,新建一个配置类,Swagger 的配置
类上除了添加必要的@Configuration 注解外,还需要添加@EnableOpenApi 注解。
复制代码
@EnableOpenApi
@Configuration
public class Swagger3Config {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.OAS_30) // 使用 Swagger3.0 版本
.enable(true)// 是否关闭在线文档,生产环境关闭
.apiInfo(apiInfo()) // 指定构建 api 文档的详细信息的方法
.select() // 指定要生成 api 接口的包路径,这里把 action 作为包路径,生成 controller 中的
所有接口 .apis(RequestHandlerSelectors.basePackage("com.yan.action"))
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))// 只 有 在 方 法
接口上添加了 ApiOperation 注解
.paths(PathSelectors.any()).build().globalResponses(HttpMethod.GET,
getGlobalResponseMessage())
.globalResponses(HttpMethod.POST, getGlobalResponseMessage());
}
// 生成摘要信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("接口文档") 设置页面标题
.description("说明信息") 设置接口描述
.contact(new Contact("yanjun", "http://baidu.com", "yan@yan.com")) 设置联系方式
.version("1.0") 设置版本
.build(); 构建
}
复制代码
在该配置类中已经使用注释详细解释了每个方法的作用了。到此已经配置好 Swagger 了。现在可以测试一下配置有没有生效,启动项目,在浏览器中输入 http://localhost:8080/test/swagger-ui/,即可看到 swagger 的接口页面,说明 Swagger 集成成功。对照 Swagger 配置文件中的配置,可以很明确的知道配置类中每个方法的作用。这样就很容易理解和掌握Swagger 中的配置了,也可以看出,其实 Swagger 配置很简单。有可能在配置 Swagger 时关不掉,是因为浏览器缓存引起的,清空一下浏览器缓存即可解决问题。
 
注意!!!!!!!:必须在application.properties中添加下面配置才能正常使用swagger
spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER

 

Spring Boot 中的 MVC 支持

Spring Boot 的 MVC 支持主要来最常用的几个注解,包括@RestController 用于声明控制器、@RequestMapping用于实现方法映射地址、@PathVariable 用于接受路径中的参数、@RequestParam 用于接受 request 请求中的
参数以及@RequestBody 用于接受 application/json 类型的请求信息。主要掌握几个注解常用的使用方式和特点。

1. @RestController

@RestController 是 Spring Boot 新增的一个注解,等价于@Controller+@ResponseBody
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
String value() default "";
}
可以看出@RestController 注解包含了原来的@Controller 和@ResponseBody 注解,使用过 Spring 的对@Controller 注解已经非常了解了,@ResponseBody 注解是将返回的数据结构转换为 Json 格式。所以@RestController可以看作是@Controller和@ResponseBody的结合体,为了编码方便建议使用@RestController后就不用再使用@Controller 了。@Controller 则返回的是逻辑地址名但是需要注意一个问题:如果是前后端分离,不用模板渲染的话,如 Thymeleaf,这种情况下是可以直接使用@RestController 将数据以 json 格式传给前端,前端拿到之后解析;但如果不是前后端分离,需要使用模板来渲染的话,一般 Controller 中都会返回到具体的页面,那么此时就不能使用@RestController
public String getUser() {
return "user";
}
其实是需要返回到 user.html 页面的,如果使用@RestController 的话,会将 user 作为字符串返回的。如果使用@Controller 注解则表示返回一个逻辑地址名 user 字符串,需要依赖于 ViewResovler 组件将逻辑地址名称转换为物理地址。在 Spring Boot 集成 Thymeleaf 模板引擎中会使用。
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html
如果使用@Controller,方法的返回值是字符串 user,则前后缀自动生效,将逻辑地址名
user 转换为物理地址名/user.html,静态页面默认存储位置可以考虑使用
resources/static 目录

2. @RequestMapping

@RequestMapping 是一个用来处理请求地址映射的注解,它可以用于类上,也可以用于方法上。在类的级别上的注解会将一个特定请求或者请求模式映射到一个控制器之上,表示类中的所有响应请求的方法都是以该地址作为父路径;在方法的级别表示进一步指定到处理方法的映射关系。
@Controller
@RequestMapping("/test") 表示当前类中每个方法映射路径的统一前缀/test
public class TestController {
@RequestMapping("/get") 针对方法的映射,加上类上的映射配置,则当前方法
的请求地址为/test/get
public String get(){
return "user";
}
}
该注解有 6 个属性,一般在项目中比较常用的有三个属性:value、method 和 produces。
value 属性:指定请求的实际地址,如果注解中只有一个 value 属性时,value=可以省略不写
method 属性:指定请求的类型,主要有 GET、PUT、POST、DELETE,默认为 GET。如果没有对应请求
方法的定义,则页面上报错 type=Method Not Allowed, status=405
produces 属性:指定返回内容类型,如 produces = "application/json; charset=UTF-8"
@RestController
@RequestMapping(value = "/test", produces = "application/json; charset=UTF-8")
public class TestController {
@RequestMapping(value = "/bbbb", method = RequestMethod.GET)
public String testGet() {
return "success";
}
}
针对 GET、POST、DELETE 和 PUT 四种不同的请求方式是有相应注解的,例如@GetMapping、@PostMappging等,使用对应请求的注解后则不用每次在@RequestMapping 注解中加 method 属性来指定,上面的 GET 方式
请求可以直接使用@GetMapping("/bbbb")注解,效果一样。相应地 PUT 方式、POST 方式和 DELETE 方式对应注解分别为@PutMapping、@PostMapping 和 DeleteMapping。

3. @PathVariable

@PathVariable 注解主要是用来获取 url 参数,Spring Boot 支持 restfull 风格的 url,比如一个 GET 请求携带一个参数 id 过来 localhost:8080/user?id=123,可以将 id 作为参数接收,注解使用@RequestParam。如果使用
路径参数则使用@PathVariable 注解。
@GetMapping("/user/{id}") 例如 http://localhost:8080/user/123 这里的{id}对应的就是 123 值。如果请求路径为 localhost:8080/user/abc 则由于将 abc 无法转换为 Integer 类型所以报错
public String testPathVariable(@PathVariable Integer id) { 将路径参数中的 123 赋值给方法参数 id
System.out.println("获取到的 id 为:" + id);
return "success";
}
这里需要注意一个问题,如果想要 url 中占位符中的{id}值直接赋值到参数 id 中,需要保证 url 中的参数和方法接收参数一致,否则就无法接收。如果不一致的话,其实也可以解决,需要用@PathVariable 中的 value 属性来指定对应关系。
@RequestMapping("/user/{idd}")
public String testPathVariable(@PathVariable(value = "idd") Integer id) {
System.out.println("获取到的 id 为:" + id);
return "success";
}
对于访问的 url,占位符的位置可以在任何位置,不一定非要在最后,比如这样也行/xxx/{id}/user。另外 url也支持多个占位符,方法参数使用同样数量的参数来接收,原理和一个参数是一样的
@GetMapping("/user/{idd}/{name}") 例如对应的请求地址为 localhost:8080/user/123/abc,按照位置对应
的 idd=123,name=abc
public String testPathVariable(@PathVariable(value = "idd") Integer id, @PathVariable String name) {
System.out.println("获取到的 id 为:" + id);
System.out.println("获取到的 name 为:" + name);
return "success";
}
运行项目在浏览器中请求 localhost:8080/test/user/2/zhangsan 可以看到控制台输出信息:
获取到的 id 为:2
获取到的 name 为:zhangsan
所以支持多个参数的接收。同样地,如果 url 中的参数和方法中的参数名称不同的话,也需要使用 value 属性来绑定两个参数。

4. @RequestParam

@RequestParam 也是获取请求参数的,@PathValiable 注解也是获取请求参数的,
@RequestParam 和@PathVariable 有什么不同呢?主要区别在于:@PathValiable 是从 url 模板中获取参数值,即这种风格的 url 为 http://localhost:8080/user/{id};而@RequestParam 是从 request 里面获取参数值,即这
种风格的 url 为 http://localhost:8080/user?id=1。可以使用该 url 带上参数 id 来测试代码:
@GetMapping("/user") 例如请求路径为 localhost:8080/user?id=123,将数据 123 赋值给方法中的同名参数,
如果参数不是 String 类型,则自动执行数据类型转换
public String testRequestParam(@RequestParam Integer id) {
System.out.println("获取到的 id 为:" + id);
return "success";
}
可以正常从控制台打印出 id 信息。同样地 url 上面的参数和方法的参数需要一致,如果不一致,也需要使用 value属性来说明,比如 url 为 http://localhost:8080/user?idd=1
@RequestMapping("/user") 例如请求路径为 localhost:8080/user?idd=123,如果没有@RequestParam 注解
则 id 为 null
public String testRequestParam(@RequestParam(value = "idd", required = false) Integer id) {
System.out.println("获取到的 id 为:" + id);
return "success";
除了 value 属性外,还有个两个属性比较常用:
required 属性:true 表示该参数必须要传,否则就会报 404 错误,false 表示可有可无,如果没有传递这个参数,则方法参数为 null。
defaultValue 属性:默认值,表示如果请求中没有同名参数时的默认值。
从 url 中可以看出,@RequestParam 注解用于 GET 请求上时,接收拼接在 url 中的参数【URL 重写】。除此之外,该注解还可以用于 POST 请求,接收前端表单提交的参数,假如前端通过表单提交 username 和 password
两个参数,那可以使用@RequestParam 来接收
@PostMapping("/form1")
public String testForm(@RequestParam String username, @RequestParam String password) {
System.out.println("获取到的 username 为:" + username);
System.out.println("获取到的 password 为:" + password);
return "success";
}
具体测试种可以使用 postman 来模拟一下表单提交,测试一下接口。但是如果表单数据很多,不可能在后台方法中写上很多参数,每个参数还要@RequestParam 注解。针对这种情况,需要封装一个实体类来接收这些
参数,实体中的属性名和表单中的参数名一致即可。
public class User {
private String username;
private String password;
// set get
}
使用实体接收的话,不能在前面加@RequestParam 注解了,直接使用即可。
@PostMapping("/form2")
public String testForm(User user) {
System.out.println("获取到的 username 为:" + user.getUsername());
System.out.println("获取到的 password 为:" + user.getPassword());
return "success";
}
如果写成 public String testForm(User user,String username)则提交的请求参数 username 的值会赋值两个地址,一个 user 中的 username 属性,另外一个是方法的参数 username
可以使用 postman 再次测试一下表单提交,观察一下返回值和控制台打印出的日志即可。在实际项目中,一般都是封装一个实体类来接收表单数据,因为实际项目中表单数据一般都很多。
5. @RequestBody
@RequestBody 注解用于接收前端传来的实体,接收参数也是对应的实体,比如前端通过 json 提交传来两个参数 username 和 password,此时需要在后端封装一个实体来接收。在传递的参数比较多的情况下,使用@RequestBody 接收会非常方便
控制器中方法的定义
@PostMapping("/user")
public String testRequestBody(@RequestBody User user) {
System.out.println("获取到的 username 为:" + user.getUsername());
System.out.println("获取到的 password 为:" + user.getPassword());
return "success";
}
可以使用 postman 工具来测试一下效果,打开 postman 然后输入请求地址和参数,参数用 json 来模拟,调用之后返回 success。
同时看一下后台控制台输出的日志:
获取到的 username 为:fenglei
获取到的 password 为:123456
可以看出,@RequestBody 注解用于 POST 请求上,接收 json 实体参数。它和上面表单提交有点类似,只不过参数的格式不同,一个是 json 实体,一个是表单提交。在实际项目中根据具体场景和需要使用对应的注解即
posted @   fenglei1  阅读(61)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示