首页 > 编程语言 >2024年1月Java项目开发指南7:增删改查与接口测试

2024年1月Java项目开发指南7:增删改查与接口测试

时间:2024-01-25 18:12:31浏览次数:32  
标签:xrilang Java Users userId 改查 2024 user import public

我们之前,是从Controller层写到Service层,然后mapper层。

接下来我们反过来,从mapper层写到Controller层

两种方式都可以,你喜欢就行,甚至你先写service层也可以,全凭个人喜欢。

在本文中,就不解释太多了,直接给出代码,对于关键地方,我会圈出来。
如果有问题,可以直接在本文首发地址(博客园 萌狼蓝天)评论留言,或者进入问答社区提问:ask.xrilang.top

Mapper


package cc.xrilang.serversystem.mapper;

import cc.xrilang.serversystem.domain.Users;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface UsersMapper {
    @Insert("INSERT INTO users (user_nickname, user_account, user_password, user_reg_time, user_last_login_time, user_status, user_identity, remarks) VALUES (#{userNickname}, #{userAccount}, #{userPassword}, #{userRegTime}, #{userLastLoginTime}, #{userStatus}, #{userIdentity}, #{remarks})")
    void insertUser(Users user);

    @Select("SELECT * FROM users")
    List<Users> selectAllUsers();

    @Select("SELECT * FROM users WHERE user_id = #{userId}")
    Users selectUserById(long userId);

    @Update("UPDATE users SET user_nickname = #{userNickname}, user_account = #{userAccount}, user_password = #{userPassword}, user_last_login_time = #{userLastLoginTime}, user_status = #{userStatus}, user_identity = #{userIdentity}, remarks = #{remarks} WHERE user_id = #{userId}")
    void updateUser(Users user);

    @Delete("DELETE FROM users WHERE user_id = #{userId}")
    void deleteUserById(long userId);
}

image

Service(Interface)

package cc.xrilang.serversystem.service;

import cc.xrilang.serversystem.domain.Users;
import java.util.List;

public interface UsersService {
    Users createUser(Users user);
    List<Users> readAllUsers();
    Users readUser(long userId);
    Users updateUser(Users user);
    void deleteUser(long userId);
}

Service(impl)

package cc.xrilang.serversystem.service.impl;

import cc.xrilang.serversystem.domain.Users;
import cc.xrilang.serversystem.mapper.UsersMapper;
import cc.xrilang.serversystem.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UsersServiceImpl implements UsersService {

    @Autowired
    private UsersMapper usersMapper;

    @Override
    public Users createUser(Users user) {
        usersMapper.insertUser(user);
        return user;
    }

    @Override
    public List<Users> readAllUsers() {
        return usersMapper.selectAllUsers();
    }

    @Override
    public Users readUser(long userId) {
        return usersMapper.selectUserById(userId);
    }

    @Override
    public Users updateUser(Users user) {
        usersMapper.updateUser(user);
        return user;
    }

    @Override
    public void deleteUser(long userId) {
        usersMapper.deleteUserById(userId);
    }
}

Controller

package cc.xrilang.serversystem.controller;

import cc.xrilang.serversystem.domain.Users;
import cc.xrilang.serversystem.service.UsersService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;


@Controller
/***
 * 用户控制器
 * 如果这里写的controller 那么想返回实体数据而不是一个页面的话,那后面的方法需要写上@ResponseBody
 * 如果这里写的@RestController 那么返回的是json数据,后面的方法不需要写上@ResponseBody
 */
@RequestMapping("/users")
public class UsersController {

    @Autowired
    private UsersService usersService;


    // 读取用户列表
    @GetMapping
    @ResponseBody
    public List<Users> readAllUsers() {
        return usersService.readAllUsers();
    }

    // 增加用户
    @PostMapping
    @ResponseBody
    public Users createUser(@RequestBody Users user) {
        return usersService.createUser(user);
    }



    // 读取单个用户
    @GetMapping("/{userId}")
    @ResponseBody
    public Users readUser(@PathVariable long userId) {
        return usersService.readUser(userId);
    }

