驾考项目3-请求参数包装返回

288 阅读4分钟

部署JiaKaoFE

image.png

前端部署很简单 直接点击index.html 浏览器打开即可

主键增长

  configuration:
    use-generated-keys: true
  global-config:
    db-config:
      id-type: auto

Mapper接口报错 实际没啥问题

参考

// 为了减少报错 我欺骗性加了 Componet 哈哈
//@Mapper
//@Component

老太太裹脚布继续开始

截止学习到 异常统一处理前 学习到一部分封装参数问题 所以这边记录一波 方便后续继续完善

创建Maven项目

image.png

image.png

配置仓库位置

image.png

Pom.xml

属性

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

配置一些库的version

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <druid.version>1.2.1</druid.version>
    <mybatis-plus.version>3.4.1</mybatis-plus.version>
    <tinypinyin.version>2.0.3</tinypinyin.version>
    <springfox.version>3.0.0</springfox.version>
    <swagger-models.version>1.6.2</swagger-models.version>
    <mapStruct.version>1.4.1.Final</mapStruct.version>
    <captcha.version>1.6.2</captcha.version>
    <commons-io.version>2.7</commons-io.version>
</properties>

springboot项目

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.4.RELEASE</version>
</parent>
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- IO -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>${commons-io.version}</version>
        </dependency>

        <!-- 权限控制 -->
<!--        <dependency>-->
<!--            <groupId>org.apache.shiro</groupId>-->
<!--            <artifactId>shiro-spring-boot-web-starter</artifactId>-->
<!--            <version>1.7.1</version>-->
<!--        </dependency>-->

        <!-- 缓存 -->
        <dependency>
            <groupId>org.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>

        <!-- 验证码 -->
        <dependency>
            <groupId>com.github.whvcse</groupId>
            <artifactId>easy-captcha</artifactId>
            <version>${captcha.version}</version>
        </dependency>

        <!-- 对象转换 -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${mapStruct.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${mapStruct.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- 接口文档 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>${springfox.version}</version>
        </dependency>
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>${swagger-models.version}</version>
        </dependency>

        <!-- 后端校验 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <!-- AOP -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!-- 拼音 -->
        <dependency>
            <groupId>com.github.promeg</groupId>
            <artifactId>tinypinyin</artifactId>
            <version>${tinypinyin.version}</version>
        </dependency>

        <!-- 数据库 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>

        <!-- debug阶段 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- 单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

记得添加依赖 可以Maven安装一下哦

编写一个最简单的Application和Controller

配置数据库端口 创建 application.yml

项目肯定有数据库 先配置吧 不然pom.xml导入后 没用 没配置则会报错

application.yml:配置公共的部分

application-dev.yml:测试环境配置

yml

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver

  profiles:
    active: dev

mybatis-plus:
  type-aliases-package: com.mj.jk.pojo
  configuration:
    use-generated-keys: true
  global-config:
    db-config:
      id-type: auto

dev-yml

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/new_jiakao?serverTimezone=GMT%2B8

server:
  port: 8888
#  servlet:
#    context-path: /jiakao

logging:
  level:
    com.mj.jk.mapper: debug
#    root:debug


jk:
  cfg:
    cors-origins:
      - http://localhost:63342

创建Application

image.png

package com.mj.jk;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JiaKaoApplication {
    public static void main(String[] args) {
        SpringApplication.run(JiaKaoApplication.class, args);
    }
}

debug一下 默认端口是8080

image.png

创建简单控制器

设置port 和 context-path

server:
  port: 8888
  servlet:
    context-path: /jiakao

image.png

链接一下数据库

自己连接一下

image.png

开始一个最简单的 crud

有个模版技术就是Eeay Code

pojo->po->DictType.java

DictType.java

public class DictType {
    private Long id;
    private String name;
    private String value;
    private String intro;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getIntro() {
        return intro;
    }

    public void setIntro(String intro) {
        this.intro = intro;
    }
}

mapper->DictTypeMapper.java 接口

DictTypeMapper.java

public interface DictTypeMapper {
    @Select("SELECT id, name, value, intro FROM dict_type")
    List<DictType> list();
}

记得扫描哦 暂时放在Application.java 里面

@MapperScan("com.mj.jk.mapper")

service->DictTypeService.java [impl->DictTypeServiceImpl.java]

DictTypeService.java DictTypeServiceImpl.java

public interface DictTypeService {
    List<DictType> list();
}
@Service
@Transactional
public class DictTypeServiceImpl implements DictTypeService {
    @Autowired(required = false)
    private DictTypeMapper mapper;

    @Override
    @Transactional(readOnly = true)
    public List<DictType> list() {
        // 只读功能 用readOnly = true
        return mapper.list();
    }
}

接口注入报错 其实不影响编译的 解决方案加个@Component

Could not autowire. No beans of 'DictTypeMapper' type found.

image.png

image.png

controller->DictTypeController.java

DictTypeController.java

@RestController
@RequestMapping("/dictTypes")
public class DictTypeController {
    @Autowired
    private DictTypeService service;

    @RequestMapping("/list")
    public List<DictType> list() {
        return service.list();
    }
}

结果json:

image.png

JiaKao1

优化1

利用MyBatis-plus 开发项目 十分简约了

Mapper 继承 BaseMapper

public interface DictTypeMapper extends BaseMapper<DictType> {

}

service - 继承IService、ServiceImpl

public interface DictTypeService extends IService<DictType> {
}
@Service
@Transactional
public class DictTypeServiceImpl extends ServiceImpl<DictTypeMapper, DictType> implements DictTypeService {

}

控制器内无需修改因为 Mybatis-plus 里面有list方法 还有其他很多方法哦。

优化2

添加mybatis-plus分页

我目前是复制课程里面的 不过有的新的版本了 具体可以百度哦

创建一个 MyBatisPlusCfg.java

把mapper扫描放到这里吧

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.mj.jk.mapper")
public class MybatisPlusCfg {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor innerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        // 当页数超过总页数时,自动跳回到第1页
        innerInterceptor.setOverflow(true);
        interceptor.addInnerInterceptor(innerInterceptor);
        return interceptor;
    }
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }
}

