微服务迁移记:公共层接口层和实现层搭建

Posted zhouyu629

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务迁移记:公共层接口层和实现层搭建相关的知识,希望对你有一定的参考价值。

公共层Nodule:zyproject-common,通用返回体、状态码枚举、自定义分页类。本来计划Entity放在common里的,后来想了下,还是放到接口层,反正其他层也都会引用接口层。

接口独立成一个Module:zyproject-api-service,定义访问接口,供实现类、表现层调用,其中Feign接口直接继续接口层,可以避免很多冗余代码

实现层Module:zyproject-api-service-impl,与数据库打交道,实现接口。

一、公共层

通用返回体是从网上抄的,ResponseData继承BaseResponse

技术图片
package com.zyproject.common;

/**
 * @program: zyproject
 * @description: 基本响应类封装
 * @author: zhouyu(zhouyu629 @ qq.com)
 * @create: 2020-02-11
 **/
public class BaseReponse {
    private int code; //响应码
    private String msg; //响应消息
    protected  BaseReponse(){}
    protected  BaseReponse(CodeEnum codeEnum){
        this.code = codeEnum.getCode();
        this.msg = codeEnum.getMsg();
    }
    public static BaseReponse out(CodeEnum codeEnum){
        return new BaseReponse(codeEnum);
    }
    public int getCode(){return code;}
    public void setCode(int code){this.code = code;}
    public String getMsg(){return msg;}
    public void setMsg(String msg){this.msg = msg;}
}
View Code
技术图片
package com.zyproject.common;

/**
 * @program: zyproject
 * @description: 响应数据结构封装
 * @author: zhouyu(zhouyu629 @ qq.com)
 * @create: 2020-02-11
 **/
public class ResponseData<T> extends BaseReponse {
    private T data;
    private ResponseData(){}
    private ResponseData(CodeEnum codeEnum, T data){
        super(codeEnum);
        this.data = data;
    }
    public static <T> ResponseData<T> out(CodeEnum codeEnum,T data){
        return new ResponseData<T>(codeEnum,data);
    }

    public T getData(){
        return data;
    }
    public void setData(T data){
        this.data = data;
    }
}
View Code

CodeEnum主要是状态码枚举

技术图片
package com.zyproject.common;

/**
 *  状态码枚举
 */
public enum CodeEnum {
    SUCCESS(1000,"成功!"),
    FAIL(1001,"未知错误"),
    LOGINFAIL(1002,"用户名或密码错误,登录失败"),
    USERNOTEXIST(1003,"用户信息不存在"),
    TIMEOUT(1004,"会话超时"),
    NORIGHT(1005,"无权限"),
    NOTREE(1006,"未查找到对应的菜单"),
    NORECORDS(1007,"无记录"),
    ;


    private int code; //状态码
    private String msg; //响应内容

    CodeEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int getCode(){
        return  code;
    }

    public String getMsg(){
        return msg;
    }

    public static String getEnumDesc(Integer value) {
        CodeEnum[] businessModeEnums = values();
        for (CodeEnum businessModeEnum : businessModeEnums) {
            if (businessModeEnum.getCode() == value) {
                return businessModeEnum.getMsg();
            }
        }
        return null;
    }

    public static Integer getEnumCode(String value) {
        CodeEnum[] codeEnums = values();
        for (CodeEnum codeEnum : codeEnums) {
            if (codeEnum.getMsg() == value) {
                return codeEnum.getCode();
            }
        }
        return null;
    }

}
View Code

MyPager是我自己写的一个自定义分页实体类,并在WEB层实现与bootstrap分页样式结合,自定义了一个feemarker宏实现分页。WEB层再详细说明。

其他,略。

二、接口层

以模块为维度建立项目,以系统管理层为例:zyproject-api-service-system,项目类型为jar,部分代码,实体部分集成lombok,代码略。

技术图片
package com.zyproject.service;

import com.zyproject.common.ResponseData;
import com.zyproject.entity.TreeEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

public interface ISystemService {