    // 更新用户
    @PutMapping
    @ResponseBody
    public Users updateUser(@RequestBody Users user) {
        return usersService.updateUser(user);
    }

    // 删除用户
    @DeleteMapping("/{userId}")
    @ResponseBody
    public void deleteUser(@PathVariable long userId) {
        usersService.deleteUser(userId);
    }
}

增删改查都写好了,接下来去测试

测试

新增用户

image

image

要注意,这个接口是需要参数的

image

请注意,这些参数不是乱写的,要和domain.users里面设置的一样

image

同时,也不是每个都必须写上去的。
比如用户ID是自增的,我们可以不用填
注册日期数据库会自动添加,我们不用填
登录时间不是必须的,我们不用填。
设置好后,保存,运行

image

可以看到数据库中新增了一条数据。

我们还可以为参数写一些注释,以便我们后续查看

image

还可以结合Mock生成数据以便测试
image

你发现,这个注册我只需要前端填写五个参数
那么其他字段怎么办?交给后端处理,那么,我们来完善后端吧!

image

image

你可以在后端设置一些前端不用填写,但是添加数据时又应该有数据的参数

然后重新运行,测试

image

image

很好,再考虑一下,如果这个用户已经注册了呢?
因此,我们需要在后端判断一下用户是否已注册,你可以尝试自己写一下,也可以看下一篇笔记我对这个功能实现的详细补充。

查询单个用户

image

image

运行
image

好,假设你明明有数据,但是查询出来,比如姓名为null,账号为null,全都是null
这怎么办?
image

这种情况,往往是因为数据库字段名称和你Java对象中的字段名称命名风格不一致导致的。
数据库中用的下划线隔开,然而POJO对象中却是驼峰命名法。

解决这个问题的方法有很多,最简单的方法就是在配置文件中添加一条自动命名匹配的配置:

# 使用该配置可以让 MyBatis 自动将 SQL 中查出来的带下划线命名的字段, 自动转换 为驼峰命名,再去匹配类中的属性。
mybatis.configuration.map-underscore-to-camel-case=true

image

删除用户

删除用户就简单了,参数也是就在URL中的

image

image

要注意的是,这次不是get,而是delete哦

image

由于返回值是void,因此没有返回内容,这个我们后面完善。不管成功失败,都应该有个返回内容才是。

修改用户

要知道,我们不是每次修改,都把所有内容都修改了。
比如用户信息,我们只允许修改昵称和密码,但是修改昵称的时候不一定修改密码,修改密码的时候不一定修改昵称

image

上面这些是允许修改的,id是必须的,其他的都不是必须的。

比如,我们给id 6改个姓名

image
可以看到,后端发生了报错,我们没有填写其他参数

image

可是如果我光改个名字还得把所有参数填一遍,多麻烦,因此,我们在后端设置一下自动填充。

    // 更新用户
    @PutMapping
    @ResponseBody
    public Users updateUser(@RequestBody Users user) {
        //获取参数的内容
        String userNickname = user.getUserNickname();
        String userPassword = user.getUserPassword();
        String userIdentity = user.getUserIdentity();
        Timestamp userLoginTime = user.getUserLastLoginTime();
        String remarks = user.getRemarks();
        long userStatus = user.getUserStatus();
        long userId = user.getUserId();
        //根据ID查出原本的数据
        Users u= usersService.readUser(userId);
        if (u == null) {
            return null;
        }
        //将需要修改的内容替换进去
        if (userNickname != null) {
            u.setUserNickname(userNickname);
        }
        if (userPassword != null) {
            u.setUserPassword(userPassword);
        }
        if (userIdentity != null) {
            u.setUserIdentity(userIdentity);
        }
        if (userLoginTime != null) {
            u.setUserLastLoginTime(userLoginTime);
        }
        if (remarks != null) {
            u.setRemarks(remarks);
        }
        if (userStatus != 0) {
            u.setUserStatus(userStatus);
        }
        return usersService.updateUser(u);
    }

image

这时候,光改姓名也可以了

小结