注入优化

Field injuection is not recommended 参考

建议不能直接注入 修改成set方法或者构造器都可以

这个不建议的

@Autowired
private DictTypeService service;

用这个吧

private DictTypeService service;
@Autowired
public void setService(DictTypeService service) {
    this.service = service;
}

这个也行

private final DictTypeService service;
@Autowired
public DictTypeController (DictTypeService service) {
    this.service = service;
}

优化3

引入query

思路:引入 query 查询条件 把查询条件 也作为返回值 返回

PageQuery

import lombok.Data;

import java.util.List;

@Data
public class PageQuery {
    private static final int DEFAULT_SIZE = 10;
    private long page;
    private long size;
    /**
     * 总记录数
     */
    private long count;
    /**
     * 总页数
     */
    private long pages;
    private List<?> data;

    public long getPage() {
        return Math.max(1,page);
    }

    public long getSize() {
        return (size < 1) ? DEFAULT_SIZE : size;
    }
}

KeyWordQuery

import lombok.Data;
import lombok.EqualsAndHashCode;

@EqualsAndHashCode(callSuper = true)
@Data
public class KeywordQuery extends PageQuery{
    private String keyword;
}

DictTypeQuery

import lombok.Data;
import lombok.EqualsAndHashCode;

@EqualsAndHashCode(callSuper = true)
@Data
public class DictTypeQuery extends KeywordQuery{
}

service中改写方法

DictTypeQuery list(DictTypeQuery  query);
@Service
@Transactional
public class DictTypeServiceImpl extends ServiceImpl<DictTypeMapper, DictType> implements DictTypeService {
    @Override
    public DictTypeQuery list(DictTypeQuery query) {
        query.setData(list());
        return query;
    }
}

image.png

添加mapper方法进行一些条件选择

Could not autowire.NO beans of 'DictTypeMapper' type found.

解决一下吧 搞个@Compnent 在mapper中

Field injuection is not recommended

解决方案set 注入

image.png

image.png

Wrapper、Page

分页 Wrapper Page

Wrapper、LambdaQueryWrapper

image.png

@Service
@Transactional
public class DictTypeServiceImpl extends ServiceImpl<DictTypeMapper, DictType> implements DictTypeService {
    @Autowired
    private DictTypeMapper mapper;
    @Override
    public DictTypeQuery list(DictTypeQuery query) {
        LambdaQueryWrapper<DictType> wrapper = new LambdaQueryWrapper<>();
        String keyword = query.getKeyword();
        if (!StringUtils.isEmpty(keyword)) {
            wrapper.like(DictType::getName, keyword).or()
                    .like(DictType::getValue, keyword).or()
                    .like(DictType::getIntro, keyword);
        }
        query.setData(list(wrapper));
        return query;
    }
}
LambdaQueryWrapper<DictType> wrapper = new LambdaQueryWrapper<>();
String keyword = query.getKeyword();
if (!StringUtils.isEmpty(keyword)) {
    wrapper.like(DictType::getName, keyword).or()
            .like(DictType::getValue, keyword).or()
            .like(DictType::getIntro, keyword);
}
// 倒叙
wrapper.orderByDesc(DictType::getId);

搜索

http://localhost:8888/dictTypes/list?keyword=职业

page 、iPage

分页功能 记得添加mybatis的插件哦

Page<DictType> page = new Page<>(query.getPage(),query.getSize());
IPage iPage = mapper.selectPage(page, wrapper);

IPage 和 Page是一个对象

getRecords、getTotal、getPages、getCurrent、getSize

回填数据 数据、

query.setData(iPage.getRecords());
query.setCount(iPage.getTotal());
query.setPages(iPage.getPages());
query.setPage(iPage.getCurrent());
query.setSize(iPage.getSize());

优化4

enhance 继续封装query

初始化传入query

updateQuery

public class MpPage<T> extends Page<T> {
    public MpPage(PageQuery query) {
        super(query.getPage(), query.getSize());
    }

    public void updateQuery(PageQuery query) {
        query.setCount(getTotal());
        query.setPages(getPages());
        query.setData(getRecords());
        query.setPage(getCurrent());
        query.setSize(getSize());
    }
}

优化5

去掉 mapper 引入 用baseMapper

image.png

R 返回值

R.java Rs.java

统一异常处理

有个jsonable 接口 然后R 实现jsonable

拦截异常 处理 CommonExceptionHandler

JSONable

CommonException

CodeMsg

优化6

json null返回

image.png

jackson:
  default-property-inclusion: non_null

还有jsonable

image.png

mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);

异常返回的json

response.setContentType("application/json; charset=UTF-8");

Debugs

R 改造