    /**
     *
     *  用户相关
     *
     */

    //用户登录方法
    @RequestMapping("/userLogin")
    public ResponseData userLogin(@RequestParam String user_code, @RequestParam String password);
    //根据用户名,查找用户信息,为SpringSercrity等业务提供服务
    @RequestMapping("/findByLoginname")
    public ResponseData findByLoginname(@RequestParam String login_name);


    /**
     *
     *  菜单相关
     *
     */


    //获取所有菜单列表,含有删除未删除的
    @RequestMapping("/getAllTreeList")
    public List<TreeEntity> getAllTreeList();
    //根据用户获取有权限的组织机构树
    @RequestMapping("/getTreeWithUserRight")
    public ResponseData getTreeWithUserRight(@RequestParam int userid);
    //根据tree_id获取菜单实体
    @RequestMapping("/getTreeByTreeId")
    public ResponseData getTreeByTreeId(@RequestParam int tree_id);
    //分页获取角色列表(状态正常)
    @RequestMapping("/getRoleByPage")
    public ResponseData getRoleByPage(@RequestParam(defaultValue = "1") int page,@RequestParam(defaultValue = "10") int pagesize);
    //根据用户获取当前用户所有权限按钮
    @RequestMapping("/getRoleTreefuncByUserid")
    public ResponseData getRoleTreefuncByUserid(@RequestParam  int user_id);

}
View Code

 

三、接口实现

以系统管理为例:zyproject-api-service-impl,项目类型为pom,需要以http形式发布访问,注册至consul。

需要引入zyproject-api-service-system接口项目依赖。

1. 配置文件

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: zhouyu2001cloud
    url: jdbc:mysql://127.0.0.1:3306/zyprojectdb?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
  application:
    ## 系统管理服务
    name: zyproject-api-service-system
  cloud:
    config:
      discovery:
        service-id: config-server
        enabled: true
      profile: dev
      label: dev
    consul:
      host: 192.168.0.7
      discovery:
        hostname: 192.168.0.6
      port: 8500
server:
  port: 9001

logging:
  level:
    org.springframework.jdbc.core.JdbcTemplate: DEBUG

2. SystemService实现ISystemService

技术图片
package com.zyproject.service;

import com.zyproject.common.CodeEnum;
import com.zyproject.common.MyPager;
import com.zyproject.common.ResponseData;
import com.zyproject.dao.RoleDao;
import com.zyproject.dao.TreeDao;
import com.zyproject.dao.UserDao;
import com.zyproject.entity.RoleEntity;
import com.zyproject.entity.RoleTreefuncEntity;
import com.zyproject.entity.TreeEntity;
import com.zyproject.entity.UserEntity;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @program: zyproject
 * @description: 系统管理实现(客户端Feign同一服务只能定义一个,这里也把所有系统管理相关的服务放到一个 Service中)
 * @author: zhouyu(zhouyu629 @ qq.com)
 * @create: 2020-02-15
 **/
