技术选型
JDK:17
Mysql:8.0.4
Maven:3.9.10
SpringBoot:3.3.13
Mybatis-Plus:3.5.7
Spring-Data-Redis:3.3.13
Spring-Cache:3.3.13
Spring-Cloud:2023.0.1
Nacos:3.0.2
安装Nacos

编辑
启动服务器:
编辑
创建微服务项目
编辑
编辑
创建emp-service模块
编辑
编辑
创建dept-service模块
编辑
编辑
创建common-pojo模块(存放实体类)
编辑
创建common-utils模块(存放工具类)
编辑
编辑
修改父工程pom文件
引入父依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>emp-service</module>
<module>dept-service</module>
<module>common-pojo</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.13</version>
<relativePath/>
</parent>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
编辑
引入共同依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>emp-service</module>
<module>dept-service</module>
<module>common-pojo</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.13</version>
<relativePath/>
</parent>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot-starter-web.version>3.3.13</spring-boot-starter-web.version>
</properties>
<!-- 引入共有的依赖 -->
<dependencies>
<!--springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-starter-web.version}</version>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
</dependencies>
</project>
编辑
管理版本依赖(并不会直接引入依赖)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>emp-service</module>
<module>dept-service</module>
<module>common-pojo</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.13</version>
<relativePath/>
</parent>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot-starter-web.version>3.3.13</spring-boot-starter-web.version>
<mysql.version>8.0.33</mysql.version>
<lombok.version>1.18.22</lombok.version>
</properties>
<!-- 引入共有的依赖 -->
<dependencies>
<!--springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-starter-web.version}</version>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
</dependencies>
<!-- 管理依赖版本 -->
<dependencyManagement>
<dependencies>
<!--mysql-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
编辑
操作common-pojo模块
修改pom文件引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>common-pojo</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
编辑
创建包引入实体类
编辑
package com.he.pojo.Dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DeptSimpleDto implements Serializable {
// 版本控制
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private LocalDateTime createTime;
}
package com.he.pojo.Dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EmpSimpleDto implements Serializable {
// 版本控制
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private Short gender;
private LocalDate entryDate;
private Integer deptId;
}
package com.he.pojo.Dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EmpSearchDto {
private String name;
private Short gender;
private LocalDate begin;
private LocalDate end;
private Integer page;
private Integer pageSize;
}
package com.he.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.he.pojo.Dto.EmpSimpleDto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dept implements Serializable {
// 版本控制
@TableField(exist = false)
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String name;
private LocalDateTime createTime;
private LocalDateTime updateTime;
@TableField(exist = false)
private List<EmpSimpleDto> empsSimple;
}
编辑
package com.he.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.he.pojo.Dto.DeptSimpleDto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("emp")
public class Emp implements Serializable {
// 版本控制
@TableField(exist = false)
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String username;
private String password;
private String name;
private Short gender;
private String phone;
private Short job;
private Integer salary;
private String image;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate entryDate;
private Integer deptId;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
@TableField(exist = false)
private DeptSimpleDto deptSimple;
}
package com.he.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean implements Serializable {
// 版本控制
private static final long serialVersionUID = 1L;
private Long total; // 总记录数
private List rows; // 当前页数据列表
}
package com.he.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result{
// 成员变量
private Integer code; // 响应码:1:成功,0:失败
private String msg; // success:成功,error:失败
private Object data; // 要封装的对象
// 成功:根据不同的情况返回相对应的结果 无数据返回
public static Result success(){
// 创建Result对象
Result result = new Result();
// 封装数据
result.code = 1;
result.msg = "success";
// 返回结果
return result;
}
// 成功:根据不同的情况返回相对应的结果 有数据返回
public static Result success(Object data){
// 创建Result对象
Result result = new Result();
// 封装数据
result.code = 1;
result.msg = "success";
result.data = data;
// 返回结果
return result;
}
// 失败:根据不同情况返回相对应的结果
public static Result error(){
// 创建Result对象
Result result = new Result();
// 封装数据
result.code = 0;
result.msg = "error";
return result;
}
// 失败:根据不同情况返回相对应的结果
public static Result error(String msg){
// 创建Result对象
Result result = new Result();
// 封装数据
result.code = 0;
result.msg = msg;
return result;
}
}
操作common-utils模块
创建包,创建MybatisPlusConfig配置类
@Configuration
public class MybatisPlusConfig {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
编辑
操作dept-service模块
修改pom文件引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>dept-service</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--mysql-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!--common-pojo-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--common-utils-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
编辑
创建包,创建DeptMapper接口
package com.he.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.he.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface DeptMapper extends BaseMapper<Dept> {
}
编辑
创建包,创建DeptService接口
package com.he.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.he.pojo.Dept;
import java.util.List;
public interface DeptService extends IService<Dept> {
// 根据部门ID查询部门信息
Dept queryById(Integer id);
}
编辑
创建包,创建DeptServiceImpl类
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {
@Autowired
DeptMapper deptMapper;
// 根据部门Id获取部门信息
@Override
public Dept queryById(Integer id) {
Dept dept = deptMapper.selectById(id);
return dept;
}
}
编辑
创建包,创建DeptController类
@Slf4j
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
DeptService deptService;
// 根据部门ID获取部门信息
@GetMapping("/{id}")
public Result queryById(@PathVariable Integer id) {
log.info("根据部门ID:{}查询部门信息", id);
Dept dept = deptService.queryById(id);
return dept != null ? Result.success(dept): Result.error();
}
}
编辑
创建application.yml配置文件
server:
port: 8091
spring:
application:
name: deptservice
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/deptdatabase
username: root
password: 123456
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true # 开启驼峰命名
logging:
level:
com.he: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
编辑
创建DeptApplication启动类
package com.he;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DeptApplication {
public static void main(String[] args) {
SpringApplication.run(DeptApplication.class, args);
}
}
编辑
操作emp-service模块
修改pom文件引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.he</groupId>
<artifactId>kawa-cloud-demo</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>emp-service</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--mysql-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!--common-pojo-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--common-utils-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
编辑
创建包,创建EmpMapper接口
package com.he.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.he.pojo.Emp;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface EmpMapper extends BaseMapper<Emp> {
}
编辑
创建包,创建EmpService接口
public interface EmpService extends IService<Emp> {
// 根据信息分页查询
PageBean queryByInfo(EmpSearchDto empSearchDto);
}
编辑
创建包,创建EmpServiceImpl类
@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {
@Autowired
EmpMapper empMapper;
// 根据信息分页查询
public PageBean queryByInfo(EmpSearchDto empSearchDto) {
// 创建查询条件
LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper();
queryWrapper.like(StringUtils.hasLength(empSearchDto.getName()),Emp::getName, empSearchDto.getName())
.eq(empSearchDto.getGender()!=null,Emp::getGender, empSearchDto.getGender())
.ge(empSearchDto.getBegin()!=null,Emp::getEntryDate, empSearchDto.getBegin())
.le(empSearchDto.getEnd()!=null,Emp::getEntryDate, empSearchDto.getEnd());
// 创建分页条件
if (empSearchDto.getPage() == null) {
empSearchDto.setPage(1);
}
if (empSearchDto.getPageSize() == null) {
empSearchDto.setPageSize(5);
}
Page<Emp> pageInfo = new Page<>(empSearchDto.getPage(), empSearchDto.getPageSize());
// 执行查询
Page<Emp> empPage = empMapper.selectPage(pageInfo, queryWrapper);
// 封装数据
PageBean pageBean = new PageBean(empPage.getTotal(), empPage.getRecords());
// 返回数据
return pageBean;
}
}
编辑
创建包,创建EmpController类
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
EmpService empService;
@GetMapping
public Result queryByInfo(@ModelAttribute EmpSearchDto empSearchDto){
log.info("查询员工信息,参数:empDto={}", empSearchDto);
PageBean pageBean = empService.queryByInfo(empSearchDto);
return pageBean!=null?Result.success(pageBean):Result.error("查询失败!");
}
}
编辑
创建application.yml配置文件
server:
port: 8081
spring:
application:
name: empservice
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/empdatabase
username: root
password: 123456
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true # 开启驼峰命名
logging:
level:
com.he: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
编辑
创建EmpApplication启动类
@SpringBootApplication
public class EmpApplication {
public static void main(String[] args) {
SpringApplication.run(EmpApplication.class, args);
}
}
编辑
修改父工程pom文件
管理版本依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>emp-service</module>
<module>dept-service</module>
<module>common-pojo</module>
<module>fegin-api</module>
<module>common-utils</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.13</version>
<relativePath/>
</parent>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot-starter-web.version>3.3.13</spring-boot-starter-web.version>
<mybatis-plus.version>3.5.7</mybatis-plus.version>
<mysql.version>8.0.33</mysql.version>
<lombok.version>1.18.22</lombok.version>
<spring-cloud.version>2023.0.1</spring-cloud.version>
<spring-cloud-alibaba-version>2023.0.1.0</spring-cloud-alibaba-version>
</properties>
<!-- 引入共有的依赖 -->
<dependencies>
<!--springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-starter-web.version}</version>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
</dependencies>
<!-- 管理依赖版本 -->
<dependencyManagement>
<dependencies>
<!--mysql-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
编辑
遇到问题:只引入SpringCloudAlibaba不引入SpringCloud就无法引入Feign依赖
原因:Spring Cloud Alibaba是对Spring Cloud生态的扩展,并非独立替代品;它需与Spring Cloud基础组件协同工作,Feign的注解解析、HTTP请求模板化等核心能力需通过spring-cloud-starter-openfeign提供,如果仅引入Spring Cloud Alibaba而不添加Spring Cloud相关依赖,会导致Feign无法被正确加载或调用。
创建feign-api模块
编辑
编辑
修改pom文件引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>fegin-api</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 负载均衡器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!--httpClient的依赖 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
<!--common-pojo-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 模块内部使用,不会传递给其他依赖 -->
<scope>provided</scope>
</dependency>
</dependencies>
</project>
遇到问题:只引入spring-cloud-starter-openfeign,不引入spring-cloud-starter-loadbalancer,测试时控制台报错
原因:在Spring Cloud项目中仅引入spring-cloud-starter-openfeign而未添加spring-cloud-starter-loadbalancer时,控制台会报错No Feign Client for loadBalancing defined,这是因为自Spring Cloud Hoxton.M2版本后,Feign默认移除了Ribbon依赖,转而使用spring-cloud-loadbalancer实现客户端负载均衡。
创建包,创建DeptClient接口
package com.he.client;
import com.he.pojo.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient("deptservice")
public interface DeptClient {
@GetMapping("/depts/{id}")
Result queryDeptSimpleById(@PathVariable Integer id);
}
编辑
操作dept-service模块
修改pom文件引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>dept-service</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--mysql-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!--common-pojo-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--common-utils-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--feign-api-->
<dependency>
<groupId>com.he</groupId>
<artifactId>feign-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
编辑
修改application.yml配置文件
server:
port: 8091
spring:
application:
name: deptservice
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/deptdatabase
username: root
password: 123456
cloud:
nacos:
server-addr: localhost:8848
# Nacos 服务器启用了认证
username: nacos # 默认用户名
password: nacos # 默认密码
discovery:
cluster-name: SZ # 集群名称
ephemeral: true # 配置是否注册为临时服务,默认是true即临时服务
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true # 开启驼峰命名
logging:
level:
com.he: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
编辑
操作emp-service模块
修改pom文件引入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>emp-service</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--mysql-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!--common-pojo-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--common-utils-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--nacos客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--feign-api-->
<dependency>
<groupId>com.he</groupId>
<artifactId>feign-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
编辑
修改application.yml配置文件
server:
port: 8081
spring:
application:
name: empservice
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/empdatabase
username: root
password: 123456
cloud:
nacos:
server-addr: localhost:8848
# Nacos 服务器启用了认证
username: nacos # 默认用户名
password: nacos # 默认密码
discovery:
cluster-name: SZ # 集群名称
ephemeral: true # 配置是否注册为临时服务,默认是true即临时服务
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true # 开启驼峰命名
logging:
level:
com.he: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
feign:
client:
config:
default: # default全局的配置
loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
httpclient:
enabled: true # 开启feign对HttpClient的支持
max-connections: 200 # 最大的连接数
max-connections-per-route: 50 # 每个路径的最大连接数
deptservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
ribbon:
eager-load:
enabled: true # 开启饥饿加载,默认是false即懒加载
clients: deptservice
编辑
修改EmpApplication启动类
@SpringBootApplication
@EnableFeignClients(clients = {DeptClient.class})
public class EmpApplication {
public static void main(String[] args) {
SpringApplication.run(EmpApplication.class, args);
}
}
编辑
修改EmpServiceImpl类
@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {
@Autowired
ObjectMapper objectMapper;
@Autowired
EmpMapper empMapper;
@Autowired
private DeptClient deptClient;
// 根据信息分页查询
@Cacheable(cacheNames = "empsList",key = "#empSearchDto.hashCode()" )
public PageBean queryByInfo(EmpSearchDto empSearchDto) {
// 创建查询条件
LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper();
queryWrapper.like(StringUtils.hasLength(empSearchDto.getName()),Emp::getName, empSearchDto.getName())
.eq(empSearchDto.getGender()!=null,Emp::getGender, empSearchDto.getGender())
.ge(empSearchDto.getBegin()!=null,Emp::getEntryDate, empSearchDto.getBegin())
.le(empSearchDto.getEnd()!=null,Emp::getEntryDate, empSearchDto.getEnd());
// 创建分页条件
if (empSearchDto.getPage() == null) {
empSearchDto.setPage(1);
}
if (empSearchDto.getPageSize() == null) {
empSearchDto.setPageSize(5);
}
Page<Emp> pageInfo = new Page<>(empSearchDto.getPage(), empSearchDto.getPageSize());
// 执行查询
Page<Emp> empPage = empMapper.selectPage(pageInfo, queryWrapper);
// 为每个员工获取对应的部门信息
List<Emp> empList = empPage.getRecords().stream().map(emp -> {
// 调用Feign客户端获取部门信息
Result deptResult = deptClient.queryDeptSimpleById(emp.getDeptId());
if (deptResult.getCode() == 1) {
// 假设员工实体中有部门名称字段 手动转换为部门实体
Object data = deptResult.getData();
DeptSimpleDto dept = objectMapper.convertValue(data, DeptSimpleDto.class);
emp.setDeptSimple(dept);
}
return emp;
}).collect(Collectors.toList());
// 封装数据
PageBean pageBean = new PageBean(empPage.getTotal(), empList);
// 返回数据
return pageBean;
}
}
编辑
启动测试
启动nacos
编辑
startup.cmd -m standalone
编辑
编辑
访问nacos
编辑
编辑
启动dept-service
编辑
启动emp-service
编辑
访问nacos
编辑
测试分页查询员工
编辑
编辑
编辑
操作emp-service模块
修改EmpService接口
public interface EmpService extends IService<Emp> {
// 根据信息分页查询
PageBean queryByInfo(EmpSearchDto empSearchDto);
// 根据部门ID获取所有符合的员工信息
List<Emp> queryByDeptId(Integer deptId);
}
编辑
修改EmpServiceImpl类
@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {
@Autowired
ObjectMapper objectMapper;
@Autowired
EmpMapper empMapper;
@Autowired
private DeptClient deptClient;
// 根据信息分页查询
@Cacheable(cacheNames = "empsList",key = "#empSearchDto.hashCode()" )
public PageBean queryByInfo(EmpSearchDto empSearchDto) {
// 创建查询条件
LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper();
queryWrapper.like(StringUtils.hasLength(empSearchDto.getName()),Emp::getName, empSearchDto.getName())
.eq(empSearchDto.getGender()!=null,Emp::getGender, empSearchDto.getGender())
.ge(empSearchDto.getBegin()!=null,Emp::getEntryDate, empSearchDto.getBegin())
.le(empSearchDto.getEnd()!=null,Emp::getEntryDate, empSearchDto.getEnd());
// 创建分页条件
if (empSearchDto.getPage() == null) {
empSearchDto.setPage(1);
}
if (empSearchDto.getPageSize() == null) {
empSearchDto.setPageSize(5);
}
Page<Emp> pageInfo = new Page<>(empSearchDto.getPage(), empSearchDto.getPageSize());
// 执行查询
Page<Emp> empPage = empMapper.selectPage(pageInfo, queryWrapper);
// 为每个员工获取对应的部门信息
List<Emp> empList = empPage.getRecords().stream().map(emp -> {
// 调用Feign客户端获取部门信息
Result deptResult = deptClient.queryDeptSimpleById(emp.getDeptId());
if (deptResult.getCode() == 1) {
// 假设员工实体中有部门名称字段 手动转换为部门实体
Object data = deptResult.getData();
DeptSimpleDto dept = objectMapper.convertValue(data, DeptSimpleDto.class);
emp.setDeptSimple(dept);
}
return emp;
}).collect(Collectors.toList());
// 封装数据
PageBean pageBean = new PageBean(empPage.getTotal(), empList);
// 返回数据
return pageBean;
}
// 根据部门ID获取所有符合的员工信息
@Override
public List<Emp> queryByDeptId(Integer deptId) {
// 创建查询条件
LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper();
queryWrapper.eq(Emp::getDeptId, deptId);
// 执行查询
List<Emp> empList = empMapper.selectList(queryWrapper);
// 返回数据
return empList;
}
}
编辑
修改EmpController类
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
EmpService empService;
@GetMapping
public Result queryByInfo(@ModelAttribute EmpSearchDto empSearchDto){
log.info("查询员工信息,参数:empDto={}", empSearchDto);
PageBean pageBean = empService.queryByInfo(empSearchDto);
return pageBean!=null?Result.success(pageBean):Result.error("查询失败!");
}
@GetMapping("/dept/{id}")
public Result queryByDeptId(@PathVariable Integer id){
log.info("根据部门ID:{}查询员工信息",id);
List<Emp> empList = empService.queryByDeptId(id);
return empList!=null?Result.success(empList):Result.error("查询失败!");
}
}
编辑
操作feign-api模块
创建EmpClient接口
@FeignClient("empservice")
public interface EmpClient {
@GetMapping("/emps/dept/{id}")
Result querySimpleByDeptId(@PathVariable Integer id);
}
编辑
操作dept-service模块
修改application.yml配置文件
server:
port: 8091
spring:
application:
name: deptservice
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/deptdatabase
username: root
password: 123456
cloud:
nacos:
server-addr: localhost:8848
# Nacos 服务器启用了认证
username: nacos # 默认用户名
password: nacos # 默认密码
discovery:
cluster-name: SZ # 集群名称
ephemeral: true # 配置是否注册为临时服务,默认是true即临时服务
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true # 开启驼峰命名
logging:
level:
com.he: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
feign:
client:
config:
default: # default全局的配置
loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
httpclient:
enabled: true # 开启feign对HttpClient的支持
max-connections: 200 # 最大的连接数
max-connections-per-route: 50 # 每个路径的最大连接数
empservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
ribbon:
eager-load:
enabled: true # 开启饥饿加载,默认是false即懒加载
clients: empservice
编辑
修改DeptApplication启动类
@SpringBootApplication
@EnableFeignClients(clients = {EmpClient.class})
public class DeptApplication {
public static void main(String[] args) {
SpringApplication.run(DeptApplication.class, args);
}
}
编辑
修改DeptServiceImpl类
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {
@Autowired
ObjectMapper objectMapper;
@Autowired
DeptMapper deptMapper;
@Autowired
EmpClient empClient;
// 根据部门Id获取部门信息
@Override
public Dept queryById(Integer id) {
Dept dept = deptMapper.selectById(id);
Result result = empClient.querySimpleByDeptId(id);
if (result.getCode()==1){
Object data = result.getData();
List<EmpSimpleDto> list = objectMapper.convertValue(data, new TypeReference<List<EmpSimpleDto>>() {});
dept.setEmpsSimple(list); // 设置简单员工列表
}
return dept;
}
}
启动测试
启动dept-service
编辑
启动emp-service
编辑
测试根据ID查询部门信息
编辑
完善emp-service模块增删改查功能
修改EmpService接口
public interface EmpService extends IService<Emp> {
// 根据信息分页查询
PageBean queryByInfo(EmpSearchDto empSearchDto);
// 根据部门ID获取所有符合的员工信息
List<Emp> queryByDeptId(Integer deptId);
// 根据员工ID获取员工信息
Emp queryById(Integer id);
// 添加员工信息
Integer addEmp(Emp emp);
// 修改员工信息
Integer updateEmp(Emp emp);
// 删除员工信息
Integer deleteEmp(Integer id);
}
编辑
修改EmpServiceImpl类
@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {
@Autowired
ObjectMapper objectMapper;
@Autowired
EmpMapper empMapper;
@Autowired
private DeptClient deptClient;
// 根据信息分页查询
public PageBean queryByInfo(EmpSearchDto empSearchDto) {
// 创建查询条件
LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper();
queryWrapper.like(StringUtils.hasLength(empSearchDto.getName()),Emp::getName, empSearchDto.getName())
.eq(empSearchDto.getGender()!=null,Emp::getGender, empSearchDto.getGender())
.ge(empSearchDto.getBegin()!=null,Emp::getEntryDate, empSearchDto.getBegin())
.le(empSearchDto.getEnd()!=null,Emp::getEntryDate, empSearchDto.getEnd());
// 创建分页条件
if (empSearchDto.getPage() == null) {
empSearchDto.setPage(1);
}
if (empSearchDto.getPageSize() == null) {
empSearchDto.setPageSize(5);
}
Page<Emp> pageInfo = new Page<>(empSearchDto.getPage(), empSearchDto.getPageSize());
// 执行查询
Page<Emp> empPage = empMapper.selectPage(pageInfo, queryWrapper);
// 为每个员工获取对应的部门信息
List<Emp> empList = empPage.getRecords().stream().map(emp -> {
// 调用Feign客户端获取部门信息
Result deptResult = deptClient.queryDeptSimpleById(emp.getDeptId());
if (deptResult.getCode() == 1) {
// 假设员工实体中有部门名称字段 手动转换为部门实体
Object data = deptResult.getData();
DeptSimpleDto dept = objectMapper.convertValue(data, DeptSimpleDto.class);
emp.setDeptSimple(dept);
}
return emp;
}).collect(Collectors.toList());
// 封装数据
PageBean pageBean = new PageBean(empPage.getTotal(), empList);
// 返回数据
return pageBean;
}
// 根据部门ID获取所有符合的员工信息
@Override
public List<Emp> queryByDeptId(Integer deptId) {
// 创建查询条件
LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper();
queryWrapper.eq(Emp::getDeptId, deptId);
// 执行查询
List<Emp> empList = empMapper.selectList(queryWrapper);
// 返回数据
return empList;
}
// 根据员工ID获取员工信息
@Override
public Emp queryById(Integer id) {
Emp emp = empMapper.selectById(id);
return emp;
}
// 添加员工
@Override
public Integer addEmp(Emp emp) {
if (emp.getName() == null || emp.getUsername() == null|| emp.getGender() == null){
return 0;
}
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
emp.setEntryDate(LocalDate.now());
emp.setPassword("123456");
int i = empMapper.insert(emp);
return i;
}
// 修改员工
@Override
public Integer updateEmp(Emp emp) {
if (emp.getId() == null){
return 0;
}
emp.setUpdateTime(LocalDateTime.now());
int i = empMapper.updateById(emp);
return i;
}
// 删除员工
@Override
public Integer deleteEmp(Integer id) {
int i = empMapper.deleteById(id);
return i;
}
}
编辑
修改EmpController类
@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {
@Autowired
EmpService empService;
@GetMapping
public Result queryByInfo(@ModelAttribute EmpSearchDto empSearchDto){
log.info("查询员工信息,参数:empDto={}", empSearchDto);
PageBean pageBean = empService.queryByInfo(empSearchDto);
return pageBean!=null?Result.success(pageBean):Result.error("查询失败!");
}
@GetMapping("/dept/{id}")
public Result queryByDeptId(@PathVariable Integer id){
log.info("根据部门ID:{}查询员工信息",id);
List<Emp> empList = empService.queryByDeptId(id);
return empList!=null?Result.success(empList):Result.error("查询失败!");
}
@GetMapping("/{id}")
public Result queryById(@PathVariable Integer id){
log.info("根据员工ID:{}查询员工信息",id);
Emp emp = empService.queryById(id);
return emp!=null?Result.success(emp):Result.error("查询失败!");
}
@PostMapping
public Result addEmp(@RequestBody Emp emp){
log.info("添加员工,参数:emp={}", emp);
Integer addEmp = empService.addEmp(emp);
return addEmp>0?Result.success("添加成功!"):Result.error("添加失败!");
}
@PutMapping
public Result updateEmp(@RequestBody Emp emp){
log.info("修改员工,参数:emp={}", emp);
Integer updateEmp = empService.updateEmp(emp);
return updateEmp>0?Result.success("修改成功!"):Result.error("修改失败!");
}
@DeleteMapping("/{id}")
public Result deleteEmp(@PathVariable Integer id){
log.info("删除员工,参数:id={}", id);
Integer deleteEmp = empService.deleteEmp(id);
return deleteEmp>0?Result.success("删除成功!"):Result.error("删除失败!");
}
}
编辑
完善dept-service模块增删改查功能
修改DeptServicze接口
package com.he.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.he.pojo.Dept;
import java.util.List;
public interface DeptService extends IService<Dept> {
// 查询所有部门信息
List<Dept> queryAll();
// 根据部门ID查询部门信息
Dept queryById(Integer id);
// 添加部门
Integer addDept(Dept dept);
// 修改部门信息
Integer updateDept(Dept dept);
// 删除部门
Integer deleteDept(Integer id);
}
编辑
修改DeptServiczeImpl类
@Service
public class DeptServiczeImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {
@Autowired
ObjectMapper objectMapper;
@Autowired
DeptMapper deptMapper;
@Autowired
EmpClient empClient;
// 查询所有部门
@Override
public List<Dept> queryAll() {
List<Dept> depts = deptMapper.selectList(null);
return depts;
}
// 根据部门Id获取部门信息
@Override
public Dept queryById(Integer id) {
Dept dept = deptMapper.selectById(id);
Result result = empClient.querySimpleByDeptId(id);
if (result.getCode()==1){
Object data = result.getData();
List<EmpSimpleDto> list = objectMapper.convertValue(data, new TypeReference<List<EmpSimpleDto>>() {});
dept.setEmpsSimple(list); // 设置简单员工列表
}
return dept;
}
// 添加部门
@Override
public Integer addDept(Dept dept) {
dept.setCreateTime(LocalDateTime.now());
dept.setUpdateTime(LocalDateTime.now());
int i = deptMapper.insert(dept);
return i;
}
// 修改部门
@Override
public Integer updateDept(Dept dept) {
if (dept.getId()==null){
return 0;
}
dept.setUpdateTime(LocalDateTime.now());
int i = deptMapper.updateById(dept);
return i;
}
// 删除部门
@Override
public Integer deleteDept(Integer id) {
Result result = empClient.querySimpleByDeptId(id);
if (result.getCode()==1){
Object data = result.getData();
List<EmpSimpleDto> list = objectMapper.convertValue(data, new TypeReference<List<EmpSimpleDto>>() {});
if (list.size()>0){
throw new RuntimeException("该部门下有员工,不能删除");
}
}
int i = deptMapper.deleteById(id);
return i;
}
}
编辑
修改DeptController类
@Slf4j
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
DeptService deptService;
// 查询所有部门信息
@GetMapping
public Result queryAll() {
log.info("查询所有部门信息");
List<Dept> list = deptService.queryAll();
return list != null ? Result.success(list) : Result.error();
}
// 根据部门ID获取部门信息
@GetMapping("/{id}")
public Result queryById(@PathVariable Integer id) {
log.info("根据部门ID:{}查询部门信息", id);
Dept dept = deptService.queryById(id);
return dept != null ? Result.success(dept): Result.error();
}
// 添加部门
@PostMapping
public Result addDept(@RequestBody Dept dept) {
log.info("添加部门:{}", dept);
Integer i = deptService.addDept(dept);
return i>0 ? Result.success() : Result.error();
}
// 修改部门
@PutMapping
public Result updateDept(@RequestBody Dept dept) {
log.info("修改部门:{}", dept);
Integer i = deptService.updateDept(dept);
return i>0 ? Result.success() : Result.error();
}
// 删除部门
@DeleteMapping("/{id}")
public Result deleteDept(@PathVariable Integer id) {
log.info("删除部门ID:{}", id);
Integer i = deptService.deleteDept(id);
return i>0 ? Result.success() : Result.error();
}
}
编辑
配置全局异常处理
修改common-utils模块pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>common-utils</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--common-pojo-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
编辑
创建包,创建GlobalExceptionHandle类
package com.he.exception;
import com.he.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandle {
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
// 收到异常之后,做的事?
e.printStackTrace(); // 打印异常信息
log.error("全局异常处理:{}",e.getMessage());
return Result.error(e.getMessage());
}
}
编辑
配置Redis缓存
修改父工程pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>emp-service</module>
<module>dept-service</module>
<module>common-pojo</module>
<module>feign-api</module>
<module>common-utils</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.13</version>
<relativePath/>
</parent>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot-starter-web.version>3.3.13</spring-boot-starter-web.version>
<mybatis-plus.version>3.5.7</mybatis-plus.version>
<mysql.version>8.0.33</mysql.version>
<lombok.version>1.18.22</lombok.version>
<spring-cloud.version>2023.0.1</spring-cloud.version>
<spring-cloud-alibaba-version>2023.0.1.0</spring-cloud-alibaba-version>
<spring-boot-starter-data-redis.version>3.3.13</spring-boot-starter-data-redis.version>
<spring-boot-starter-cache.version>3.3.13</spring-boot-starter-cache.version>
</properties>
<!-- 引入共有的依赖 -->
<dependencies>
<!--springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot-starter-web.version}</version>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
</dependencies>
<!-- 管理依赖版本 -->
<dependencyManagement>
<dependencies>
<!--mysql-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${spring-boot-starter-data-redis.version}</version>
</dependency>
<!--spring-cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>${spring-boot-starter-cache.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
编辑
遇到问题:只引入spring-boot-starter-cache,不引入spring-boot-starter-data-redis,数据不会存在redis中
原因:Spring Boot会默认使用基于内存的ConcurrentMapCacheManager作为缓存管理器,数据不会存储到Redis中,必须显式引入spring-boot-starter-data-redis依赖,并配置Redis连接信息时Spring Boot会自动检测到Redis依赖,并将缓存管理器替换为RedisCacheManager。
修改common-utils模块pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.he</groupId>
<artifactId>kawa-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>common-utils</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--common-pojo-->
<dependency>
<groupId>com.he</groupId>
<artifactId>common-pojo</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring-cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
</dependencies>
</project>
编辑
common-utils模块创建RedisConfiguration配置类
@Configuration
public class RedisConfiguration {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
// 使用StringRedisSerializer
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// 使用Jackson序列化器
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
// 创建RedisTemplate对象
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 设置连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置redis的key序列化器
redisTemplate.setKeySerializer(stringRedisSerializer);
// 设置redis的value序列化器
redisTemplate.setValueSerializer(serializer);
// 设置redis的hashKey序列化器
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// 添加redis的hashValue序列化器
redisTemplate.setHashValueSerializer(serializer);
// 返回
return redisTemplate;
}
}
编辑
完善emp-service模块redis缓存
修改application.yml配置文件
server:
port: 8081
spring:
application:
name: empservice
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/empdatabase
username: root
password: 123456
cloud:
nacos:
server-addr: localhost:8848
# Nacos 服务器启用了认证
username: nacos # 默认用户名
password: nacos # 默认密码
discovery:
cluster-name: SZ # 集群名称
ephemeral: true # 配置是否注册为临时服务,默认是true即临时服务
data:
redis:
host: localhost
port: 6379
password: ""
database: 0
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true # 开启驼峰命名
logging:
level:
com.he: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
feign:
client:
config:
default: # default全局的配置
loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
httpclient:
enabled: true # 开启feign对HttpClient的支持
max-connections: 200 # 最大的连接数
max-connections-per-route: 50 # 每个路径的最大连接数
deptservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
ribbon:
eager-load:
enabled: true # 开启饥饿加载,默认是false即懒加载
clients: deptservice
编辑
修改EmpApplication启动类
@SpringBootApplication
@EnableCaching
@EnableFeignClients(clients = {DeptClient.class})
public class EmpApplication {
public static void main(String[] args) {
SpringApplication.run(EmpApplication.class, args);
}
}
编辑
修改EmpServiceImpl类
@Service
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService {
@Autowired
ObjectMapper objectMapper;
@Autowired
EmpMapper empMapper;
@Autowired
private DeptClient deptClient;
// 根据信息分页查询
@Cacheable(cacheNames = "empsList",key = "#empSearchDto.hashCode()" )
public PageBean queryByInfo(EmpSearchDto empSearchDto) {
// 创建查询条件
LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper();
queryWrapper.like(StringUtils.hasLength(empSearchDto.getName()),Emp::getName, empSearchDto.getName())
.eq(empSearchDto.getGender()!=null,Emp::getGender, empSearchDto.getGender())
.ge(empSearchDto.getBegin()!=null,Emp::getEntryDate, empSearchDto.getBegin())
.le(empSearchDto.getEnd()!=null,Emp::getEntryDate, empSearchDto.getEnd());
// 创建分页条件
if (empSearchDto.getPage() == null) {
empSearchDto.setPage(1);
}
if (empSearchDto.getPageSize() == null) {
empSearchDto.setPageSize(5);
}
Page<Emp> pageInfo = new Page<>(empSearchDto.getPage(), empSearchDto.getPageSize());
// 执行查询
Page<Emp> empPage = empMapper.selectPage(pageInfo, queryWrapper);
// 为每个员工获取对应的部门信息
List<Emp> empList = empPage.getRecords().stream().map(emp -> {
// 调用Feign客户端获取部门信息
Result deptResult = deptClient.queryDeptSimpleById(emp.getDeptId());
if (deptResult.getCode() == 1) {
// 假设员工实体中有部门名称字段 手动转换为部门实体
Object data = deptResult.getData();
DeptSimpleDto dept = objectMapper.convertValue(data, DeptSimpleDto.class);
emp.setDeptSimple(dept);
}
return emp;
}).collect(Collectors.toList());
// 封装数据
PageBean pageBean = new PageBean(empPage.getTotal(), empList);
// 返回数据
return pageBean;
}
// 根据部门ID获取所有符合的员工信息
@Override
public List<Emp> queryByDeptId(Integer deptId) {
// 创建查询条件
LambdaQueryWrapper<Emp> queryWrapper = new LambdaQueryWrapper();
queryWrapper.eq(Emp::getDeptId, deptId);
// 执行查询
List<Emp> empList = empMapper.selectList(queryWrapper);
// 返回数据
return empList;
}
// 根据员工ID获取员工信息
@Override
@Cacheable(cacheNames = "emps",key = "#id")
public Emp queryById(Integer id) {
Emp emp = empMapper.selectById(id);
return emp;
}
// 添加员工
@Override
@CacheEvict(cacheNames = "empsList",allEntries = true)
public Integer addEmp(Emp emp) {
if (emp.getName() == null || emp.getUsername() == null|| emp.getGender() == null){
return 0;
}
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
emp.setEntryDate(LocalDate.now());
emp.setPassword("123456");
int i = empMapper.insert(emp);
return i;
}
// 修改员工
@Override
@Caching(evict = {@CacheEvict(cacheNames = "emps", key = "#emp.id"),@CacheEvict(cacheNames = "empsList",allEntries = true)})
public Integer updateEmp(Emp emp) {
if (emp.getId() == null){
return 0;
}
emp.setUpdateTime(LocalDateTime.now());
int i = empMapper.updateById(emp);
return i;
}
// 删除员工
@Override
@Caching(evict = {@CacheEvict(cacheNames = "emps", key = "#id"),@CacheEvict(cacheNames = "empsList",allEntries = true)})
public Integer deleteEmp(Integer id) {
int i = empMapper.deleteById(id);
return i;
}
}
编辑
完善dept-service模块redis缓存
修改application.yml配置文件
server:
port: 8091
spring:
application:
name: deptservice
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/deptdatabase
username: root
password: 123456
cloud:
nacos:
server-addr: localhost:8848
# Nacos 服务器启用了认证
username: nacos # 默认用户名
password: nacos # 默认密码
discovery:
cluster-name: SZ # 集群名称
ephemeral: true # 配置是否注册为临时服务,默认是true即临时服务
data:
redis:
host: localhost
port: 6379
password: ""
database: 0
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true # 开启驼峰命名
logging:
level:
com.he: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
feign:
client:
config:
default: # default全局的配置
loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
httpclient:
enabled: true # 开启feign对HttpClient的支持
max-connections: 200 # 最大的连接数
max-connections-per-route: 50 # 每个路径的最大连接数
empservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
ribbon:
eager-load:
enabled: true # 开启饥饿加载,默认是false即懒加载
clients: empservice
编辑
修改DeptApplication启动类
@SpringBootApplication
@EnableCaching
@EnableFeignClients(clients = {EmpClient.class})
public class DeptApplication {
public static void main(String[] args) {
SpringApplication.run(DeptApplication.class, args);
}
}
编辑
修改DeptServiceImpl类
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {
@Autowired
ObjectMapper objectMapper;
@Autowired
DeptMapper deptMapper;
@Autowired
EmpClient empClient;
// 查询所有部门
@Override
@Cacheable(cacheNames = "depts", key = "'deptsList'")
public List<Dept> queryAll() {
List<Dept> depts = deptMapper.selectList(null);
return depts;
}
// 根据部门Id获取部门信息
@Override
@Cacheable(cacheNames = "depts", key = "#id")
public Dept queryById(Integer id) {
Dept dept = deptMapper.selectById(id);
Result result = empClient.querySimpleByDeptId(id);
if (result.getCode()==1){
Object data = result.getData();
List<EmpSimpleDto> list = objectMapper.convertValue(data, new TypeReference<List<EmpSimpleDto>>() {});
dept.setEmpsSimple(list); // 设置简单员工列表
}
return dept;
}
// 添加部门
@Override
@CacheEvict(cacheNames = "depts",key = "'deptsList'")
public Integer addDept(Dept dept) {
dept.setCreateTime(LocalDateTime.now());
dept.setUpdateTime(LocalDateTime.now());
int i = deptMapper.insert(dept);
return i;
}
// 修改部门
@Override
@Caching(evict = {@CacheEvict(cacheNames = "depts", key = "#dept.id"),@CacheEvict(cacheNames = "depts",key = "'deptsList'")})
public Integer updateDept(Dept dept) {
if (dept.getId()==null){
return 0;
}
dept.setUpdateTime(LocalDateTime.now());
int i = deptMapper.updateById(dept);
return i;
}
// 删除部门
@Override
@Caching(evict = {@CacheEvict(cacheNames = "depts", key = "#id"),@CacheEvict(cacheNames = "depts",key = "'deptsList'")})
public Integer deleteDept(Integer id) {
Result result = empClient.querySimpleByDeptId(id);
if (result.getCode()==1){
Object data = result.getData();
List<EmpSimpleDto> list = objectMapper.convertValue(data, new TypeReference<List<EmpSimpleDto>>() {});
if (list.size()>0){
throw new RuntimeException("该部门下有员工,不能删除");
}
}
int i = deptMapper.deleteById(id);
return i;
}
}
编辑
提交至Gitee
初始化本地仓库
编辑
添加远程仓库
编辑
编辑
本地提交
编辑
推送至远端仓库
编辑
编辑
源码:gitee.com/banana911/k…
数据库sql:
drop table if EXISTS dept;
CREATE TABLE dept (
id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT 'ID, 主键',
name varchar(10) NOT NULL UNIQUE COMMENT '部门名称',
create_time datetime DEFAULT NULL COMMENT '创建时间',
update_time datetime DEFAULT NULL COMMENT '修改时间'
) COMMENT '部门表';
INSERT INTO dept VALUES (1,'学工部','2023-09-25 09:47:40','2023-09-25 09:47:40'),
(2,'教研部','2023-09-25 09:47:40','2023-10-09 15:17:04'),
(3,'咨询部','2023-09-25 09:47:40','2023-11-30 21:26:24'),
(4,'就业部','2023-09-25 09:47:40','2023-09-25 09:47:40'),
(5,'人事部','2023-09-25 09:47:40','2023-09-25 09:47:40'),
(15,'行政部','2023-11-30 20:56:37','2023-11-30 20:56:37'),
(6,'财务部','2023-12-01 08:30:15','2023-12-01 08:30:15'),
(7,'市场部','2023-12-05 14:22:10','2024-01-10 11:05:33'),
(8,'技术部','2023-12-10 09:15:45','2024-02-15 16:40:22'),
(9,'客服部','2023-12-15 10:20:30','2023-12-15 10:20:30'),
(10,'采购部','2023-12-20 13:45:00','2024-03-05 09:30:18'),
(11,'法务部','2024-01-05 15:10:25','2024-01-05 15:10:25'),
(12,'品牌部','2024-01-10 11:35:40','2024-04-20 14:25:10'),
(13,'国际部','2024-01-15 16:50:55','2024-01-15 16:50:55'),
(14,'研发中心','2024-02-01 09:25:30','2024-05-15 10:45:12'),
(16,'质量部','2024-02-10 14:15:20','2024-02-10 14:15:20');
drop table if EXISTS emp;
create table emp(
id int unsigned primary key auto_increment comment 'ID,主键',
username varchar(20) not null unique comment '用户名',
password varchar(50) default '123456' comment '密码',
name varchar(10) not null comment '姓名',
gender tinyint unsigned not null comment '性别, 1:男, 2:女',
phone char(11) not null unique comment '手机号',
job tinyint unsigned comment '职位, 1 班主任, 2 讲师 , 3 学工主管, 4 教研主管, 5 咨询师',
salary int unsigned comment '薪资',
image varchar(300) comment '头像',
entry_date date comment '入职日期',
dept_id int unsigned comment '部门ID',
create_time datetime comment '创建时间',
update_time datetime comment '修改时间'
) comment '员工表';
INSERT INTO emp VALUES
(1,'shinaian','123456','施耐庵',1,'13309090001',4,15000,'5.png','2000-01-01',2,'2023-10-20 16:35:33','2023-11-16 16:11:26'),
(2,'songjiang','123456','宋江',1,'13309090002',2,8600,'01.png','2015-01-01',2,'2023-10-20 16:35:33','2023-10-20 16:35:37'),
(3,'lujunyi','123456','卢俊义',1,'13309090003',2,8900,'01.png','2008-05-01',2,'2023-10-20 16:35:33','2023-10-20 16:35:39'),
(4,'wuyong','123456','吴用',1,'13309090004',2,9200,'01.png','2007-01-01',2,'2023-10-20 16:35:33','2023-10-20 16:35:41'),
(5,'gongsunsheng','123456','公孙胜',1,'13309090005',2,9500,'01.png','2012-12-05',2,'2023-10-20 16:35:33','2023-10-20 16:35:43'),
(6,'huosanniang','123456','扈三娘',2,'13309090006',3,6500,'01.png','2013-09-05',1,'2023-10-20 16:35:33','2023-10-20 16:35:45'),
(7,'chaijin','123456','柴进',1,'13309090007',1,4700,'01.png','2005-08-01',1,'2023-10-20 16:35:33','2023-10-20 16:35:47'),
(8,'likui','123456','李逵',1,'13309090008',1,4800,'01.png','2014-11-09',1,'2023-10-20 16:35:33','2023-10-20 16:35:49'),
(9,'wusong','123456','武松',1,'13309090009',1,4900,'01.png','2011-03-11',1,'2023-10-20 16:35:33','2023-10-20 16:35:51'),
(10,'linchong','123456','林冲',1,'13309090010',1,5000,'01.png','2013-09-05',1,'2023-10-20 16:35:33','2023-10-20 16:35:53'),
(11,'huyanzhuo','123456','呼延灼',1,'13309090011',2,9700,'01.png','2007-02-01',2,'2023-10-20 16:35:33','2023-10-20 16:35:55'),
(12,'xiaoliguang','123456','小李广',1,'13309090012',2,10000,'01.png','2008-08-18',2,'2023-10-20 16:35:33','2023-10-20 16:35:57'),
(13,'yangzhi','123456','杨志',1,'13309090013',1,5300,'01.png','2012-11-01',1,'2023-10-20 16:35:33','2023-10-20 16:35:59'),
(14,'shijin','123456','史进',1,'13309090014',2,10600,'01.png','2002-08-01',2,'2023-10-20 16:35:33','2023-10-20 16:36:01'),
(15,'sunerniang','123456','孙二娘',2,'13309090015',2,10900,'01.png','2011-05-01',2,'2023-10-20 16:35:33','2023-10-20 16:36:03'),
(16,'luzhishen','123456','鲁智深',1,'13309090016',2,9600,'01.png','2010-01-01',2,'2023-10-20 16:35:33','2023-10-20 16:36:05'),
(17,'liying','12345678','李应',1,'13309090017',1,5800,'01.png','2015-03-21',1,'2023-10-20 16:35:33','2023-10-20 16:36:07'),
(18,'shiqian','123456','时迁',1,'13309090018',2,10200,'01.png','2015-01-01',2,'2023-10-20 16:35:33','2023-10-20 16:36:09'),
(19,'gudasao','123456','顾大嫂',2,'13309090019',2,10500,'01.png','2008-01-01',2,'2023-10-20 16:35:33','2023-10-20 16:36:11'),
(20,'ruanxiaoer','123456','阮小二',1,'13309090020',2,10800,'01.png','2018-01-01',2,'2023-10-20 16:35:33','2023-10-20 16:36:13'),
(21,'ruanxiaowu','123456','阮小五',1,'13309090021',5,5200,'01.png','2015-01-01',3,'2023-10-20 16:35:33','2023-10-20 16:36:15'),
(22,'ruanxiaoqi','123456','阮小七',1,'13309090022',5,5500,'01.png','2016-01-01',3,'2023-10-20 16:35:33','2023-10-20 16:36:17'),
(23,'ruanji','123456','阮籍',1,'13309090023',5,5800,'01.png','2012-01-01',3,'2023-10-20 16:35:33','2023-10-20 16:36:19'),
(24,'tongwei','123456','童威',1,'13309090024',5,5000,'01.png','2006-01-01',3,'2023-10-20 16:35:33','2023-10-20 16:36:21'),
(25,'tongmeng','123456','童猛',1,'13309090025',5,4800,'01.png','2002-01-01',3,'2023-10-20 16:35:33','2023-10-20 16:36:23'),
(26,'yanshun','123456','燕顺',1,'13309090026',5,5400,'01.png','2011-01-01',3,'2023-10-20 16:35:33','2023-11-08 22:12:46'),
(27,'lijun','123456','李俊',1,'13309090027',2,6600,'8.png','2004-01-01',2,'2023-10-20 16:35:33','2023-11-16 17:56:59'),
(28,'lizhong','123456','李忠',1,'13309090028',5,5000,'6.png','2007-01-01',3,'2023-10-20 16:35:33','2023-11-17 16:34:22'),
(30,'liyun','123456','李云',1,'13309090030',NULL,NULL,'01.png','2020-03-01',NULL,'2023-10-20 16:35:33','2023-10-20 16:36:31'),
(36,'linghuchong','123456','令狐冲',1,'18809091212',2,6800,'1.png','2023-10-19',2,'2023-10-20 20:44:54','2023-11-09 09:41:04');