你要知道,什么时候参数写在路径中,什么时候写在param中,什么时候写在body中
【参数写在哪?】

你要知道,选择什么请求方法(Get,Post,Put等等)

你要知道Get的优点缺点,Post优点缺点
你要知道Put有什么用,Opinion是什么(虽然这次没用到,但是你最好了解一下)

既然这是一个测试,那你就要从这个接口测试中发现问题(缺陷,或者不足)
然后对程序进行改进

增删改查的大致功能和测试先到这里了,后续我们继续完善后端的功能,比如实现密码加密存储,统一返回值的格式等等

标签:xrilang,Java,Users,userId,改查,2024,user,import,public
From: https://www.cnblogs.com/mllt/p/17987804/project202401-7

相关文章

  • JAVA调用Python脚本执行
    SpringBoot-web环境<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>springboot--启动类@SpringBootApplication(ex......
  • java aspect 切面怎么获取 POST 数据
    javaaspect切面怎么获取POST数据/***切面*/@Aspect@ComponentpublicclassPostRequestBodyAspect{@Pointcut("execution(*com.example.controller.*.*(..))")publicvoidcontrollerMethods(){}......
  • html 中javascript 如何被调用
    在HTML中,JavaScript可以通过多种方式进行调用。1.内联脚本(InlineScript):直接将JavaScript代码写入到HTML文件的<script>标签中。示例代码如下所示:<!DOCTYPEhtml><html><head><title>使用内联脚本</title></head><body><!--HTML页面内容--><scripttyp......
  • JAVA学习笔记--使用Inte IDEA
    使用IntellijIDEA编写代码新建项目创建新项目选择创建一个空项目并输入项目名弹出ProjecStructure窗口先关闭新建一个模板(Module)并输入模板名打开前面关闭的ProjecStructure窗口修改以下信息(注意:安装的是JDK8则按照以下信息修改,若安装的是JDK其他版本则......
  • JAVA学习笔记--数据类型及注意事项
    Java的数据类型(笔试考题)Java是强类型语言:要求变量使用要严格符合规定,所有变量都必须先定义后才能使用基本类型(primitivetype)数据类型整数类型byte(1字节):-128~127short(2字节):-32768~32767int(4字节):-2147483648~2147483647(最常用)long(8字节):-9223372036854775808~922......
  • JAVA学习笔记--变量与常量
    变量局部变量注意:必须声明并且必须初始化值publicclassHello{//main方法publicstaticvoidmain(String[]args){//局部变量,只在{}内使用inti=10;System.out.print(i);}//其他方法publicvoidadd(){......
  • 2024年1月Java项目开发指南6:接口测试
    我们使用APIFox这款工具对接口进行测试。(你要是会其他的例如postman进行测试也行)https://apifox.com/新建一个项目,新增一个接口因为这个接口没有参数,所以无需填写参数,保存然后点击运行没有设置环境记得先去设置环境我们配置开发环境保存然后选择开发环境进行使用......
  • 2024年1月Java项目开发指南5:controller、service、mapper
    准备工作你知道什么是JSON吗?JSON是什么?格式是什么?有什么用?有什么优点?有什么缺点?请自己百度探索一下,对JSON做了个了解,如果你不知道什么是JSON的话,知道就免了,直接下一步吧。开始:项目目录结构先确保你已经创建了上图的那些文件夹。这都是我们需要用到。简单的做个介绍co......
  • Java中SimpleDateFormat时YYYY与yyyy以及HH和hh的区别注意踩坑
    场景Java开发手册中为什么要求SimpleDateFormat时用y表示年,而不能用Y:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131052335在使用SimpleDateFormat在获取当前日期时因使用了YYYY导致20231231这个日期被格式化为20241231这里推荐在日期处理时统一使用封装工具......
  • java线程数量如何确定
    1.概述使用线程池的好处降低资源消耗:线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,通过重复利用己创建的线程可以降低线程创建和销毁造成的消耗。提高响应速度:当任务到达时,可以不需要等待线程创建就能立即执行提高线程的可管理性:线程池提......