@RestController
public class SystemService implements ISystemService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private TreeDao treeDao;

    @Autowired
    private RoleDao roleDao;

    @GetMapping("/userLogin")
    @ApiOperation("用户登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user_code",value = "登录名",dataType = "String",required = true),
            @ApiImplicitParam(name = "password",value = "密码(32位小md5)",dataType = "String",required = true)
    })
    @Override
    public ResponseData userLogin(String user_code, String password) {
        UserEntity userEntity = userDao.userLogin(user_code,password);
        return ResponseData.out(userEntity!=null? CodeEnum.SUCCESS:CodeEnum.LOGINFAIL,userEntity);
    }

    @GetMapping("/findByLoginname")
    @ApiOperation("根据用户名查找用户信息")
    @Override
    public ResponseData findByLoginname(String login_name) {
        UserEntity userEntity = userDao.findByUsername(login_name);
        return ResponseData.out(userEntity!=null?CodeEnum.SUCCESS:CodeEnum.USERNOTEXIST,userEntity);
    }

    @GetMapping("/getAllTreeList")
    @ApiOperation("查找所有的菜单树")
    public List<TreeEntity> getAllTreeList() {
        return treeDao.getAllTreeList();
    }

    @GetMapping("/getTreeWithUserRight")
    @ApiOperation("根据用户获取权限菜单树")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userid",type = "int",value = "用户id")
    })
    @Override
    public ResponseData getTreeWithUserRight(@RequestParam(name = "userid") int userid) {
        List<TreeEntity> treeList = this.treeDao.getTreeWithUserRight(userid);
        return ResponseData.out(treeList!=null?CodeEnum.SUCCESS:CodeEnum.NORIGHT,treeList);
    }

    @GetMapping("/getTreeByTreeId")
    @ApiOperation("根据菜单ID获取对应的菜单实体")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "tree_id",value = "菜单编号",dataType = "int")
    )
    @Override
    public ResponseData getTreeByTreeId(@RequestParam int tree_id) {
        TreeEntity tree = this.treeDao.getTreeByTreeId(tree_id);
        return ResponseData.out(tree!=null?CodeEnum.SUCCESS:CodeEnum.NOTREE,tree);
    }

    @GetMapping("/getRoleByPage")
    @ApiOperation("分页获取角色列表(del_flag=0)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码(从1开始)", dataType = "int"),
            @ApiImplicitParam(name = "pagesize", value = "分页大小", dataType = "int")
    })
    @Override
    public ResponseData getRoleByPage(int page, int pagesize) {
        MyPager pager = this.roleDao.getRoleByPage(page,pagesize);
        return ResponseData.out(pager!=null?CodeEnum.SUCCESS:CodeEnum.NORECORDS,pager);
    }

    @GetMapping("/getRoleTreefuncByUserid")
    @ApiOperation("根据用户获取所有权限按钮")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user_id",value = "用户ID")
    })
    @Override
    public ResponseData getRoleTreefuncByUserid(int user_id) {
        List<RoleTreefuncEntity> list = this.treeDao.getRoleTreefuncByUserid(user_id);
        return ResponseData.out(CodeEnum.SUCCESS,list);
    }
}
View Code

3. Dao层,集成jdbctemplate,以UserDao为例

技术图片
package com.zyproject.dao;

import com.zyproject.entity.UserEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @program: zyproject
 * @description: 用户dao
 * @author: zhouyu(zhouyu629 @ qq.com)
 * @create: 2020-02-11
 **/
@Repository
public class UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    //用户登录
    public UserEntity userLogin(String user_code, String password){
        String sql = "SELECT * FROM tb_user WHERE login_code=? AND login_password=? AND del_flag=0";
        try {
            List<UserEntity> user = jdbcTemplate.query(sql,new Object[]{user_code,password},new BeanPropertyRowMapper(UserEntity.class));
            if(user!=null){
                //登录次数+1
                jdbcTemplate.update("UPDATE tb_user SET login_count=login_count+1 WHERE login_code=?",user_code);
            }
            return user!=null?user.get(0):null;
        }catch (Exception e){
            return null;
        }
    }

    //根据登录名,获取用户信息
    public UserEntity findByUsername(String login_name){
        String sql = "SELECT * FROM tb_user WHERE login_code=? AND del_flag=0";
        try {
            List<UserEntity> users = jdbcTemplate.query(sql,new BeanPropertyRowMapper(UserEntity.class),login_name);
            return users!=null?users.get(0):null;
        }catch (Exception ex){
            return null;
        }
    }
}
View Code

 

以上是关于微服务迁移记:公共层接口层和实现层搭建的主要内容,如果未能解决你的问题,请参考以下文章

vue“欺骗”ueditor,实现图片上传

springboot整合aop实现网站访问日志记录

Java Spring Boot如何实现业务逻辑层和资源库层?

Spring Boot 业务逻辑层

java中dao层和service层的区别是啥?

具有服务层和存储库层的 ASP.NET MVC,应该在哪里定义接口?