驾考项目4-数据一致性

155 阅读2分钟

不用外键的问题

不用外键 一致性问题 1.remove开头方法很多

2.关联表很多

3.更新

数据一致性小框架

基于注解的 DictItem 的 typeId 是DictType 里面的 id

@ControllerAdvice 异常处理

@Aspect 切面 和上面的异常不要🤪混了

ForeignAspect

引入一个外键小框架 mj老师写的 引入Strings、Stop、Classes 直接拷贝Foreign到项目中 然后隐藏 JsonVos

完善 Rs 2个raise方法

使用外键注解

简单写法 和 复杂写法

image.png

image.png

删除效果

image.png

可以被多个

讲了半节课的框架 我也不懂 嘿嘿

开始场地模块 表 exam_place

截屏2022-03-09 下午3.09.01.png

create table new_jiakao.exam_place
(
    id          smallint unsigned auto_increment comment '主键'
        primary key,
    name        varchar(15)       default ''        not null comment '名称',
    province_id smallint unsigned default 0         not null comment '考场是哪个省份的',
    city_id     smallint unsigned default 0         not null comment '考场是哪个城市的',
    address     varchar(100)      default ''        not null comment '考场的具体地址',
    latitude    decimal(10, 7)    default 0.0000000 not null comment '纬度',
    longitude   decimal(10, 7)    default 0.0000000 not null comment '经度',
    constraint exam_place_city_id_name_uindex
        unique (city_id, name)
)
    comment '考场' charset = utf8mb4;


优化CommonExceptionHandler 日志、内容格式

image.png

树状结构

引入Dto

image.png

在mapper里面写方法。自己写sql啦

public interface PlateRegionMapper extends BaseMapper<PlateRegion> {
    List<ProvinceDto> selectRegions();
}

join 必须有交集的 才能查出来

image.png

left join 没有= 也能查出来 所以用LEFT JOIN

image.png

SELECT
    p.id,
    p.name,
    p.plate,
    c.id city_id,
    c.name city_name,
    c.plate city_plate
FROM plate_region p
    LEFT JOIN plate_region c ON c.parent_id = p.id
WHERE p.parent_id = 0

xml 内容

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mj.jk.mapper.PlateRegionMapper">
    <resultMap id="rmSelectRegions" type="com.mj.jk.pojo.dto.ProvinceDto">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="plate" property="plate"/>
        <collection property="children" ofType="com.mj.jk.pojo.dto.CityDto">
            <id column="city_id" property="id"/>
            <result column="city_name" property="name"/>
            <result column="city_plate" property="plate"/>
        </collection>
    </resultMap>

    <select id="selectRegions" resultMap="rmSelectRegions">
        SELECT
            p.id,
            p.name,
            p.plate,
            c.id city_id,
            c.name city_name,
            c.plate city_plate
        FROM plate_region p
                 LEFT JOIN plate_region c ON c.parent_id = p.id
        WHERE p.parent_id = 0
    </select>

</mapper>

CommonExceptionHandler 优化

之前的

@ControllerAdvice
@Slf4j
public class CommonExceptionHandler {
    @ExceptionHandler(Throwable.class)
    public void handle(Throwable t, HttpServletRequest request, HttpServletResponse response) throws Exception{
        //response.setContentType("application/json; charset=UTF-8");
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
        response.setStatus(400);
        response.getWriter().write(Rs.error(t).jsonString());
//        Debugs.run(new Runnable() {
//            @Override
//            public void run() {
//                t.printStackTrace();
//            }
//        });
//        Debugs.run(() -> {
//            t.printStackTrace();
//        });
        Debugs.run(t::printStackTrace);
         //log.error(null,t);
    }
}

之后的 @RestControllerAdvice

image.png

后端校验

前端也会校验 但是后端也需要校验哦

@NotBlank

@Valid

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
@NotBlank(message = "名称不能为空")
private String name;

image.png

如果是空的

Field error in object 'examPlace' on field 'name': rejected value []; codes [NotBlank.examPlace.name,NotBlank.name,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [examPlace.name,name]; arguments []; default message [name]];
default message [名称不能为空]

自动校验 Validator BoolNumber

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Constraint(validatedBy = BoolNumber.BoolNumberValidator.class)
public @interface BoolNumber {
    String message() default "只能是01";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    class BoolNumberValidator implements ConstraintValidator<BoolNumber, Short> {
        @Override
        public boolean isValid(Short num, ConstraintValidatorContext constraintValidatorContext) {
            return num == 0 || num == 1;
        }
    }
}
//@Range(min = 0,max = 1,message = "disabled 只能是0和1")
@BoolNumber(message = "disabled 只能是0和1")
private Integer sn;

非model注解

需要在控制器上面加 @Validated

image.png

image.png

继续追加错误

 else if(t instanceof ConstraintViolationException) {
    ConstraintViolationException cve = (ConstraintViolationException)t;
    List<String> msgs = cve.getConstraintViolations()
            .stream().map(ConstraintViolation::getMessage)
            .collect(Collectors.toList());
    // 拼接
    String msg = StringUtils.collectionToDelimitedString(msgs,", ");
    return error(msg);
}

image.png

快速失败

@Configuration
public class ValidatorCfg {
    @Bean
    public Validator validator() {
        return  Validation
                .byProvider(HibernateValidator.class)
                .configure()
                .failFast(true)
                .buildValidatorFactory().getValidator();
    }
}