我们之前,是从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);
}

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);
}
}

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

测试

新增用户

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

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

同时,也不是每个都必须写上去的。

比如用户ID是自增的,我们可以不用填

注册日期数据库会自动添加,我们不用填

登录时间不是必须的,我们不用填。

设置好后,保存,运行

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

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

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

你发现,这个注册我只需要前端填写五个参数

那么其他字段怎么办?交给后端处理,那么,我们来完善后端吧!

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

然后重新运行,测试

很好,再考虑一下,如果这个用户已经注册了呢?

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

查询单个用户

运行

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

这怎么办?

这种情况,往往是因为数据库字段名称和你Java对象中的字段名称命名风格不一致导致的。

数据库中用的下划线隔开,然而POJO对象中却是驼峰命名法。

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

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

删除用户

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

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

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

修改用户

要知道,我们不是每次修改,都把所有内容都修改了。

比如用户信息,我们只允许修改昵称和密码,但是修改昵称的时候不一定修改密码,修改密码的时候不一定修改昵称

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

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



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

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

    // 更新用户
@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);
}

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

小结

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

【参数写在哪?】

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

你要知道Get的优点缺点,Post优点缺点

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

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

然后对程序进行改进

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

2024年1月Java项目开发指南7:增删改查与接口测试的更多相关文章

  1. Java项目——模拟电话薄联系人增删改查

    该项目模拟了电话本记录联系人的业务功能,用来练习对数据库的增删改查等操作. 菜单类:Menu -- 用来封装主菜单和个选项的子菜单 Person类: Person--联系人的实体类 TelNoteRe ...

  2. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_3-2.使用Mybatis注解开发视频列表增删改查

    笔记 2.使用Mybatis注解开发视频列表增删改查     讲解:使用Mybatis3.x注解方式 增删改查实操, 控制台打印sql语句              1.控制台打印sql语句      ...

  3. 使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序

    使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻 ...

  4. java对xml文件做增删改查------摘录

    java对xml文件做增删改查 package com.wss; import java.io.File;import java.util.ArrayList;import java.util.Lis ...

  5. 使用java对sql server进行增删改查

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import ...

  6. Java API实现Hadoop文件系统增删改查

    Java API实现Hadoop文件系统增删改查 Hadoop文件系统可以通过shell命令hadoop fs -xx进行操作,同时也提供了Java编程接口 maven配置 <project x ...

  7. 基于gin的golang web开发:mysql增删改查

    Go语言访问mysql数据库需要用到标准库database/sql和mysql的驱动.标准库的Api使用比较繁琐这里再引入另一个库github.com/jmoiron/sqlx. go get git ...

  8. 基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查

    上一篇文章(https://www.cnblogs.com/meowv/p/12913676.html)我们用Code-First的方式创建了博客所需的实体类,生成了数据库表,完成了对EF Core的 ...

  9. mybatis:开发环境搭建--增删改查--多表联合查询(多对一)

    什么是mybatisMyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XML或 ...

  10. ssm项目框架搭建(增删改查案例实现)——(SpringMVC+Spring+mybatis项目整合)

    Spring 常用注解 内容 一.基本概念 1. Spring 2. SpringMVC 3. MyBatis 二.开发环境搭建 1. 创建 maven 项目 2. SSM整合 2.1 项目结构图 2 ...

随机推荐

  1. Android性能优化:getResources()与Binder交火导致的界面卡顿优化

    背景 某轮测试发现,我们的设备运行一个第三方的App时,卡顿感非常明显: 界面加载很慢,菊花转半天 滑屏极度不跟手,目测观感帧率低于15 对比机(竞品)也会稍微一点卡,但是好很多,基本不会有很大感觉的 ...

  2. 批量读取nii文件的shape

    import SimpleITK as sitk from glob import glob import os path = glob(r"D:\MyData\date\*") ...

  3. 2021年11月墨天轮国产数据库排行榜:openGauss闯入前三,Kingbase流行度与日俱增,TDengine厚积薄发

    2021年11月的国产数据库流行度排行榜已在墨天轮发布,本月共有163家数据库参与排名.就前15名的总体情况来看,除openGauss反超OceanBase闯入前三,TDengine厚积薄发来到第15 ...

  4. Oracle ADG 自动切换脚本分享

    为大家分享一个[Oracle ADG自动切换]的脚本,由云和恩墨工程师HongyeDBA编写,支持Switchover.Failover. 下载链接:https://www.modb.pro/down ...

  5. 九问 GBase | 如何看待“科技制裁”?如何助力中国数据库国产化落地?

    导读: Oracle.SAP.Apple.Google.Github等国际科技巨头纷纷宣布停止在俄罗斯业务,英特尔.AMD.戴尔等科技企业也被曝已中断向俄供货.当全面科技制裁来临,俄罗斯将如何应对此次 ...

  6. for循环、break和continue、二重循环

    循环语句 循环语句可以反复多次执行同一组语句,for关键字可以用来编写循环:可以在for循环里让一个变量依次代表一组数字,然后使用同一组语句处理这个变量代表的每个数字.这个变量叫做循环变量,按照统一的 ...

  7. MySQL数据的导入

    我们在帖子MySQL数据的导出 - brucexia - 博客园 (cnblogs.com)中讲了MySQL数据的导出,本文讲讲解MySQL数据的导入. MySQL数据的导入包括使用LOAD DATA ...

  8. 让容器通信变得简单:深度解析 Containerd 中的 CNI 插件

    作者:尹珉,KubeSphere Ambassador & contributor,KubeSphere 社区用户委员会杭州站站长. 引言 在上一篇文章中,我们详细讨论了 Kubernetes ...

  9. KubeSphere 边缘节点 IP 冲突的分析和解决思路分享

    在上一篇监控问题排查的文章中,笔者分析了 KubeSphere 3.1.0 集成 KubeEdge 中的边缘监控原理和问题排查思路,在介绍 EdgeWatcher 组件时提到了"边缘节点的内 ...

  10. go高并发之路——本地缓存

    一.使用场景 试想一个场景,有一个配置服务系统,里面存储着各种各样的配置,比如直播间的直播信息.点赞.签到.红包.带货等等.这些配置信息有两个特点: 1.并发量可能会特别特别大,试想一下,一个几十万人 ...