学习目标:开发中常见注意事项
学习内容:
- 锁:悲观锁/乐观锁
- 悲观锁:只要操作数据就上锁,别的线程无法访问,效率低
- 乐观锁:当要更新记录时,检查该记录是否被修改过,若没有有改过则直接提交,修改过则回退,更新失败
- 配置类:写在启动类中的配置均可写在配置类中,简化启动类,配置类需加@Configuration注解
@Configuration
@MapperScan("com.atguigu.mpdemo1010.mapper")
public class MpConfig {
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
- 父工程简介
- 子模块简介
- Mybatis-Plus代码生成器:自动根据数据库内容生成Controller,service,entity等代码
<!-- velocity 模板引擎, Mybatis Plus 代码生成器需要 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
</dependency>
public class CodeGenerator {
@Test
public void main1() {
AutoGenerator mpg = new AutoGenerator();
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
System.out.println(projectPath);
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("atguigu");
gc.setOpen(false);
gc.setFileOverride(false);
gc.setServiceName("%sService");
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://8.140.167.86:3306/guli?serverTimezone=GMT%2B8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
PackageConfig pc = new PackageConfig();
pc.setModuleName("eduserviceedu");
pc.setParent("com.atguigu");
pc.setController("controller");
pc.setEntity("entity");
pc.setService("service");
pc.setMapper("mapper");
mpg.setPackageInfo(pc);
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("edu_teacher");
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setTablePrefix(pc.getModuleName() + "_");
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
mpg.setStrategy(strategy);
mpg.execute();
}
}
- //@RestController = @Controller(交给spring管理) + @ResponseBody(返回json类型数据)
- rest风格:每种请求用到不同的请求方式
- 查询:GetMapping(“请求地址”)
- 删除:DeleteMapping(“{参数}”):在请求路径中传参数时,需在方法的形参前加注解:@PathVariable。(逻辑删除)
@DeleteMapping("{id}")
public boolean deleteTeacherByID(@PathVariable String id){
boolean flag = eduTeacherService.removeById(id);
return flag;
}
- 返回json格式时,时间会带时区,在配置文件中加如下配置即可
#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
- 测试工具:swagger、postman
- swagger:
- 生成在线接口文档
- 方便接口测试
- 使用步骤:一般放在Common模块中
- 引入依赖
- 编写配置类
- 引入Common模块依赖
- 若配置类和启动类不在同一个项目,需在启动类上加注解:@ComponentScan(basePackages = {“com.atguigu”})
- 访问即可,路径:http://localhost:项目模块端口/swagger-ui.html
- 可以在controller上添加注解,在swagger上增加中文注释
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<scope>provided </scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<scope>provided </scope>
</dependency>
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket webApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("webApi")
.apiInfo(webApiInfo())
.select()
.paths(Predicates.not(PathSelectors.regex("/admin/.*")))
.paths(Predicates.not(PathSelectors.regex("/error.*")))
.build();
}
private ApiInfo webApiInfo(){
return new ApiInfoBuilder()
.title("网站-课程中心API文档")
.description("本文档描述了课程中心微服务接口定义")
.version("1.0")
.contact(new Contact("chenhao","http://atguigu.com","1036640646@qq.com"))
.build();
}
}
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>service_base</artifactId>
<version>1.0.0</version>
</dependency>
@SpringBootApplication
@ComponentScan(basePackages = {"com.atguigu"})
public class EduApplication {
public static void main(String[] args) {
SpringApplication.run(EduApplication.class,args);
}
}
- 统一返回数据格式:R,方便前端解析,示例如下,链式编程
{
"success": 布尔,
"code": 数字,
"message": 字符串,
"data": HashMap
}
@Data
public class R {
@ApiModelProperty(value = "是否成功")
private Boolean success;
@ApiModelProperty(value = "返回码")
private Integer code;
@ApiModelProperty(value = "返回消息")
private String message;
@ApiModelProperty(value = "返回数据")
private Map<String, Object> data = new HashMap<String, Object>();
private R(){}
public static R ok(){
R r = new R();
r.setSuccess(true);
r.setCode(ResultCode.SUCCESS);
r.setMessage("成功");
return r;
}
public static R error(){
R r = new R();
r.setSuccess(false);
r.setCode(ResultCode.ERROR);
r.setMessage("失败");
return r;
}
public R success(Boolean success){
this.setSuccess(success);
return this;
}
public R message(String message){
this.setMessage(message);
return this;
}
public R code(Integer code){
this.setCode(code);
return this;
}
public R data(String key, Object value){
this.data.put(key, value);
return this;
}
public R data(Map<String, Object> map){
this.setData(map);
return this;
}
}