微服务之spring Boot+MyBatis-Plus +mysql框架

今天小白将从零亲手搭建spring Boot+MyBatis-Plus +mysql框架的微服务。

一、新建一个微服务模块cloud-user

1、 搭建步骤

  • 具体步骤请看前面章节(微服务的搭建):https://blog.csdn.net/qq_38066812/article/details/109426982
  • 搭建目录如下
    在这里插入图片描述
  • controller层一般有多个端,根据不同的端的意义来命名即可。
  • 本地安装mysql5.1以上版本。
  • 在父目录的pom文件中引入mybatis依赖如下。
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>${mybatis-plus-boot-starter.version}</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>${mybatis-plus-boot-starter.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity</artifactId>
    <version>${velocity.version}</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.version}</version>
</dependency>
<!-- mybatis-plus end -->

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <mybatis-plus-boot-starter.version>3.3.0</mybatis-plus-boot-starter.version>
    <mysql.version>5.1.47</mysql.version>
    <druid.version>1.1.20</druid.version>
</properties>
  • 注意事项:如果希望操作数据库删除数据使用逻辑删除,mybatis-plus版本一定要使用3.3.0以上,低版本的不支持
  • 逻辑删除指导请查看链接:https://baomidou.com/guide/logic-delete.html

二、编码

1、新建UserController类

  • 接口定义遵循RestFull风格。
package yooo.yun.com.user.controller.saas;

import com.alibaba.fastjson.JSON;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import yooo.yun.com.common.api.ApiCode;
import yooo.yun.com.common.api.ApiResult;
import yooo.yun.com.common.entity.enums.LoginTypeEnum;
import yooo.yun.com.common.entity.pojo.UserPoJo;
import yooo.yun.com.common.entity.request.UserLoginReq;
import yooo.yun.com.common.entity.request.UserReq;
import yooo.yun.com.user.service.UserService;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;

/**
 * @author WangJiao
 * @since 2020/10/14
 */
@Slf4j
@RequestMapping(value = "/saas/user")
@RestController("sUserC")
public class UserController {
  @Resource private UserService service;

  /**
   * 用户注册
   *
   * @param req 注册信息
   * @return obj
   */
  @PostMapping("/register")
  @ApiOperation("注册")
  public ApiResult register(@Valid @RequestBody UserReq req) {
    log.info("register:[req:{}]", JSON.toJSONString(req));
    if (!Objects.equals(req.getPassword(), req.getRePassword())) {
      return ApiResult.fail(ApiCode.USER_TWO_PASSWORDS_INCONSISTENT);
    }
    UserPoJo findUser = service.getByTel(req.getTel());
    if (Objects.nonNull(findUser)) {
      return ApiResult.fail(ApiCode.USER_ACCOUNT_REGISTERED);
    }

    // md5加密
    req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()));
    boolean res = service.save(UserPoJo.of(req));
    log.info("register:[res:{}]", res);
    return ApiResult.ok(res);
  }

  /**
   * 用户登录
   *
   * @param req req
   * @return res
   */
  @PostMapping("/login")
  @ApiOperation("登录")
  public ApiResult login(@Valid @RequestBody UserLoginReq req) {
    log.info("login:[req:{}]", req);
    String tel = req.getTel();
    UserPoJo findUser = service.getByTel(tel);
    if (Objects.isNull(findUser)) {
      return ApiResult.fail(ApiCode.USER_ACCOUNT_NOT_EXIST);
    }
    if (!Objects.equals(
        DigestUtils.md5DigestAsHex(req.getPassword().getBytes()), findUser.getPassword())) {
      return ApiResult.fail(ApiCode.USER_PASSWORDS_ERROR);
    }
    return ApiResult.ok(service.login(findUser, LoginTypeEnum.SAAS.getValue()));
  }

  /**
   * 获取用户详情
   *
   * @param id id
   * @return res
   */
  @GetMapping("/{id}")
  @ApiOperation("获取用户详情")
  public ApiResult detail(@PathVariable(value = "id") long id) {
    log.info("detail:[id:{}]", id);
    return ApiResult.ok(service.getById(id));
  }

  /**
   * 删除用户信息
   *
   * @param id id
   * @return res
   */
  @DeleteMapping("/delete/{id}")
  @ApiOperation("删除用户信息")
  public ApiResult delete(@PathVariable(value = "id") long id) {
    log.info("delete:[id:{}]", id);
    return ApiResult.ok(service.removeById(id));
  }
}

