写点什么

软件测试学习笔记丨后端架构优化设计 - spring boot 增删改查操作

作者:测试人
  • 2024-05-06
    北京
  • 本文字数:7177 字

    阅读完需:约 24 分钟

本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/30757

一,springBoot 项目 导入依赖

<dependencies>		<dependency>			<groupId>org.springframework.boot</groupId>			<artifactId>spring-boot-starter-web</artifactId>		</dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.8.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.13.1</version> </dependency> <!-- mysql连接 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.29</version> </dependency> <!--mybatis坐标--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <!-- https://mvnrepository.com/artifact/tk.mybatis/mapper-spring-boot-starter --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.1.5</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.4.2.Final</version> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.7</version> <!--插件设置--> <configuration> <!--允许移动生成的文件--> <verbose>true</verbose> <!--启用覆盖--> <overwrite>true</overwrite> <!--自动生成配置 如果名字是generatorConfig.xml可以省略配置--> <configurationFile>src/main/resources/generator/generatorConfig.xml</configurationFile> </configuration> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.29</version> <scope>runtime</scope> </dependency> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper</artifactId> <version>4.1.5</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>12</source> <target>12</target> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.4.2.Final</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
<!-- <profiles>--><!-- <profile>--><!-- <id>dev</id>--><!-- <properties>--><!-- <profilesActive>dev</profilesActive>--><!-- </properties>--><!-- </profile>--><!-- <profile>--><!-- <id>test</id>--><!-- <properties>--><!-- <profilesActive>test</profilesActive>--><!-- </properties>--><!-- <activation>--><!-- <!– 设置为默认环境的配置–>--><!-- <activeByDefault>true</activeByDefault>--><!-- </activation>--><!-- </profile>--><!-- </profiles>-->
</project>
复制代码

二, 配置数据源(application.yml 文件为例)

#spring数据库连接配置spring:  datasource:    driver-class-name: com.mysql.cj.jdbc.Driver    url: jdbc:mysql://10.52.46.11:33066/advert    username: mysql    password: 123456  #Swagger页面展示内容配置  mvc:    pathmatch:      matching-strategy: ANT_PATH_MATCHER
复制代码

三,添加 mapper 扫描路径(加上 MapperScan 注解)

package com.oppo.advertSpring;
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication@MapperScan("com.oppo.advertSpring.mapper")public class AdvertSpringApplication { public static void main(String[] args) { SpringApplication.run(AdvertSpringApplication.class, args); }
}
复制代码

四,配置 mybatis 相关依赖(application.yml 文件为例)

#mybatis连接配置mybatis:  configuration:    use-actual-param-name: true  mapper-locations: classpath:mapper/*.xml  type-aliases-package: com.oppo.advertSpring.entity
复制代码

五,Bean 拷贝实现

5.1 Bean 拷贝实现的背景及解决方法

背景:

  • 前端通过接口直接操作数据库表的实体类对象,对应的字段都暴露出来,数据库字段数据泄密风险

解决方法:

  • (1)使用自定义的 dto 进行业务逻辑编写 entity:entity 是实体类,会在数据库中存在的实际的表,包括它的每一个字段 DTO: 与 Controller 交互的对象,都当做是 DTO 对象,dto 存储前端传参字段,不透露数据表

  • (2)使用 bean 拷贝 dto 的实体类与 entity 的实体类进行转换 bean 拷贝:DTO 与 entity 转换

5.2 实现工具类 mapstruct

  • 注解处理器

  • 可以生成 JavaBean 之间那的映射代码

  • 类型安全, 高性能, 无依赖性

  • 通过注解的方式帮我们实现 JavaBean 之间的转换

5.3 mapstruct 依赖导入

<dependencies>              <dependency>			<groupId>org.mapstruct</groupId>			<artifactId>mapstruct</artifactId>			<version>1.4.2.Final</version>		</dependency>	</dependencies>
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>12</source> <target>12</target> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.4.2.Final</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
复制代码

六,编写业务代码

6.1 定义一个 dto 的实体类,实体类字段根据需要取必要的传参字段,字段少于 entity 的实体类

package com.oppo.advertSpring.dto;
import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import javax.persistence.Column;import javax.persistence.Table;

