SAAS-HRM-day1

1. 项目功能架构

1.1 项目背景

  1. 找工作的人:

    现在社会竞争压力越来愈大,很多应届毕业生毕业后没法直接胜任某类工作,或者是一些已经工作的人慢慢丧失自己学习的能力,最终导致失业无法再次就业。

  2. 招聘单位

    虽然求职者非常多,但是很多人的能力达不到用人企业的要求,他们期望一招聘进来马上就能使用,所以需要对求职候选人进行培养筛选。

  3. 培训机构

    很多培训机构虽然有能力培训人才但是,市场能力比较差,找不到合适的学员,让他们通过培训能找到工作

正是由于以上三类场景,所以我们开发一个源码人力系统,让找工作的人,能够选择特定机构的课程学习,并参与平台发布的招聘,而且还能参与一些活动。 让招聘单位入驻进来发布岗位进行招聘,甚至委托培训机构培训合适的人才。对于配置机构可以发布课程,吸收学员来完成学习并通过收取学费获取商业价值。

1.2 功能模块

1.3 项目原型

2. 项目技术架构

2.1 技术栈

前后端分离模式,接口规范API:Swagger

  1. 前端:Nodejs、Npm、webpack、 vue.js、vuecli、Element UI。测试使用mock
  2. 后端:微服务架构:按照功能拆分N多个服务,每个服务可以独立技术选型,独立开发,独立部署,独立运维.,单个服务使用基于ssm的springboot,服务间通过spring cloud协调。测试接口使用postman

2.2 开发步骤

前后端分离模式下并行开发,多人协作!开发步骤如下:

  1. 需求分析
  2. 组建团队
  3. 开发
  4. 测试
  5. 上线
  6. 运维
  7. 开发其他项目

3. 开发环境

前端:

后端:

  1. idea
  2. maven 3.3.9
  3. jdk1.8
  4. windows10
  5. tomcat8
  6. mysql 5.6

4. 后端项目微服务原型搭建

4.1 idea指定maven配置

4.1.1 maven配置settings.xml

打开maven的安装目录/conf/settings.xml,修改三处地方:仓库地址、阿里云镜像、jdk1.8。我个人没有网络上网,就配置了第四处代理上网!

  1. 本地仓库路径
<localRepository>D:/soft/repository</localRepository>
  1. 阿里云镜像
    <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
    </mirror>
  1. jdk1.8
    <profile>    
        <id>jdk-1.8</id>    
            <activation>    
                <activeByDefault>true</activeByDefault>    
                <jdk>1.8</jdk>    
            </activation>    
    <properties>    
    <maven.compiler.source>1.8</maven.compiler.source>    
    <maven.compiler.target>1.8</maven.compiler.target>    
    <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>    
    </properties>    
    </profile>
  1. 代理上网
    <proxy>
      <id>myproxy</id>
      <active>true</active>
      <protocol>http</protocol>
      <username>xxx</username>
      <password>xxx</password>
      <host>172.16.6.254</host>
      <port>808</port>
      <nonProxyHosts>localhost|127.0.0.1</nonProxyHosts>
    </proxy>

4.1.2 idea配置maven

打开idea,点击File-->Other settings-->Default settings-->Build,Execution,Deployment-->Build Tools-->Maven-->修改三处地方:

  1. Maven home directory:maven的安装目录
  2. User settings file:指定安装目录下/conf/settings.xml
  3. Local repository:本地仓库地址

4.2 Maven结构

hrm_parent
  hrm_support_parent -->springcloud微服务支持模块
    hrm_eureka
    hrm_config_server
    hrm_zuul
  hrm_basic_parent -->基础模块
    hrm_basic_util 工具
  ......

模块名 端口
hrm_eureka 7001
hrm_config_server 8848
hrm_zuul 9527
management_parent(服务) 9001
...... 9999
hrm_主站 6001
...... 6999

4.3 环境搭建

4.3.1 顶级父工程(hrm_parent)