2、新建UserService类

package yooo.yun.com.user.service;

import yooo.yun.com.common.entity.pojo.UserPoJo;
import yooo.yun.com.common.service.BaseService;

/**
 * @author WangJiao
 * @since 2020/11/12
 */
public interface UserService extends BaseService<UserPoJo> {
  /**
   * query user info by tel
   *
   * @param tel the tel
   * @return user
   */
  UserPoJo getByTel(String tel);

  int testE(int status);

  /**
   * 登录
   *
   * @param findUser findUser
   * @param loginType loginType
   * @return token
   */
  String login(UserPoJo findUser, String loginType);
}
  • UserService继承BaseService,可以直接使用mybatis提供的原生操作数据库的方法,简单的业务处理不需要我们动手去写sql语句。

3、新建UserServiceImpl类

package yooo.yun.com.user.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import yooo.yun.com.common.entity.enums.UserRoleEnum;
import yooo.yun.com.common.entity.pojo.UserPoJo;
import yooo.yun.com.common.service.Impl.BaseServiceImpl;
import yooo.yun.com.common.utils.JWTUtil;
import yooo.yun.com.user.mapper.UserMapper;
import yooo.yun.com.user.service.UserService;

import javax.annotation.Resource;

/**
 * @author WangJiao
 * @since 2020/11/12
 */
@Slf4j
@Service
public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserPoJo> implements UserService {
  @Resource private UserMapper mapper;

  @Override
  public UserPoJo getByTel(String tel) {
    log.info("getByTel:[tel:{}]", tel);
    return mapper.selectOne(Wrappers.<UserPoJo>lambdaQuery().eq(UserPoJo::getTel, tel));
  }

  @Override
  public int testE(int status) {
    int num = 0;
    return status / num;
  }

  @Override
  public String login(UserPoJo findUser, String loginType) {
    // TODO: 2020/11/25/025 其他业务逻辑处理

    String token =
        JWTUtil.generateSaasToken(findUser.getId(), UserRoleEnum.ADMIN.getValue(), null, loginType);
    log.info("login:[token:{}]", token);
    return token;
  }
}

4、编写UserMapper类

package yooo.yun.com.user.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
import yooo.yun.com.common.entity.pojo.UserPoJo;

/**
 * @author WangJiao
 * @since 2020/11/12
 */
@Repository
public interface UserMapper extends BaseMapper<UserPoJo> {
}
  • UserMapper继承BaseMapper;
  • 我们就可以使用框架提供的原生方法,不需要再写一遍,提高开发速度;
  • mybatis中的BaseMapper源码如下,我们可以直接调用。

5、application.yml文件配置如下

server:
  port: 5050
  servlet:
    context-path: /user

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8080/eureka

  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
############################### mysql start #################################
spring:
  application:
    name: cloud-user
  freemarker:
    enabled: false
  thymeleaf:
    cache: false
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?characterEncoding=utf8&generateSimpleParameterMetadata=true&connectTimeout=5000&useSSL=false
    username: ****
    password: ****
############################### mysql end #################################
# logback.xml中有详细的日志配置
logging:
  config: classpath:logback.xml

############################### mybatis-plus start #################################
mybatis-plus:
  # 启动时是否检查MyBatis XML文件是否存在
  check-config-location: true
  # MyBatis原生配置
  configuration:
    # 字段名称下划线转驼峰命名
    map-underscore-to-camel-case: true
    # 打印SQL日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      # 全局默认主键类型
      id-type: id_worker
      logic-delete-field: isDelete
      # 逻辑已删除值(默认为 1)
      logic-delete-value: true # 逻辑已删除值(默认为 1)
      # 逻辑未删除值(默认为 0)
      logic-not-delete-value: false # 逻辑未删除值(默认为 0)
  # mapper xml映射路径
  mapper-locations: classpath*:mapper/**/*Mapper.xml
################################ mybatis-plus end ##################################

#################################### Swagger start #################################
# swagger配置
swagger:
  base:
    package: yooo.yun.com
  contact:
    email: jiao.wang@cloud.yun
    name: wangjiao
    url: ''
  description: ''
  title: spring-demo
  url: ''
  version: 1.0
#################################### Swagger end ###################################

