前言
转载请注明原文地址:https://blog.csdn.net/qq_43055855/article/details/110006813
1.实战这三天,实训Advisor讲了个小实战项目——增删改查的实战嘛,俗话说毕业的初级程序不就是干crud的嘛,只有扎实于基础才能在未来的面试中游刃有余。再次写下来加深印象.项目源代码:
链接:https://pan.baidu.com/s/1ri0WRaQZlxSyrQ2sQiqvHA
提取码: weh7
2.此项目适合学完springboot基础的小白,讲解的代码参照写可以实现运行效果。小项目主要涉及到三层代码逻辑:控制层、数据持久层、业务逻辑层。通过springboot与后台数据库进行通信并实现对员工数据表的增删改查工作。
3.创作不易,如果这篇博客对你有帮助的话最后别忘了点个赞,投个币,收个藏,转个发再走噢,爱你哟~
一、项目准备
1.数据库
1.1、创建数据库
在MySql数据库创建usermanage数据库,SQL脚本语句如下:
/*1.在MySQL中创建数据库:usermanage的脚本:*/
CREATE DATABASE usermanage
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
刷新后可以看到数据库被创建出来。
之后使用这个数据库。
/*2.使用usermanage数据库:*/
use usermanage;
1.2、创建表
在usermanage数据库中创建表userinfo,SQL脚本语句如下:
CREATE TABLE `userinfo` (
`id` int(11) NOT NULL auto_increment COMMENT '用户主键',
`user_name` varchar(50) NOT NULL COMMENT '用户名',
`pwd` varchar(50) NOT NULL DEFAULT '123456' COMMENT '用户密码',
`type` char(1) DEFAULT NULL COMMENT
'用户类型:1 普通用户,9 管理员',
`sex` char(1) DEFAULT NULL COMMENT
'用户性别:1 男 0 女',
`degree` char(1) DEFAULT NULL COMMENT
'用户学历:1 研究生 2 本科 3 高中 4初中 5小 学',
`avatar` varchar(100) DEFAULT NULL COMMENT
'用户头像图片地址',
`hobby` varchar(100) DEFAULT NULL COMMENT
'用户爱好:游泳,体育,滑冰',
`content` varchar(500) DEFAULT NULL COMMENT '描述',
`birthday` date DEFAULT NULL COMMENT
'用户生日',
PRIMARY KEY (`id`) )
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息表';
操作步骤:
执行一下SQL语句可以看到
数据库多了用户信息表。
紧接着咱们增加user_name的唯一索引。
ALTER TABLE `usermanage`.`userinfo`
ADD UNIQUE INDEX `USER_NAME_UNIQUE`(`user_name`) USING BTREE COMMENT '用户名唯一';
表示用户名是唯一的,不能重复。
2、新建项目
2.1、创建SpringBoot项目
项目名:usermanage-api
核心依赖如下表:
2.2、项目的目录、文件、包结构
2.3、配置mybatis框架
2.3.1、分页插件
在pom.xml添加springboot的分页启动插件依赖,代码如下:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
2.3.2、mybatis-config.xml
在src/main/resources/mybatis文件夹中新建mybatis-config.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 全局参数 -->
<configuration>
<settings>
<!-- 使用驼峰命名法转换字段,如:将 user_name 转换为 userName -->
<setting name="mapUnderscoreToCamelCase" value="true" />
<!-- 使全局的映射器启用或禁用缓存。 -->
<setting name="cacheEnabled" value="true" />
<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会
按需要加载。 -->
<setting name="aggressiveLazyLoading" value="true" />
<!-- 是否允许单条sql 返回多个数据集 (取决于驱动的兼容性) default:true -->
<setting name="multipleResultSetsEnabled" value="true" />
<!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
<setting name="useColumnLabel" value="true" />
<!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键
,有一些驱动器不兼容不过仍然可以执行。 default:false -->
<setting name="useGeneratedKeys" value="true" />
<!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不隐射 PARTIAL:部分 FULL:全部-->
<setting name="autoMappingBehavior" value="PARTIAL" />
<!-- 这是默认的执行类型 (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared
statements语句;BATCH:执行器可以重复执行语句和批量更新) -->
<setting name="defaultExecutorType" value="SIMPLE" />
<!-- 设置本地缓存范围 session:就会有数据的共享 statement:语句范围 (这样就不会有数据的共
享 ) defalut:session -->
<setting name="localCacheScope" value="SESSION" />
<!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER,插入空值时不需要指定类
型 -->
<setting name="jdbcTypeForNull" value="NULL" />
<!-- 设置日志 -->
<setting name="logImpl" value="LOG4J" />
</settings>
</configuration>
2.3.3、mapper文件夹
在src/main/resources/mybatis目录下新建mapper文件夹存放每个dao的SQL映射文件。这个dao就是我们常说的接口功能部分,数据控制层里面的接口。
3、配置SpringBoot
3.1、创建application.yml配置文件
#配置服务器的启动端口
server:
port: 8080
spring:
#配置数据库连接的相关信息
datasource:
url: jdbc:mysql://localhost:3306/usermanage?characterEncoding=utf8&useSSL=false&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
#配置应用的名称
application:
name: usermanage-api
#配置MyBatis的相关信息
mybatis:
config-location: classpath:mybatis/mybatis.config.xml
mapper-locations: classpath:mybatis/mapper/*Mapper.xml
type-aliases-package: com.neusoft.usermanage.entity
#配置分页的相关信息
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
注意:这里的层级目录不能写错了,如果出现黄色的提示说明这里的配置代码是不起作用的。比如:
这样的话是不能连接数据库的,会报jdbc datesource连接不上的异常错误。
3.2、日志配置
使用log4j日志框架来配置日志信息,因为作为一名专业的程序员,老师说要养成写日志配置的习惯,因为这样报错、日期、项目信息的运行情况就会打印出来,方便以后寻找。
3.2.1.添加log4j依赖
(1) 排除web包中默认的logback日志依赖;
(2) 添加log4j依赖。
关于使用log4j日志相关的pom.xml中的代码如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
3.2.2、添加日志配置文件
在src/main/resources目录下,新建log4j.properties文件,内容如下:
LOG_DIR=E:\\logs\\usermanage-api
log4j.rootLogger=debug,Console,FileInfo,FileError
log4j.logger.com.neusoft.usermanage=debug
log4j.logger.org.springframework=info
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
#FileInfo
log4j.appender.FileInfo = org.apache.log4j.DailyRollingFileAppender
log4j.appender.FileInfo.Threshold = INFO
log4j.appender.FileInfo.ImmediateFlush = true
log4j.appender.FileInfo.Append = true
log4j.appender.FileInfo.DatePattern = '_'yyyy-MM-dd'.log'
log4j.appender.FileInfo.encoding=UTF-8
log4j.appender.FileInfo.File = ${LOG_DIR}/info
log4j.appender.FileInfo.layout = org.apache.log4j.PatternLayout
log4j.appender.FileInfo.layout.ConversionPattern = [%-5p][%d{ISO8601}]%m%n
#FileError
log4j.appender.FileError = org.apache.log4j.DailyRollingFileAppender
log4j.appender.FileError.Threshold = ERROR
log4j.appender.FileError.ImmediateFlush = true
log4j.appender.FileError.Append = true
log4j.appender.FileError.DatePattern = '_'yyyy-MM-dd'.log'
log4j.appender.FileError.encoding=UTF-8
log4j.appender.FileError.File = ${LOG_DIR}/error
log4j.appender.FileError.layout = org.apache.log4j.PatternLayout
log4j.appender.FileError.layout.ConversionPattern = [%-5p][%d{ISO8601}]%m%n
二、项目开发
1.登录接口的实现
1.1、创建实体类
以后开发项目,也一定会有实体类,实体类一般写在一个叫 entity 的包下面。
在com.neusoft.usermanage.entity包中创建Userinfo(属性和数据库表中的字段对应),代码如下:
package com.neusoft.usermanage.entity;
import com.neusoft.usermanage.uitl.Page;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Userinfo extends Page {
private Integer id; // 用户主键
private String userName; //用户名, db: user_name -> 实体类中: userName
private String pwd; // 用户密码
private String type; // 用户类型: 0-普通用户,9-管理员
private String sex; // 用户性别
private String degree; // 文凭|用户学历
private String avatar; // 头像
private String hobby; // 用户兴趣爱好
private String content; // 用户描述|简介
private Date birthday; // 用户生日
}
1.2、DAO层
1.2.1、创建UserinfoDao接口
在com.neusoft.usermanage.dao包中创建UserinfoDao接口,添加通过用户名获取用户信息的方法getUserByName,代码如下:
package com.neusoft.usermanage.dao;
import com.neusoft.usermanage.entity.Userinfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface UserinfoDao {
/**
* 根据用户名查找用户信息
* @param userName
* @return
*/
Userinfo getUserByName(@Param("userName") String userName);
}
1.2.2、UserinfoMapper.xml编写sql
在src/main/resources/mybatis/mapper文件夹中创建UserinfoMapper.xml文件,代码如下:
<?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.neusoft.usermanage.dao.UserinfoDao">
<!— 写 SQL 语句处 -->
</mapper>
然后在UserinfoMapper.xml中添加getUserByName接口的sql语句,代码如下:
<!-- 根据用户名查询用户 -->
<select id="getUserByName"
parameterType="string"
resultType="com.neusoft.usermanage.entity.Userinfo">
select * from userinfo where user_name = #{userName}
</select>
1.3、Service层
1.3.1、创建UserinfoService
在com.neusoft.usermanage.service包中创建UserinfoService接口,添加根据用户名获取用户信息的方
法getUserByName,代码如下:
package com.neusoft.usermanage.service;
import com.neusoft.usermanage.entity.Userinfo;
public interface UserinfoService {
/**
* 根据用户名查找用户的信息
* @param userName
* @return
* @throws Exception
*/
Userinfo getUserByName(String userName) throws Exception;
}
1.3.2、创建UserinfoServiceImpl
在com.neusoft.usermanage.service.impl包中创建UserinfoServiceImpl类,实现UserinfoService接口中的方法getUserByName,代码如下:
package com.neusoft.usermanage.service.impl;
import com.neusoft.usermanage.dao.UserinfoDao;
import com.neusoft.usermanage.entity.Userinfo;
import com.neusoft.usermanage.service.UserinfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserinfoServiceImpl implements UserinfoService {
private Logger log = LoggerFactory.getLogger(this.getClass());
// Ctrl + I : 实现接口方法的快捷键
@Autowired
private UserinfoDao userinfoDao;
public Userinfo getUserByName(String userName) throws Exception{
try {
return userinfoDao.getUserByName(userName);
}catch (Exception e) {
log.error("UserServiceImpl-->>getUserByName", e);
throw new RuntimeException(e.getMessage());
}
}
}
1.4、Controller控制层
在com.neusoft.usermanage.util包中创建BaseResponse类,用于统一返回json的数据格式
package com.neusoft.usermanage.uitl;
import org.springframework.http.ResponseEntity;
public class BaseResponse<T> {
private int responseCode;
private String responseMsg;
private T data;
public BaseResponse(int responseCode, String responseMsg, T data) {
this.responseCode = responseCode;
this.responseMsg = responseMsg;
this.data = data;
}
public BaseResponse() {
super();
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return super.toString();
}
@Override
protected void finalize() throws Throwable {
super.finalize();
}
//请求成功(带成功信息和数据)
public static ResponseEntity generateOKResponseEntity(String responseMsg, Object object) {
// Map<String, Object> obj = new HashMap<String, Object>();
return ResponseEntity.ok().body(new BaseResponse<>(0, responseMsg,
object));
}
//请求成功(带数据)
public static ResponseEntity generateOKResponseEntity(Object object) {
return ResponseEntity.ok().body(new BaseResponse<>(0, "Success",
object));
}
public static ResponseEntity generateBadResponseEntity(int code, String
message, Object object) {
return ResponseEntity.ok().body(new BaseResponse<>(code, message,
object));
}
public int getResponseCode() {
return responseCode;
}
public void setResponseCode(int responseCode) {
this.responseCode = responseCode;
}
public String getResponseMsg() {
return responseMsg;
}
public void setResponseMsg(String responseMsg) {
this.responseMsg = responseMsg;
}
public T getData() {
return data;
}
}
1.4.2、创建UserinfoController
在com.neusoft.usermanage.controller包中创建UserinfoController类,设置类上的模块访问路径:“/user”,注入UserinfoService对象,定义log变量,代码如下:
package com.neusoft.usermanage.controller;
import com.neusoft.usermanage.entity.Userinfo;
import com.neusoft.usermanage.service.UserinfoService;
import com.neusoft.usermanage.util.BaseResponse;
import org.slf4j.Logger; //注意这里是f4j包下的Logger
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
@RestController
@RequestMapping("/user")
public class UserinfoController {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Autowired
private UserinfoService userinfoService;
}
1.4.3、编写/user/login接口
在UserinfoController类里增加login方法,完成用户登录的功能,代码如下:
@PostMapping("/login")
public ResponseEntity<BaseResponse> login(@RequestBody Userinfo user) throws Exception {
Userinfo userForBase = userinfoService.getUserByName(user.getUserName());
if (userForBase == null) {
return BaseResponse.generateBadResponseEntity(500, "登录失败,用户不存在", "");
} else {
if (!userForBase.getPwd().equals(user.getPwd())) {
return BaseResponse.generateBadResponseEntity(500, "密码错误", "");
} else {
//token 以后的代码修改为自动生成
String token = "adminToken";
HashMap obj = new HashMap();
//obj.put("token", tokenUtil.getToken(userForBase));
obj.put("token", token);
obj.put("user", userForBase);
return BaseResponse.generateOKResponseEntity(obj);
}
}
}
1.4.4、登录接口测试
新建测试类UserinfoControllerTest,新增testLogin方法,代码如下:
package com.neusoft.usermanage;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.neusoft.usermanage.controller.UserinfoController;
import com.neusoft.usermanage.entity.Userinfo;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.Date;
@WebAppConfiguration
public class UserinfoControllerTest extends MyAppBaseTest {
private MockMvc mockMvc;
@Autowired
private UserinfoController userinfoController;
@BeforeEach
void setUp() {
mockMvc= MockMvcBuilders.standaloneSetup(userinfoController).build();
}
@Test
void testLogin() throws Exception{
//1. 模拟登录数据
Userinfo userinfo=new Userinfo();
userinfo.setUserName("jabari");
userinfo.setPwd("123456");
//2. 转换为 json
String userJsonString = new ObjectMapper().writeValueAsString(userinfo);
//3. 使用 MockMvc 模拟 http 发送 post 的登录请求测试
MvcResult mvcResult=mockMvc.perform(
MockMvcRequestBuilders.post("/user/login")
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(userJsonString)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
}
}
测试类执行查看一下运行结果。
测试登录成功。
2.添加接口的实现
2.1、DAO层
2.1.1、创建新增用户的Dao层方法
在com.neusoft.usermanage.dao.UserinfoDao接口中编写接口方法:insertUser,代码如下:
/**
* 新增用户
* @param userinfo
* @return
*/
int insertUser(Userinfo userinfo);
2.1.2 、UserinfoMapper.xml 中编写sql
在src/main/resources/mybatis/mapper/UserinfoMapper.xml中,添加如下代码:
<!-- 新增用户 -->
<insert id="insertUser" parameterType="com.neusoft.usermanage.entity.Userinfo">
insert into userinfo(user_name,pwd,type,sex,degree,avatar,hobby,content,birthday)
values
(#{userName}, #{pwd},#{type},#{sex},#{degree},#{avatar},#{hobby},#{content},#{birthday})
</insert>
2.2、Service层
service 层实现用户添加的业务逻辑
2.2.1、创建接口方法
在com.neusoft.usermanage.service.UserinfoService中添加addUser方法,代码如下:
/**
* 新增用户
* @param userinfo
* @return
* @throws Exception
*/
int addUser(Userinfo userinfo) throws Exception;
在com.neusoft.usermanage.service.UserinfoService中添加isUserName接口的方法,判断用户名是否重复,代码如下:
/**
* 判断用户名是否存在
* @param userName
* @return
* @throws Exception
*/
boolean isUserName(String userName) throws Exception;
2.2.2、实现接口方法
在com.neusoft.usermanage.service . impl . UserinfoServiceImpl中实现addUser方法,代码如下:
@Override
public int addUser(Userinfo userinfo) throws Exception {
try {
return userinfoDao.insertUser(userinfo);
} catch (Exception e) {
log.error("UserinfoServiceImpl-->>addUser",e);
throw new RuntimeException(e.getMessage());
}
}
在com.neusoft.usermanage.service.impl . UserinfoServiceImpl中实现isUserName接口的方法,代码如下:
/**
* 校验用户名是否重复。
* @param userName
* @return true: 代表重复;false:代表不重复。
* @throws Exception
*/
@Override
public boolean isUserName(String userName) throws Exception {
try {
Userinfo userinfo = userinfoDao.getUserByName(userName);
if (userinfo != null) {
return true;
} else {
return false;
}
} catch (Exception e) {
log.error("UserinfoServiceImpl-->>isUserName",e);
throw new RuntimeException(e.getMessage());
}
}
2.3、Controller层
2.3.1、添加用户新增的Controller接口
在com.neusoft.usermanage.controller.UserinfoController中添加方法addUser,代码如下:
@PostMapping("/register")
public ResponseEntity<BaseResponse> addUser(HttpServletRequest request,
@RequestBody Userinfo userInfo) {
try {
//判断用户名是否重复
if (userinfoService.isUserName(userInfo.getUserName())) {
return BaseResponse. generateBadResponseEntity (500, "用户名不能重复", "");
}
//调用service层方法
int flag = userinfoService.addUser(userInfo);
if (flag == 1) {
return BaseResponse. generateOKResponseEntity ("用户新增成功", "");
} else {
return BaseResponse. generateBadResponseEntity (500, "用户新增失败", "");
}
} catch (Exception e) {
log.error("UserinfoController-->>addUser", e);
return BaseResponse. generateBadResponseEntity (500, "服务器内部错误", "");
}
}
2.3.2、添加用户的Controller接口测试
在UserinfoControllerTest类中,新增testAddUser方法,代码如下:
@Test
void testAddUser() throws Exception{
// 1.模拟创建Userinfo对象
Userinfo userinfo=new Userinfo();
userinfo.setUserName("jabari");
userinfo.setPwd("123456");
userinfo.setAvatar("http://www.baidu.com");
userinfo.setBirthday(new Date());
userinfo.setContent("我的名字叫:Jabari,来自江苏!");
userinfo.setDegree("1");
userinfo.setHobby("游泳");
userinfo.setSex("1");
userinfo.setType("1");
// 2.将Userinfo对象转换为Json字符串
String userinfoJsonString = new ObjectMapper().writeValueAsString(userinfo);
// 3.使用MockMvc模拟http请求来测试用户新增的请求
MvcResult mvcResult=mockMvc.perform(
MockMvcRequestBuilders. post ("/user/register")
.accept(MediaType. APPLICATION_JSON_UTF8 )
.contentType(MediaType. APPLICATION_JSON_UTF8 )
.content(userinfoJsonString)
).andExpect(MockMvcResultMatchers. status ().isOk())
.andDo(MockMvcResultHandlers. print ()).andReturn();
}
执行添加测试的方法。
去数据库看一眼,可以看到数据成功地被添加上去了:
3、删除接口的实现
3.1、DAO层
3.1.1、创建接口方法
在com.neusoft.usermanage.dao.UserinfoDao中添加删除用户的接口方法delUser,代码如下:
/**
* 删除用户
* @param id
* @return
第 15 页 共 32 页
* @throws Exception
*/
public int delUser(@Param("id") int id);
3.1.2、UserinfoMapper.xml中编写sql
在src/main/resources/mybatis/mapper/UserinfoMapper.xml中,添加如下代码:
<!-- 根据用户Id删除用户 -->
<delete id="delUser">
delete from userinfo where id = #{id} and id != 1
</delete>
3.2、Sevice层
在service层实现删除用户的业务逻辑
3.2.1、添加接口方法
在com.neusoft.usermanage.service.UserinfoService中添加删除用户的接口方法delUser,代码如下:
/**
* 删除用户
* @param id
* @return
* @throws Exception
*/
int delUser(int id) throws Exception;
3.2.2、实现接口的方法
在com.neusoft.usermanage.service . impl . UserinfoServiceImpl实现delUser方法,代码如下:
/**
* 删除用户
* @param id
* @return
* @throws Exception
*/
public int delUser(int id) throws Exception{
try{
return userinfoDao.delUser(id);
}catch(Exception e){
log.error("UserinfoServiceImpl-->>delUser",e);
throw new RuntimeException(e.getMessage());
}
3.3、Controller层
3.3.1、删除用户接口
在com.neusoft.usermanage.controller.UserinfoController中添加方法delUser实现删除,代码如下:
@DeleteMapping("/del")
public ResponseEntity<BaseResponse> delUser(HttpServletRequest request,
@RequestBody Userinfo userinfo) {
try {
//判断用户名是admin
if (userinfo!=null && 1 == userinfo.getId()) {
return BaseResponse. generateBadResponseEntity (500, "admin用户不能删除", "");
}
int flag = userinfoService.delUser(userinfo.getId());
if (flag == 1) {
return BaseResponse. generateOKResponseEntity ("用户删除成功", "");
} else {
return BaseResponse. generateBadResponseEntity (500, "用户删除失败", "");
}
} catch (Exception e) {
log.error("UserinfoController-->>delUser", e);
return BaseResponse. generateBadResponseEntity (500, "服务器内部错误", "");
}
}
3.3.2、删除用户接口测试
@Test
void testDelUser() throws Exception {
Userinfo userinfo = new Userinfo();
userinfo.setId(1);
String userJsonString = new ObjectMapper().writeValueAsString(userinfo);
MvcResult mvcResult = mockMvc.perform(
MockMvcRequestBuilders.delete("/user/del")
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON)
.content(userJsonString)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
}
运行删除的测试代码
此时因为数据表里面只有一条数据所以删除不了,如果新增一条数据,运行增加数据的测试类,再执行删除数据的测试类的话。
那么刷新一下数据库发现数据表又恢复了一条,成功地删除了id为2的数据信息。
4、获取单个用户接口的实现
4.1、DAO层
4.1.1、创建接口方法
在com.neusoft.usermanage.dao.UserinfoDao中添加查找单个用户的接口方法getUserById(根据用户Id查找),代码如下:
/**
*通过用户id获取用户信息
*@param id
*@return
*/
Userinfo getUserById(@Param("id") int id);
4.1.2、UserinfoMapper.xml中编写sql
在src/main/resources/mybatis/mapper/UserinfoMapper.xml中添加:根据用户id检索单个用户信息,代码如下:
<!-- 根据用户id查找用户 -->
<select id="getUserById" resultType="com.neusoft.usermanage.entity.Userinfo">
select * from userinfo where id = #{id}
</select>
4.2、Service层
4.2.1、添加接口方法
在com.neusoft.usermanage.service.UserinfoService中添加查找单个用户的业务接口法getUserById,代码如下:
/**
*根据用户Id获取用户信息
*@param id
*@return
*@throws Exception
*/
Userinfo getUserById(int id) throws Exception;
4.2.2、实现接口方法
在com.neusoft.usermanage.service.impl.UserinfoServiceImpl类中实现接口的方法getUserById,代码如下:
/**
* 根据用户id获取用户的信息
* @param id
* @return
* @throws Exception
*/
public Userinfo getUserById(int id) throws Exception {
try {
Userinfo userinfo = userinfoDao.getUserById(id);
return userinfo;
} catch (Exception e) {
log.error("UserinfoServiceImpl-->>getUserById", e);
throw new RuntimeException(e.getMessage());
}
}
4.3、Controller层
4.3.1、获得单个用户接口
在com.neusoft.usermanage.controller.UserinfoController中添加方法实现单个用户接口getUserInfo,代码如下:
@GetMapping(value = "/{id}")
public ResponseEntity<BaseResponse<Userinfo>> getUserInfo(@PathVariable("id") int id) {
try {
Userinfo user = userinfoService.getUserById(id);
return BaseResponse.generateOKResponseEntity(user);
} catch (Exception e) {
log.error("UserinfoController-->>getUserInfo", e);
return BaseResponse.generateBadResponseEntity(500, "服务器内部错误", "");
}
}
4.3.2、测试获取单个用户接口
在UserinfoControllerTest类中,增加testGetUserInfo方法,代码如下:
@Test
void testGetUserInfo() throws Exception{
MvcResult mvcResult=mockMvc.perform(
MockMvcRequestBuilders.get("/user/1")
.accept(MediaType.APPLICATION_JSON_UTF8)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
}
测试结果:
5、更新用户接口的实现
5.1、DAO层
5.1.1、创建接口方法
在com.neusoft.usermanage.dao.UserinfoDao中添加更新单个用户的接口方法updateUser,代码如下:
/**
*更新用户信息
*@param userinfo
*@return
*/
int updateUser(Userinfo userinfo);
5.1.2 、 UserinfoMapper.xml中编写
在resources/mybatis/mapper/UserinfoMapper.xml中添加:根据用户id更新用户信息,代码如下:
<!-- 更新用户 -->
<update id="updateUser" parameterType="com.neusoft.usermanage.entity.Userinfo">
update userinfo
<set>
<if test="pwd != null and pwd != ''">
pwd=#{pwd},
</if>
<if test="degree != null and degree != ''">
degree=#{degree},
</if>
<if test="type != null and type != ''">
`type`=#{type},
</if>
<if test="sex != null and sex != ''">
sex=#{sex},
</if>
<if test="avatar != null and avatar != ''">
avatar=#{avatar},
</if>
<if test="hobby != null and hobby != ''">
hobby=#{hobby},
</if>
<if test="content != null and content != ''">
content=#{content},
</if>
<if test="birthday != null">
birthday=#{birthday},
</if>
</set>
where id = #{id}
and id != 1
</update>
5.2、Service层
5.2.1、添加接口方法
在com.neusoft.usermanage.service.UserinfoService中添加更新单个用户的业务接口法updateUser,代码如下:
/**
* 更新用户
* @param userinfo
* @return
* @throws Exception
*/
int updateUser(Userinfo userinfo) throws Exception;
5.2.2、实现接口方法
在com.neusoft.usermanage.service.impl.UserinfoServiceImpl类中实现接口的方法updateUser,代码如下:
/**
* 更新用户
* @param userinfo
* @return
* @throws Exception
*/
public int updateUser(Userinfo userinfo)throws Exception{
int flag = 0;
try{
userinfoDao.updateUser(userinfo);
flag=1;
}catch(Exception e){
log.error("UserinfoServiceImpl-->>updateUser",e);
throw new RuntimeException(e.getMessage());
}
return flag;
}
5.3 、Controller层
5.3.1、更新单个用户接口
在com.neusoft.usermanage.controller.UserinfoController中添加方法实现单个用户接口updateUser,代码如下:
@PutMapping("/update")
public ResponseEntity<BaseResponse> updateUser(
@RequestBody Userinfo userinfo) {
try {
int flag = userinfoService.updateUser(userinfo);
if (flag == 1) {
return BaseResponse.generateOKResponseEntity("修改成功", "");
} else {
return BaseResponse.generateBadResponseEntity(500, "服务器内部错误", "");
}
} catch (Exception e) {
log.error("UserinfoController-->>updateUser", e);
return BaseResponse.generateBadResponseEntity(500, "服务器内部错误", "");
}
}
5.3.2、测试更新单个用户接口
@Test
void testUpdateUser() throws Exception {
Userinfo userinfo = new Userinfo();
userinfo.setId(3);
userinfo.setUserName("test02");
userinfo.setPwd("22222");
userinfo.setAvatar("http://www.jd.com");
userinfo.setBirthday(new Date());
userinfo.setContent("this 22222is content");
userinfo.setDegree("3");
userinfo.setHobby("打游戏");
userinfo.setSex("1");
userinfo.setType("1");
String userJsonString = new ObjectMapper().writeValueAsString(userinfo);
MvcResult mvcResult = mockMvc.perform(
MockMvcRequestBuilders.put("/user/update")
.accept(MediaType.APPLICATION_JSON_UTF8)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(userJsonString)
)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
}
测试一下,执行一下更新一下单个用户接口的测试方法
发现id为4的一行信息被修改了。
总结
增删改查的套路无非是先Dao层编写接口功能,前提是在entity的实体类完成lombock的注入,然后实现mapper.xml的sql语句,service业务服务层,测试类的实现,最后是控制层的接口访问。
只要搞清楚了这个套路,明白了思路,在写代码的路上才会走的轻松。此次项目学到了跟着老师敲自己不思考代码的过程是没有用的,我们要做代码的执行人,不能做代码的搬运工。
人生缺乏的不是才干而是志向,不是成功地能力而是勤劳的意志。——郭尔王