美文网首页微服务
SpringBoot2.0实战 | 第十章:SpringBoot

SpringBoot2.0实战 | 第十章:SpringBoot

作者: 学好该死的程序 | 来源:发表于2019-12-09 13:24 被阅读0次

在之前章节的例子中,我们在接收参数的时候都是使用的 User 类对象,这是一个 DO 对象,是用于与数据库进行交互的,而不是用于与前端业务进行交互的,所以需要创建一个 BO 业务对象用来与前端业务进行交互,保证数据隔离性及安全性。
接收参数换成了 BO 对象,但数据入库使用的是 DO 对象,这中间就需要将 BO 对象的属性复制到 DO 对象,然后代码里就会出现大量的 do.set(bo.get()),这让代码显得臃肿,繁琐。当然,通过反射或者是使用 Spring 提供的 BeanUtils.copyProperties() 等方法也可以达到简化代码的效果,但是在效率方面不尽如人意。
而 MapStruct 则提供了一种高效的解决方案,其实现方式是在编译期,自动生成相关的 do.set(bo.get()) 代码,所以,在运行期实际上就是直接调用原生的get/set 方法。

相关知识

MapStruct官网:http://mapstruct.org

课程目标

SpringBoot 整合 MapStruce 以及 Lombok

操作步骤

本文使用 Idea 集成开发环境

环境准备

  1. 安装 MapStruce 插件

File -> settings,打开 Idea 的设置界面,从左侧栏选择 Plugins 选项,再在右侧查询 MapStruce,点击安装。

  1. 设置IDE

File -> Settings 打开设置界面,
选择 Build,Execution,Deployment -> Compiler -> Annotation Processors 进入设置界面,
勾选 enable annotation processing

添加依赖

引入 Spring Boot Starter 父工程

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
</parent>

添加 mapstruct 的依赖

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.3.0.Final</version>
</dependency>

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.3.0.Final</version>
    <scope>provided</scope>
</dependency>

添加 mapstructlombok 的插件依赖

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <annotationProcessorPaths>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.3.0.Final</version>
            </path>
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

添加后的整体依赖如下

<dependencies>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
       <exclusions>
           <exclusion>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-tomcat</artifactId>
           </exclusion>
       </exclusions>
   </dependency>

   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-undertow</artifactId>
   </dependency>

   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-jpa</artifactId>
   </dependency>

   <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
   </dependency>

   <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <scope>provided</scope>
   </dependency>
   
   <dependency>
       <groupId>org.mapstruct</groupId>
       <artifactId>mapstruct-jdk8</artifactId>
       <version>1.3.0.Final</version>
   </dependency>
   
   <dependency>
       <groupId>org.mapstruct</groupId>
       <artifactId>mapstruct-processor</artifactId>
       <version>1.3.0.Final</version>
       <scope>provided</scope>
   </dependency>


   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
   </dependency>
</dependencies>

编码

  1. 编写 BO 类,用于接收前端入参
@Getter
@Setter
public class UserBO {

    /**
     * 手机号
     */
    @NotBlank(message = "手机号不能为空")
    private String mobile;

    /**
     * 密码
     */
    @NotBlank(message = "密码不能为空")
    @Length(min = 6, max = 16, message = "密码长度必须在6-16位之间")
    private String upwd;

}
  1. 编写 Mappering 转换器
  • 类上添加 @Mapper 注解,用于项目启动时自动加载
  • 方法上添加 @Mapping 注解,用于设置转换规则
  • 设置常量 INSTANCE,用于其它方法调用,也可以通过 Spring 的 IOC 进行注入
@Mapper
public interface UserMapper {

    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    @Mapping(source = "mobile", target = "name")
    User bo2Do(UserBO bo);

}
  1. 编写 controller 接口
@RestController
@RequestMapping("/user")
@Slf4j
@AllArgsConstructor
public class UserController {

    private UserRepository userRepository;

    @PostMapping("/register")
    public User register(@Valid @RequestBody UserBO userBO) {
        return userRepository.save(UserMapper.INSTANCE.bo2Do(userBO));
    }

}

验证结果

编写测试用例

@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = Application.class)
public class UserTest {

    private MockMvc mvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Before
    public void setUp() {
        mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void test1() throws Exception {
        MvcResult mvcResult = mvc.perform(
                MockMvcRequestBuilders
                .post("/register")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content("{\"mobile\":\"13700000001\",\"upwd\":\"123456\"}")
        )
        .andDo(MockMvcResultHandlers.print())
        .andReturn();

        Assert.assertEquals(200, mvcResult.getResponse().getStatus());
    }

}

源码地址

本章源码 : https://gitee.com/gongm_24/spring-boot-tutorial.git

总结

MapStruct 释放掉大量的属性复制的代码,改为编译时自动生成,所以只是精简了项目代码。

相关文章

网友评论

    本文标题:SpringBoot2.0实战 | 第十章:SpringBoot

    本文链接:https://www.haomeiwen.com/subject/cnubgctx.html