新建项目,名字为hrm_parent,删除src文件夹!在pom.xml中配置

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
        <springboot.version>2.0.5.RELEASE</springboot.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${springboot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

4.3.2 二级子模块(hrm_support_parent)

新建二级子模块,取名为hrm_support_parent,删除src文件夹

4.3.2.1 Eureka注册中心

  1. 新建项目

    在hrm_support_parent模块下新建三级子模块,取名为hrm_eureka_7001

  2. pom.xml导包

<!--web场景-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--测试场景-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--eureka服务端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
  1. 配置文件application.yml(不考虑集群)
spring:
  application:
    name: hrm-eureka
server:
  port: 7001
eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false # 是否要注册到eureka 自己本身就是eureka,无需注册
    fetchRegistry: false  # 表示是否从Eureka Server获取注册信息,自己是eureka服务端,无需获取注册信息
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 单机配置 效果同 http://localhost:7001/eureka
  1. 入口类
package cn.wangningbo.hrm;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServer7001Application {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer7001Application.class, args);
    }
}
  1. 测试

    启动EurekaServer7001Application入口类,浏览器访问地址http://localhost:7001/,能进去就代表成功

4.3.2.2 Zuul GateWay

  1. 新建项目

    在hrm_support_parent模块下新建三级子模块,取名为hrm_zuul_9527

  2. pom.xml导包

        <!-- springBoot支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- spring boot 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!-- Eureka 客户端依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- zuul支持-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
  1. 配置文件application.yml
server:
  port: 9527
spring:
  application:
    name: zuul-gateway
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka
  instance:
    instance-id: gateway-9527.com
    prefer-ip-address: true
  1. 入口类
package cn.wangningbo.hrm;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class Zuul9527Application {
    public static void main(String[] args) {
        SpringApplication.run(Zuul9527Application.class, args);
    }
}
  1. 测试

    先启动EurekaServer7001Application的主方法,然后Zuul9527Application入口类的主方法,浏览器访问网址http://localhost:7001/,查看zuul是否已经注册进去,注册进去就算做成功!

4.3.3 二级子模块(hrm_basic_parent)

新建二级子模块,取名为hrm_basic_parent,删除src文件夹

4.3.3.1 基础模块工具(hrm_basic_util)

这个三级子模块是用来存放一些封装的基础工具类

  1. 新建项目

    在二级子模块hrm_basic_util下新建三级子模块,取名为hrm_basic_util

  2. 工具类

query包下

package cn.wangningbo.hrm.query;


/**
 * 基础查询对象
 */
public class BaseQuery {
    //关键字
    private String keyword;
    //有公共属性-分页
    private Integer page = 1; //当前页
    private Integer rows = 10; //每页显示多少条

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

    public Integer getPage() {
        return page;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getRows() {
        return rows;
    }

    public void setRows(Integer rows) {
        this.rows = rows;
    }
}

5. 系统管理中心-后台搭建

新建二级子模块,我这里取名hrm_sysmanage_parent

在二级子模块hrm_sysmanage_parent下创建2个三级子模块名字分别为hrm_sysmanage_interface和hrm_sysmanage_service

hrm_sysmanage_interface:domain,query,client feign接口,(内部服务调用),fallbackFactory
hrm_sysmanage_service:controller,service,mapper

5.1 数据库和表准备

5.2 hrm_sysmanage_interface模块

5.2.1 步骤分析

  1. pom.xml导包

5.2.2 步骤实现

  1. pom.xml导包
 <!--不能直接依赖starter,有自动配置,而消费者是不需要额。-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>cn.wangningbo.hrm</groupId>
            <artifactId>hrm_basic_util</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

5.3 hrm_sysmanage_service模块

5.3.1 步骤分析

  1. pom.xml导包
  2. application.yml配置
  3. 入口类
  4. 测试

5.3.2 步骤实现

  1. pom.xml导包
<!--所有provider公共依賴-->
        <dependency>
            <groupId>cn.wangningbo.hrm</groupId>
            <artifactId>hrm_sysmanage_interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Eureka 客户端依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
  1. application.yml配置
server:
  port: 9001
spring:
  application:
    name: hrm-sysmanage
  datasource:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/hrm_sysmanage
      username: root
      password: apy06942
mybatis-plus:
  mapper-locations: classpath:cn/wangningbo/hrm/mapper/*Mapper.xml
  type-aliases-package: cn.wangningbo.hrm.domain,cn.wangningbo.hrm.query
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka
  instance:
    prefer-ip-address: true
  1. 入口类
package cn.wangningbo.hrm;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class SysManage9001Application {
    public static void main(String[] args) {
        SpringApplication.run(SysManage9001Application.class, args);
    }
}
  1. 测试

    先启动EurekaServer7001Application的主方法,再启动SysManage9001Application的主方法,查看是否注册到了eureka!注册到了即算是成功!

5.4 数据字典

5.4.1 步骤分析

  1. 表设计
  2. 集成mybatis-plus

5.4.2 步骤实现

5.4.2.1 表设计

5.4.2.2 集成mybatis-plus

在hrm_sysmanage_interface导包

        <!--不能全部引入mybatis-plus,这是要做数据库操作,这里是不需要的,只需引入核心包解决错误而已-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>2.2.0</version>
        </dependency>

        <!--客户端feign支持-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

在hrm_sysmanage_service导包

        <!--mybatis-plus支持-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>
        <!--数据库支持-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

5.4.2.3 生成api和service代码

步骤分析:

  1. 写一个代码生成器模块
  2. 导包
  3. 配置
  4. 准备代码
  5. 生成代码
  6. 修改模板
  7. 入口类
  8. 测试

步骤实现

  1. 写一个代码生成器模块

    我这里取名为hrm_mybatisplus_gen

  2. 导包

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

        <!--模板引擎-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
  1. 配置

mybatisplus-sysmanage.properties

#代码放到哪儿
OutputDir=D:\\Java20190329\\workspace\\java6webSpringCloud\\hrm_parent\\hrm_sysmanage_parent\\hrm_sysmanage_service\\src\\main\\java
#mapper.xml SQL映射文件目录
OutputDirXml=D:\\Java20190329\\workspace\\java6webSpringCloud\\hrm_parent\\hrm_sysmanage_parent\\hrm_sysmanage_service\\src\\main\\resources
#接口路径
InterfaceOutputDirBase=D:\\Java20190329\\workspace\\java6webSpringCloud\\hrm_parent\\hrm_sysmanage_parent\\hrm_sysmanage_service\\src\\main\\java
#设置作者
author=wangningbo
#自定义包路径
parent=cn.wangningbo.hrm

#数据库连接信息
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///hrm_sysmanage
jdbc.user=root
jdbc.pwd=apy06942
  1. 准备代码模板

模板放在了resources下的templates目录下.我这里准备了4个模板

client.java.vm

package cn.wangningbo.hrm.client;

import ${package.Entity}.${entity};
import cn.wangningbo.hrm.query.${entity}Query;
import cn.wangningbo.hrm.util.AjaxResult;
import cn.wangningbo.hrm.util.PageList;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author ${author}
 * @since ${date}
 */
@FeignClient(value = "ZUUL-GATEWAY", configuration = FeignClientsConfiguration.class,
        fallbackFactory = ${entity}ClientHystrixFallbackFactory.class)
@RequestMapping("/user/${table.entityPath}" )
public interface ${entity}Client {
    /**
     * 保存和修改公用的
     * @param ${table.entityPath} 传递的实体
     * @return Ajaxresult转换结果
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    AjaxResult save(${entity} ${table.entityPath});

    /**
     * 删除对象信息
     * @param id
     * @return
     */
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
    AjaxResult delete(@PathVariable("id" ) Integer id);

    //获取用户
    @RequestMapping("/{id}" )
        ${entity} get(@RequestParam(value = "id", required = true) Long id);


    /**
     * 查看所有
     * @return
     */
    @RequestMapping("/list" )
    public List<${entity}> list();

    /**
     * 分页查询数据
     *
     * @param query 查询对象
     * @return PageList 分页对象
     */
    @RequestMapping(value = "/json", method = RequestMethod.POST)
    PageList<${entity}> json(@RequestBody ${entity}Query query);
}

ClientHystrixFallbackFactory.java.vm

package cn.wangningbo.hrm.client;

import ${package.Entity}.${entity};
import cn.wangningbo.hrm.query.${entity}Query;
import cn.wangningbo.hrm.util.AjaxResult;
import cn.wangningbo.hrm.util.PageList;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author ${author}
 * @since ${date}
 */
@Component
public class ${entity}ClientHystrixFallbackFactory implements FallbackFactory<${entity}Client> {

    @Override
    public ${entity}Client create(Throwable throwable) {
        return new ${entity}Client() {
            @Override
            public AjaxResult save(${entity} ${table.entityPath}) {
                return null;
            }

            @Override
            public AjaxResult delete(Integer id) {
                return null;
            }

            @Override
            public ${entity} get(Long id) {
                return null;
            }

            @Override
            public List<${entity}> list() {
                return null;
            }

            @Override
            public PageList<${entity}> json(${entity}Query query) {
                return null;
            }
        };
    }
}

Controller.java.vm

package

    ${package.Controller};

import ${package.Service}.${table.serviceName};
import ${package.Entity}.${entity};
import cn.wangningbo.hrm.query.${entity}Query;
import cn.wangningbo.hrm.util.AjaxResult;
import cn.wangningbo.hrm.util.PageList;
import com.baomidou.mybatisplus.plugins.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author ${author}
 * @since ${date}
 */
@RestController
@RequestMapping("/${table.entityPath}" )
public class ${entity}Controller {
    @Autowired
    public ${table.serviceName} ${table.entityPath}Service;

    /**
     * 保存和修改公用的
     * @param ${table.entityPath} 传递的实体
     * @return Ajaxresult转换结果
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public AjaxResult save(@RequestBody ${entity} ${table.entityPath}) {
        try {
            if (${table.entityPath}.getId() != null){
                    ${table.entityPath}Service.updateById(${table.entityPath});
            }else{
                    ${table.entityPath}Service.insert(${table.entityPath});
            }
            return AjaxResult.me();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setMessage("保存对象失败!" + e.getMessage());
        }
    }

    /**
    * 删除对象信息
    * @param id
    * @return
    */
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public AjaxResult delete(@PathVariable("id" ) Long id) {
        try {
                ${table.entityPath}Service.deleteById(id);
            return AjaxResult.me();
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setMessage("删除对象失败!" + e.getMessage());
        }
    }

    //获取用户
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public ${entity} get(@PathVariable("id" ) Long id) {
        return ${table.entityPath}Service.selectById(id);
    }


    /**
    * 查看所有的员工信息
    * @return
    */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public List<${entity}> list() {

        return ${table.entityPath}Service.selectList(null);
    }


    /**
    * 分页查询数据
    *
    * @param query 查询对象
    * @return PageList 分页对象
    */
    @RequestMapping(value = "/json", method = RequestMethod.POST)
    public PageList<${entity}> json(@RequestBody ${entity}Query query) {
        Page<${entity}> page = new Page<${entity}>(query.getPage(), query.getRows());
        page = ${table.entityPath}Service.selectPage(page);
        return new PageList<${entity}>(page.getTotal(), page.getRecords());
    }
}

query.java.vm

package cn.wangningbo.hrm.query;


/**
 * @author ${author}
 * @since ${date}
 */
public class ${table.entityName}Query extends BaseQuery {
}
  1. 生成代码

准备生成代码所需要的类

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.*;

/**
 * Created by wangningbo on 2019/08/30
 */
public class GenteratorCode {

    public static void main(String[] args) throws InterruptedException {
        //用来获取Mybatis-Plus.properties文件的配置信息
        ResourceBundle rb = ResourceBundle.getBundle("mybatisplus-sysmanage");
        AutoGenerator mpg = new AutoGenerator();
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(rb.getString("OutputDir"));
        gc.setFileOverride(true);
        gc.setActiveRecord(true);// 开启 activeRecord 模式
        gc.setEnableCache(false);// XML 二级缓存
        gc.setBaseResultMap(true);// XML ResultMap
        gc.setBaseColumnList(false);// XML columList
        gc.setAuthor(rb.getString("author"));
        mpg.setGlobalConfig(gc);
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setTypeConvert(new MySqlTypeConvert());
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername(rb.getString("jdbc.user"));
        dsc.setPassword(rb.getString("jdbc.pwd"));
        dsc.setUrl(rb.getString("jdbc.url"));
        mpg.setDataSource(dsc);
        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setTablePrefix(new String[] { "t_" });// 此处可以修改为您的表前缀
        strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
        strategy.setInclude(new String[]{"t_systemdictionary","t_systemdictionaryitem"}); // 需要生成的表
        mpg.setStrategy(strategy);
        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent(rb.getString("parent"));
        pc.setController("web.controller");
        pc.setService("service");
        pc.setServiceImpl("service.impl");
        pc.setEntity("domain");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 注入自定义配置,可以在 VM 中使用 cfg.abc 【可无】
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-rb");
                this.setMap(map);
            }
        };

        List<FileOutConfig> focList = new ArrayList<FileOutConfig>();


        // 调整 xml 生成目录演示
        focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return rb.getString("OutputDirXml")+ "/cn/wangningbo/hrm/mapper/" + tableInfo.getEntityName() + "Mapper.xml";
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
        // 调整 domain 生成目录演示
        focList.add(new FileOutConfig("/templates/controller.java.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return rb.getString("OutputDir")+ "/cn/wangningbo/hrm/web/controller/" + tableInfo.getEntityName() + "Controller.java";
            }
        });
        //=====================接口里面存放==================================//
        // 调整 domain 生成目录演示
        focList.add(new FileOutConfig("/templates/entity.java.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return rb.getString("InterfaceOutputDirBase")+ "/cn/wangningbo/hrm/domain/" + tableInfo.getEntityName() + ".java";
            }
        });
        // 调整 query 生成目录演示
        focList.add(new FileOutConfig("/templates/query.java.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return rb.getString("InterfaceOutputDirBase")+ "/cn/wangningbo/hrm/query/" + tableInfo.getEntityName() + "Query.java";
            }
        });
        // 调整 client 生成目录演示
        focList.add(new FileOutConfig("/templates/client.java.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return rb.getString("InterfaceOutputDirBase")+ "/cn/wangningbo/hrm/client/" + tableInfo.getEntityName() + "Client.java";
            }
        });
        // 调整 ClientHystrixFallbackFactory 生成目录演示
        focList.add(new FileOutConfig("/templates/ClientHystrixFallbackFactory.java.vm") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return rb.getString("InterfaceOutputDirBase")+ "/cn/wangningbo/hrm/client/" + tableInfo.getEntityName() + "ClientHystrixFallbackFactory.java";
            }
        });
        //=====================接口里面存放==================================//

        // 自定义模板配置,可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改,
        // 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置,也可以自定义模板名称
        TemplateConfig tc = new TemplateConfig();
        tc.setService("/templates/service.java.vm");
        tc.setServiceImpl("/templates/serviceImpl.java.vm");
        tc.setEntity(null);
        tc.setMapper("/templates/mapper.java.vm");
        tc.setController(null);
        tc.setXml(null);
        // 如上任何一个模块如果设置 空 OR Null 将不生成该模块。
        mpg.setTemplate(tc);

        // 执行生成
        mpg.execute();
    }

}
  1. 修改模板
  2. 入口类

注意注解@MapperScan("cn.wangningbo.hrm.mapper")

hrm_sysmanage_service的入口类

package cn.wangningbo.hrm;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
@MapperScan("cn.wangningbo.hrm.mapper")
public class SysManage9001Application {
    public static void main(String[] args) {
        SpringApplication.run(SysManage9001Application.class, args);
    }
}
  1. 测试

    先启动EurekaServer7001Application的主方法,再启动SysManage9001Application的主方法,然后查看是否注册到了注册中心,浏览器访问地址:http://localhost:9001//systemdictionary/list是否可以拿到数据!

5.4.2.4 网关配置

  1. 配置

在hrm_zuul_9527的配置文件中加入下面的配置

zuul:
  routes:
    sysmanage.serviceId: hrm-sysmanage # 服务名
    sysmanage.path: /sysmanage/** # 把myUser打头的所有请求都转发给user-provider
  ignored-services: "*" # 所有服务都不允许以服务名来访问
  prefix: "/services" # 加一个统一前缀
  retryable: true # 是否重试
ribbon:
  ConnectTimeout: 250 # 连接超时时间(ms)
  ReadTimeout: 2000 # 通信超时时间(ms)
  OkToRetryOnAllOperations: true # 是否对所有操作重试
  MaxAutoRetriesNextServer: 2 # 同一服务不同实例的重试次数
  MaxAutoRetries: 1 # 同一实例的重试次数
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMillisecond: 3000 # 熔断超时时长:3000ms
  1. 测试

    启动EurekaServer7001Application,再启动Zuul9527Application,最后启动

    打开浏览器,按照配置文件的网关配置的方式访问资源http://localhost:9527/services/sysmanage/systemdictionary/list,这是通过网关访问资源的,拿到了就是成功!

5.5 接口测试工具postman

使用postman访问网关的controller层

略过

5.6 接口文档Swagger

由于要生成接口文档,这样前段看着才方便,所以我这里是使用Swagger

5.6.1 本项目hrm_sysmanage_service配置

5.6.1.1 步骤分析

  1. 导包
  2. 配置类
  3. 测试

5.6.1.2 步骤实现

  1. 导包
<!--引入swagger支持-->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>
  1. 配置类
package cn.wangningbo.hrm.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class Swagger2 {
 
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //对外暴露服务的包,以controller的方式暴露,所以就是controller的包.
                .apis(RequestHandlerSelectors.basePackage("cn.wangningbo.hrm.web.controller"))
                .paths(PathSelectors.any())
                .build();
    }


    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("人力资源平台服务api")
                .description("人力资源平台服务接口文档说明")
                .contact(new Contact("wangningbo", "", "wang_ning_bo163@163.com"))
                .version("1.0")
                .build();
    }

}
  1. 测试

    依次启动EurekaServer7001Application、Zuul9527Application、SysManage9001Application。

    浏览器访问地址http://127.0.0.1:9001/swagger-ui.html

5.6.2 网关配置

一个一个项目的配置swagger太过于麻烦,我如果有很多个项目在配置就会很难受前端开发每次都要记录每个服务ip不好,期望只记忆网关ip就ok,需要做配置!所有我要在网关里面配置!

5.6.2.1 步骤分析

网关9527里面

  1. 导包
  2. 配置
  3. 测试

5.6.2.1 步骤实现

  1. 导包
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
  1. 配置
package cn.wangningbo.hrm.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("分布式人力资源系统")
                .description("人力资源系统接口文档说明")
                .termsOfServiceUrl("http://www.wangningbo.cn")
                .contact(new Contact("wangningbo", "", "wang_ning_bo163@163.com"))
                .version("1.0")
                .build();
    }

}
package cn.wangningbo.hrm.config;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;

@Component
@Primary
public class DocumentationConfig implements SwaggerResourcesProvider {
    @Override
    public List<SwaggerResource> get() {
        List resources = new ArrayList<>();
        //通过网关访问服务地址
        resources.add(swaggerResource("系统管理", "/services/sysmanage/v2/api-docs", "2.0"));
        //如果有多个项目模块需要配置,就在后面加就行
//        resources.add(swaggerResource("系统管理2", "/services/sysmanage/v2/api-docs", "2.0"));
//        resources.add(swaggerResource("系统管理3", "/services/sysmanage/v2/api-docs", "2.0"));
        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location, String version) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion(version);
        return swaggerResource;
    }
}
  1. 测试

    启动项目

    浏览器访问http://127.0.0.1:9527/swagger-ui.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容