@ApiModel(value = "精准词表", description = "advert.ads_search_kwctrl")@Table(name = "ads_search_kwctrl")public class AdsSearchKwctrlDto {
/** * 应用ID */ @Column(name = "app_id") private Integer appId;
/** * 关键词 */ private String keyword;
/** * 来源[1运营添加 2广告主添加] */ @ApiModelProperty(value = "来源", allowableValues = "1,2") private Integer source;
public Integer getAppId() { return appId; }
public void setAppId(Integer appId) { this.appId = appId; }
public String getKeyword() { return keyword; }
public void setKeyword(String keyword) { this.keyword = keyword; }
public Integer getSource() { return source; }
public void setSource(Integer source) { this.source = source; }
@Override public String toString() { return "AdsSearchKwctrlDto{" + "appId=" + appId + ", keyword='" + keyword + ''' + ", source=" + source + '}'; }}
复制代码

6.2 定义一个 KwctrlService 接口,传参为 dto 的实体类

package com.oppo.advertSpring.service;
import com.oppo.advertSpring.dto.AdsSearchKwctrlDto;import com.oppo.advertSpring.util.Result;
import java.text.ParseException;
public interface KwctrlService {
Result insertKwctl(AdsSearchKwctrlDto adsSearchKwctrlDto) throws ParseException;
Result updateKwctl(AdsSearchKwctrlDto adsSearchKwctrlDto) throws ParseException;
Result findKwctl(AdsSearchKwctrlDto adsSearchKwctrlDto);
Result deleteKwctl(AdsSearchKwctrlDto adsSearchKwctrlDto);
}
复制代码

6.3 创建转换类,实现 AdsSearchKwctrl 转换成 AdsSearchKwctrlDto

  • 使用 mapper 注解,导入的包为 mapstruct 的包

  • @Mapper(componentModel = “spring”) 生成的映射器是一个单例范围的 Spring bean,可以通过以下方式检索 @Autowired

package com.oppo.advertSpring.converter;
import com.oppo.advertSpring.dto.AdsSearchKwctrlDto;import com.oppo.advertSpring.entity.AdsSearchKwctrl;import org.mapstruct.Mapper;import org.mapstruct.Mapping;import org.mapstruct.Mappings;
@Mapper(componentModel = "spring")public interface AdsSearchKwctrConverter { // AdsSearchKwctrl转换成AdsSearchKwctrlDto的实现
@Mappings({ @Mapping(target = "appId", source = "appId"), @Mapping(target = "keyword", source = "keyword"), @Mapping(target = "source", source = "source") }) AdsSearchKwctrl dtoForKwctl(AdsSearchKwctrlDto adsSearchKwctrlDto);
}
复制代码

6.4 创建接口实现类 KwctrlServiceImpl

package com.oppo.advertSpring.service;
import com.oppo.advertSpring.converter.AdsSearchKwctrConverter;import com.oppo.advertSpring.dto.AdsSearchKwctrlDto;import com.oppo.advertSpring.entity.AdsSearchKwctrl;import com.oppo.advertSpring.mapper.AdsSearchKwctrlMapper;import com.oppo.advertSpring.util.Result;import com.oppo.advertSpring.util.TimestampUtil;import lombok.SneakyThrows;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import tk.mybatis.mapper.entity.Example;import java.text.ParseException;import java.util.List;
@Servicepublic class KwctrlServiceImpl implements KwctrlService {
@Autowired AdsSearchKwctrlMapper adsSearchKwctrlMapper;
@Autowired AdsSearchKwctrConverter adsSearchKwctrConverter;
TimestampUtil time = new TimestampUtil();
// @SneakyThrows @Override public Result insertKwctl(AdsSearchKwctrlDto adsSearchKwctrlDto) throws ParseException { AdsSearchKwctrl adsSearchKwctrl = adsSearchKwctrConverter.dtoForKwctl(adsSearchKwctrlDto);
adsSearchKwctrl.setInsertTime(time.timestamp()); adsSearchKwctrl.setLastModifyTime(time.timestamp()); int insertNum = adsSearchKwctrlMapper.insert(adsSearchKwctrl); System.out.println(insertNum); return Result.OK().data(adsSearchKwctrl).message("数据插入成功"); }

@Override public Result findKwctl(AdsSearchKwctrlDto adsSearchKwctrlDto) { AdsSearchKwctrl adsSearchKwctrl = adsSearchKwctrConverter.dtoForKwctl(adsSearchKwctrlDto); List<AdsSearchKwctrl> select = adsSearchKwctrlMapper.select(adsSearchKwctrl);// AdsSearchKwctrl one = adsSearchKwctrlMapper.selectOne(adsSearchKwctrl); System.out.println(select); return Result.OK().data(select).message("查找成功"); }
// @SneakyThrows @Override public Result updateKwctl(AdsSearchKwctrlDto adsSearchKwctrlDto) throws ParseException { AdsSearchKwctrl adsSearchKwctrl = adsSearchKwctrConverter.dtoForKwctl(adsSearchKwctrlDto); //查找条件,相当于select * from ads_search_kwctrl where app_id= and keyword= Example example = new Example(AdsSearchKwctrl.class); Example.Criteria criteria = example.createCriteria(); criteria.andEqualTo("appId", adsSearchKwctrl.getAppId());
List<AdsSearchKwctrl> kwctrlList = adsSearchKwctrlMapper.selectByExample(example); System.out.println("查找结果的第一条数据:" + kwctrlList.get(0)); //获取appId对应的唯一主键 Integer id = kwctrlList.get(0).getKwctrlId(); adsSearchKwctrl.setKwctrlId(id); //填充最新修改时间 adsSearchKwctrl.setLastModifyTime(time.timestamp()); //根据查找结果更新这条数据 int updateNum = adsSearchKwctrlMapper.updateByPrimaryKeySelective(adsSearchKwctrl); System.out.println( "更新数据:"+ updateNum + "条"); //查询修改后的数据 AdsSearchKwctrl selectOne = adsSearchKwctrlMapper.selectOne(adsSearchKwctrl); System.out.println("更新后的数据:"+selectOne); return Result.OK().data(selectOne).message("修改成功"); }
@Override public Result deleteKwctl(AdsSearchKwctrlDto adsSearchKwctrlDto) { AdsSearchKwctrl adsSearchKwctrl = adsSearchKwctrConverter.dtoForKwctl(adsSearchKwctrlDto); int delete = adsSearchKwctrlMapper.delete(adsSearchKwctrl); System.out.println(delete); return Result.OK().data(adsSearchKwctrl).message("删除成功"); }



}
复制代码

6.5 controller 创建对应的接口

package com.oppo.advertSpring.controller;
import com.oppo.advertSpring.dto.AdsSearchKwctrlDto;import com.oppo.advertSpring.entity.AdsSearchKwctrl;import com.oppo.advertSpring.service.KwctrlService;import com.oppo.advertSpring.util.Result;import io.swagger.annotations.ApiOperation;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RestController;import java.text.ParseException;
@RestControllerpublic class KwctrlController {
@Autowired KwctrlService kwctrlService;
@ApiOperation("精准词insert接口") @PostMapping(path = "/insertKwctl", produces = "application/json") Result insertKwctl(@RequestBody AdsSearchKwctrlDto adsSearchKwctrlDto) throws ParseException { return kwctrlService.insertKwctl(adsSearchKwctrlDto); }

@ApiOperation("精准词find接口") @PostMapping(path = "/findKwctl", produces = "application/json") Result findKwctl(@RequestBody AdsSearchKwctrlDto adsSearchKwctrlDto){ return kwctrlService.findKwctl(adsSearchKwctrlDto); }

@ApiOperation("精准词update接口") @PostMapping(path = "/updateKwctl", produces = "application/json") Result updateKwctl(@RequestBody AdsSearchKwctrlDto adsSearchKwctrlDto) throws ParseException { return kwctrlService.updateKwctl(adsSearchKwctrlDto); }

@ApiOperation("精准词delete接口") @PostMapping(path = "/deleteKwctl", produces = "application/json") Result deleteKwctl(@RequestBody AdsSearchKwctrlDto adsSearchKwctrlDto){ return kwctrlService.deleteKwctl(adsSearchKwctrlDto); }
}
复制代码

6.6 Swagger 页面调用接口看是否正常


软件测试开发免费视频教程分享


发布于: 刚刚阅读数: 3
用户头像

测试人

关注

专注于软件测试开发 2022-08-29 加入

霍格沃兹测试开发学社,测试人社区:https://ceshiren.com/t/topic/22284

评论

发布
暂无评论
软件测试学习笔记丨后端架构优化设计 - spring boot 增删改查操作_软件测试_测试人_InfoQ写作社区