3、测试接口

1、测试逻辑删除

  • 表中目前有一条数据
    在这里插入图片描述
  • 调用查询接口
    在这里插入图片描述
  • 查询详情接口编写
/**
 * 获取用户详情
 *
 * @param id id
 * @return res
 */
@GetMapping("/{id}")
@ApiOperation("获取用户详情")
public ApiResult detail(@PathVariable(value = "id") long id) {
  log.info("detail:[id:{}]", id);
  return ApiResult.ok(service.getById(id));
}
  • 控制台日志
    在这里插入图片描述
  • 调用删除接口
    在这里插入图片描述
  • 删除接口控制台打印信息
    在这里插入图片描述
  • 因为是逻辑删除,所以调用的是修改sql的语句,而不是直接删除的sql语句
  • 查看表中数据,is_delete的状态已经改变了
    在这里插入图片描述
  • 如果需要在控制台显示sql语句,需要如下配置
    在这里插入图片描述 - user的yml文件配置如下
    在这里插入图片描述

四、注解解释

1、@Slf4j:

  • @Slf4j注解在类上;为类提供一个 属性名为log 的 log4j 日志对像
  • 导入类import lombok.extern.slf4j.Slf4j;
  • Slf4j属于lombok注解,
  • 导入的pom依赖如下
<!-- lombok使实体类简写get与set方法-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
    <scope>provided</scope>
</dependency>
  • 例子:log.info(“register:user register info[req:{}]”, JSON.toJSONString(req));

2、@RequestMapping

  • RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
    在这里插入图片描述

3、@RestController

  • 项目url父路径
@RequestMapping(value = "/saas/user")

@RestController注解,相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解,但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面
例子:@RestController(value = “miniUserC”)中的value区分项目中的bean,比如项目中有两个相同的UserController。

提供了对Restful风格的支持

4、@GetMapping

  • 处理get请求,查询数据请求
@GetMapping("/{id}")

等价于

@RequestMapping(value = "/{id}",method = RequestMethod.GET)
  /**
   * 获取用户详情
   *
   * @param id id
   * @return res
   */
  @GetMapping("/{id}")
  @ApiOperation("获取用户详情")
  public ApiResult detail(@PathVariable(value = "id") long id) {
    log.info("detail:[id:{}]", id);
    return ApiResult.ok(service.getById(id));
  }

5、@PostMapping

  • 处理post请求,写入数据
@PostMapping("/register")

等价于

@RequestMapping(value = "/register",method = RequestMethod.POST)
/**
   * 用户注册
   *
   * @param req 注册信息
   * @return obj
   */
  @PostMapping("/register")
  @ApiOperation("注册")
  public ApiResult register(@Valid @RequestBody UserReq req) {
    log.info("register:user register info[req:{}]", JSON.toJSONString(req));
    if (!Objects.equals(req.getPassword(), req.getRePassword())) {
      return ApiResult.fail(ApiCode.USER_TWO_PASSWORDS_INCONSISTENT);
    }
    UserPoJo findUser = service.getByTel(req.getTel());
    if (Objects.nonNull(findUser)) {
      return ApiResult.fail(ApiCode.USER_ACCOUNT_REGISTERED);
    }

    // md5加密
    req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes()));
    boolean res = service.save(UserPoJo.of(req));
    log.info("register:[res:{}]", res);
    return ApiResult.ok(res);
  }

6、@PutMapping

  • 处理put请求,修改数据请求
@PutMapping("/update/{id}")

等价于

@RequestMapping(value = "/register",method = RequestMethod.POST)

7、@DeleteMapping

  • 处理delete请求,删除数据
@DeleteMapping("/delete/{id}")

等价于

@RequestMapping(value = "/update/{id}",method = RequestMethod.DELETE)
  /**
   * 删除用户信息
   *
   * @param id id
   * @return res
   */
  @DeleteMapping("/delete/{id}")
  @ApiOperation("删除用户信息")
  public ApiResult delete(@PathVariable(value = "id") long id) {
    log.info("delete:[id:{}]", id);
    UserPoJo find = service.getById(id);
    if (Objects.isNull(find)) {
      return ApiResult.fail(ApiCode.DATA_NOT_EXIST_FAILED_DELETE);
    }
    return ApiResult.ok(service.removeById(id));
  }

:- 学到这里,你就get到了喔

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值