是测试就要知道系列之黑盒不黑: IDEA SpringBoot实现增删改查
个人觉得很值得亲自动手实现的基础开发功能,前前后后公司内分享好几次,反响很不错的
不讲原理,网上很多很深入。主要看操作,在实现过程中理解:测试对象「黑盒里的结构」。由此可以发挥自己的兴趣一步一步拓展,比如:实现导入导出功能,实现批量插入,对异常的报错处理 等,这样就知道后端是如何处理这些功能的。
单功能实现不难的,对测试很有价值。
后端开发难点在于满足性能的并发处理,分布式,中间件等等架构方面的建设,也是测试人员下一步努力的方向(熟悉通用中间件,比如Kafka,redis等,可以使用Jmeter压测Kafka)
⚠️由于是培训文件,需要查一些资料配合服用,效果更好
目录:
一、Springboot框架简介
二、配置文件(maven项目)
三、工程目录结构
四、代码实现
五、调用接口操作数据库
一、Springboot框架简介
1、用到到工具 IDEA:全称 IntelliJ IDEA
2、环境配置 JAVA8、apache-maven-3.6.1
3、DBMS mysql-8.0.27-macos11-x86_64.dmg免费开源的关系型数据库管理系统
4、开发框架 SpringBoot+Mybatis Mybatis原理:读取MyBatis的配置文件,加载映射文件(mapper.xml),构造数据库会话链接(简单来说就是优化JDBC)
什么是SpringBoot
1、 用来简化spring应用的初始搭建以及开发过程 使用特定的方式来进行配置(properties或yml文件)
2、 创建独立的spring引用程序 main方法运行
3、 嵌入的Tomcat 无需部署war文件
4、 简化maven配置
二、配置文件(maven项目)
1、什么是Maven? Maven是一个项目管理工具
2、 核心功能 通过pom.xml文件的配置获取jar包不用手动的去添加jar包
3、 管理jar包过程 通过 pom.xml 文件配置要引入的 jar 包的坐标,再读取坐标并到仓库中加载 jar 包,这 样我们就可以直接使用 jar 包了。
4、 仓库 「仓库」就是存放jar包的地方,即前面说的通过pom.xml中通过设置索引来到仓库中寻找jar包;仓库分为:本地仓库,第三方仓库,中央仓库
5、settings.xml
三、工程目录结构
1、项目根目录/src/main/java:放置项目Java源代码
2、项目根目录/src/main/resources:放置项目静态资源和配置文件
3、项目根目录/src/test/java:放置项目测试用例代码
四、代码实现
1、 创建user表--DBMS+可视化工具
CREATE TABLE `module_config` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主键', `user_name` varchar(255) NOT NULL COMMENT '用户名', `real_name` varchar(255) NOT NULL COMMENT '真名', `sex` varchar(255) NOT NULL COMMENT '性别', `create_time` timestamp DEFAULT CURRENT_TIMESTAMP, `update_time` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=UTF8MB4 COMMENT='用户表';
2、 实体定义、关系映射、数据访问层代码接口--entity、mapper、mapper.xml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.example.demo.entity; public class User { private Integer id; private String userName; private String passWord; private String realName; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } @Override public String toString() { return "User{" + "id=" + id + ", userName='" + userName + '\'' + ", passWord='" + passWord + '\'' + ", realName='" + realName + '\'' + '}'; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.example.demo.mapper; import com.example.demo.entity.User; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface UserMapper { /** * 根据id查询用户信息 * @param id * @return */ User getUserInfo(int id); /** * 新增用户 * @param user * @return */ int save (User user); /** * 更新用户信息 * @param user * @return */ int update (User user); /** * 根据id删除 * @param id * @return */ int deleteById (int id); /** * 查询所有用户信息 * @return */ List<User> selectAll (); }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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.example.demo.mapper.UserMapper"> <!--增加用户信息--> <insert id="save"> insert into user <trim prefix="(" suffix=")" suffixOverrides="," > <if test="id != null" > id, </if> <if test="userName != null" > userName, </if> <if test="passWord != null" > passWord, </if> <if test="realName != null" > realName, </if> </trim> <trim prefix="values (" suffix=")" suffixOverrides="," > <if test="id != null" > #{id,jdbcType=INTEGER}, </if> <if test="userName != null" > #{userName,jdbcType=VARCHAR}, </if> <if test="passWord != null" > #{passWord,jdbcType=VARCHAR}, </if> <if test="realName != null" > #{realName,jdbcType=VARCHAR}, </if> </trim> </insert> <!--根据id更改用户信息--> <update id="update"> update user <set > <if test="userName != null" > userName = #{userName,jdbcType=VARCHAR}, </if> <if test="passWord != null" > passWord = #{passWord,jdbcType=VARCHAR}, </if> <if test="realName != null" > realName = #{realName,jdbcType=VARCHAR}, </if> </set> where id = #{id,jdbcType=INTEGER} </update> <!--删除用户信息--> <delete id="deleteById"> delete from user where id=#{id} </delete> <!--查询用户信息--> <select id="getUserInfo" resultType="com.example.demo.entity.User"> select * from user where id = #{id} </select> <!--返回所有用户信息--> <select id="selectAll" resultType="com.example.demo.entity.User"> select * from user </select> </mapper>
3、 控制器代码--controller
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.example.demo.controller; import com.example.demo.entity.User; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; //主要包括2个注解:1、@Controller处理 Http 请求;2、@ResponseBody返回 json 格式 @RestController //@RequestMapping处理请求地址映射的注解 @RequestMapping("/testBoot") public class UserController { @Autowired private UserService userService; // 通过用户id获取用户所有信息 // http://localhost:8081/testBoot/getUser/1(此处1为要获取的id) @RequestMapping(value = {"getUser/{id}","getUser/"}, method = RequestMethod.GET) public String GetUser(@PathVariable(required = false) int id) { return userService.getUserInfo(id).toString(); } //查询全量数据 //http://localhost:8081/testBoot/selectAll @RequestMapping("/selectAll") @ResponseBody public List<User> ListUser() { return userService.selectAll(); } // 插入新用户 // http://localhost:8081/testBoot/insert?id=100&userName=同事1&passWord=123456&realName=好好好 @RequestMapping(value = "/insert", method = RequestMethod.POST) public User insert(User user) { return userService.save(user); } // 通过用户id删除用户 // http://localhost:8081/testBoot/delete?id=1(此处1为要删除的id) @RequestMapping(value = "/delete", method = RequestMethod.DELETE) public String delete(int id) { int result = userService.deleteById(id); if (result >= 1) { return "删除成功"; } else { return "删除失败"; } } //根据用户id更新用户信息 //http://localhost:8081/testBoot/update?id=2&userName=波波&passWord=123456&realName=lalala @RequestMapping(value = "/update", method = RequestMethod.GET) public String update(User user) { int result = userService.Update(user); if (result >= 1) { return "修改成功"; } else { return "修改失败"; } } }
4、 业务逻辑代码--service
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.example.demo.service; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; @Service public class UserService { @Autowired UserMapper userMapper; public User getUserInfo(int id) { return userMapper.getUserInfo(id); } public int deleteById(int id) { return userMapper.deleteById(id); } public int Update(User user) { return userMapper.update(user); } public User save(User user) { int save = userMapper.save(user); return user; } public List<User> selectAll() { return userMapper.selectAll(); } }
五、调用接口操作数据库
1、 postman调用接口,操作数据库
2、查看结果是否符合预期
3、异常请求处理
a.请求参数为空处理:非必传参数required = false
b.请求参数为不存在: