springcloud-概述及微服务搭建【springcloud】

1 微服务的概念

微服务(micro service),是一种架构风格,它将一个复杂的应用拆分成多个独立自治的服务,服务与服务间通过松耦合的形式交互。这些服务都可以单独的开发,测试,部署,运行;相互协作,更好完成原来大的业务系统的所有功能。

2 微服务的特点,优点和缺点

1)特点
解耦:服务做了拆分,相互影响会大大降低,符合软件设计的低耦合原则。

组件化:每个服务都相当于一个独立的组件,可以进行独立升级和扩展,可以被重复使用,节省人力成本。
业务能力强:职责明确,更专注于某一个业务

自治:一个微服务就是一个独立的实体,它可以独立部署、升级,服务与服务之间通过REST等形式的标准接口进行通信,并且一个微服务实例可以被替换成另一种实现,而对其它的微服务不产生影响。

敏捷性: 微服务可以敏捷开发(迭代)非常适合。 中国扶贫办->中国移动(华为,亚信)-> 精简版上线30天上线->每隔2-3迭代一个新功能(修复旧版本的BUG),直到整个10个月全部完成
2)优点
易于开发和部署(单个项目)
启动快
局部更新,对整体影响很小
技术不受限制
按需求伸缩

devops(develop开发 operations运维) 促进开发,运维和测试(质检QA)的协作

DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。
它是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

3)缺点
复杂度高:微服务间通过REST(restful)、RPC(dubbo)等形式交互,需要考虑被调用方故障、过载、消息丢失等,分布式锁,分布式事务
运维复杂:需要一个设计良好的监控系统对各个微服务的运行状态进行监控。
影响性能:微服务的间通过REST、RPC等形式进行交互,通信的时延会受到较大的影响

3 分布式服务系统框架演变

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

3.1 单一应用架构

当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。

3.2 垂直应用架构

当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,提升效率的方法之一是将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。

3.3 分布式服务架构

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式服务框架(RPC(remote procedure call))是关键。

3.4 流动计算架构

当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键。
在这里插入图片描述

4 springcloud简介

英文官网: https://spring.io/projects/spring-cloud
中文官网: https://www.springcloud.cc/
微服务架构集大成者,云计算最佳业务实践。Spring Cloud 为开发者提供了工具来快速构建分布式系统中的一些常见模式(例如配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话,集群状态)。分布式系统的协调导致了样板模式,使用 Spring Cloud 开发人员可以快速建立实现这些模式的服务和应用程序。它们在任何分布式环境中都能很好地工作,包括开发人员自己的笔记本电脑、裸机数据中心以及 Cloud Foundry 等托管平台。

5 springcoud特征

分布式/版本化配置
服务注册和发现
路由
服务到服务调用
负载均衡
断路器
全局锁
领导选举和集群状态
分布式消息传递

6 springcloud的主要组件,体系架构及版本号

在这里插入图片描述
服务注册中心(服务注册和发现)
eureka:一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。
nacos:Nacos 致力于帮助您发现、配置和管理微服务。

服务配置中心
springcloud config:配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git以及Subversion。
nacos:Nacos 致力于帮助您发现、配置和管理微服务。
服务路由(网关)
zuul:Zuul 是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。
gateway:该项目提供了一个库,用于在 Spring WebFlux 之上构建 API 网关。Spring Cloud Gateway 旨在提供一种简单而有效的方式来路由到 API,并为它们提供横切关注点,例如:安全性、监控/指标和弹性。
服务熔断器
hystrix:熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
sentinel:流量控制和服务降级,断路和系统自适应保护
消息队列(异步)
kafka:kafka是由apache软件基金会开发的一个开源流处理框架,由JAVA和scala语言编写。是一个高吞吐量的分布式的发布和订阅消息的一个系统。Kafka® 用于构建实时的数据管道和流式的app.它可以水平扩展,高可用,速度快,并且已经运行在数千家公司的生产环境。
服务到服务调用(同步)
ribbon:提供云端负载均衡,有多种负载均衡策略可供选择,可配合服务发现和断路器使用
open feign:Feign是一种声明式、模板化的HTTP客户端。

版本号:
https://github.com/spring-projects/spring-cloud/wiki
在这里插入图片描述
GA = General Availability,通用版本 一般可用性(发布); 应该非常稳定,功能齐全
SR = Server RELEASE 服务发布版本(主要版本之后的后续维护版本-RELEASE)
RC = Release Candidate 候选版本

7 微服务规划父子项目搭建

             父子项目(以springboot为基础)
              父:     springcloud_demo_20220216(方便jar包管理 type='pom')
                           注册中心eureka:
                             子项目(单机版注册中心-独立模式): eureka_registry (14110)
                                  子子项目(HA(High Available)注册中心):
                                                registry_a(14111)
                                                registry_b(14112)
                                                registry_c(14113)
                            nacos     默认端口:8848(独立项目之外的)
		 nacos 集群  3台主机及端口为 192.168.170.41:18841  192.168.170.42:18842  192.168.170.43:18843 
                            微服务:(springboot+mybatis):
                                  子项目micro_services(统一管理微服务的jar包)
                                     子子项目:
                                          订单管理(3个项目,目的讲解ribbon和open feign负载均衡)
                                            order_server_a(14121) 订单管理1(真正开发,开发一份代码,部署3个服务器)
                                            order_server_b(14122) 订单管理2
                                            order_server_c(14123) 订单管理3
                                          商品管理(讲解ribbon)
                                            goods_server_ribbon (14131)   
                                          sns管理(讲解openfeign)
                                            sns_server_feign (14132)
                                          营销活动管理(讲解ribbon的hystrix路由熔断)
                                            market_server_ribbon_hystrix(14141)
                                            market_server_openfeign_hystrix(14142)
                                          会员服务管理(讲解feign的hystrix路由熔断)
                                            member_server_ribbon_sentinel(14143)
				 member_server_openfeign_sentinel(14144)
                           单点登录:sso_server(14188)
    member_server_feign_sentinel(14144)
                           路由过滤中心 
                                   子项目:   zuul_server(14151)
                                   子项目: gateway_server(14152)
                           配置中心 
                                   子项目: config_server(14160)
                                   nacos     默认端口:8848(独立项目之外的)

8 搭建父子工程

pom.xml的properties配置:

<properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <spring-boot.version>2.3.4.RELEASE</spring-boot.version>
        <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.3.RELEASE</spring-cloud-alibaba.version>
        <mybatis-plus.version>3.4.0</mybatis-plus.version>
        <mybatis-plus-extension.version>3.4.0</mybatis-plus-extension.version>
        <hutool.version>5.7.18</hutool.version>
        <swagger.fox.version>3.0.0</swagger.fox.version>
        <swagger-spring-boot>2.0.2.RELEASE</swagger-spring-boot>
        <nacos.version>2.0.3</nacos.version>
        <fastjson.version>1.2.78</fastjson.version>
        <mysql.version>5.1.10</mysql.version>
        <lombok.version>1.18.22</lombok.version>
        <druid.version>1.2.8</druid.version>
        <pagehelper.version>1.4.1</pagehelper.version>

    </properties>

pom.xml的dependencyManagement配置:

<dependencyManagement>
          <dependencies>
              <!-- spring boot 依赖 -->
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-dependencies</artifactId>
                  <version>${spring-boot.version}</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
              <!-- spring cloud 依赖 -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-dependencies</artifactId>
                  <version>${spring-cloud.version}</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
              <!-- spring cloud alibaba 依赖 -->
              <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>
              <!--springboot整合mybatis包-->
<!--              <dependency>-->
<!--                  <groupId>org.mybatis.spring.boot</groupId>-->
<!--                  <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!--                  <version>2.2.1</version>-->
<!--              </dependency>-->
              <!--mybatis-plus-->
              <dependency>
                  <groupId>com.baomidou</groupId>
                  <artifactId>mybatis-plus-boot-starter</artifactId>
                  <version>${mybatis-plus.version}</version>
              </dependency>
              <!--mybatis-plus扩展包-->
            <!--  <dependency>
                  <groupId>com.baomidou</groupId>
                  <artifactId>mybatis-plus-extension</artifactId>
                  <version>${mybatis-plus-extension.version}</version>
              </dependency>-->
              <!--简化entity写法包-->
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <version>${lombok.version}</version>
              </dependency>
              <!-- mysql驱动包-->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>${mysql.version}</version>
              </dependency>
              <!--测试包-->
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-test</artifactId>
                  <version>${spring-boot.version}</version>
                  <scope>test</scope>
              </dependency>
              <!--druid 连接池  其他常用连接池:dbcp  c3p0  proxool  -->
              <dependency>
                  <groupId>com.alibaba</groupId>
                  <artifactId>druid</artifactId>
                  <version>${druid.version}</version>
              </dependency>
              <dependency>
                  <groupId>com.alibaba</groupId>
                  <artifactId>druid-spring-boot-starter</artifactId>
                  <version>${druid.version}</version>
              </dependency>
              <!-- 分页插件pagehelper -->
              <dependency>
                  <groupId>com.github.pagehelper</groupId>
                  <artifactId>pagehelper-spring-boot-starter</artifactId>
                  <version>${pagehelper.version}</version>
              </dependency>
              <!-- 分页插件pagehelper -->
              <!-- swagger2 -->
            <!--  <dependency>
                  <groupId>io.springfox</groupId>
                  <artifactId>springfox-swagger2</artifactId>
                  <version>${swagger.fox.version}</version>
              </dependency>
              <dependency>
                  <groupId>io.springfox</groupId>
                  <artifactId>springfox-swagger-ui</artifactId>
                   <version>${swagger.fox.version}</version>
              </dependency>-->
              <!-- swagger-spring-boot-starter -->
              <dependency>
                  <groupId>com.spring4all</groupId>
                  <artifactId>swagger-spring-boot-starter</artifactId>
                  <version>${swagger-spring-boot}</version>
              </dependency>
              <!-- fastjson -->
              <dependency>
                  <groupId>com.alibaba</groupId>
                  <artifactId>fastjson</artifactId>
                  <version>${fastjson.version}</version>
              </dependency>
          </dependencies>
    </dependencyManagement>    

知识点:
dependencyManagement和dependencies区别:

dependencies:自动引入声明在dependencies里的所有依赖,并默认被所有的子项目继承。如果项目中不写依赖项,则会从父项目继承(属性全部继承)声明在父项目dependencies里的依赖项。

dependencyManagement里只是声明依赖, 子项目按需依赖。只有在子项目中写了该依赖项,并且没有指定具体版本,才会从父项目中继承该项,并且version和scope都读取自父pom。 如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

dependency中type属性:
引入包的类型 默认为jar 当为pom时,作用为需要引入很多jar包的时候会导致pom.xml过大,可以定义一个父项目,通过type=pom把父项目的所有包都可以引入,选择性使用。

dependency中scope属性:
打包范围,有以下选项:

compile, 缺省值,适用于所有阶段,会随着项目一起发布。在编译和打包时都会将依赖存储进去
provided,类似compile,期望JDK、容器或使用者会提供这个依赖。
runtime, 在运行时使用,如JDBC驱动,适用运行和测试阶段。
test 只在测试时使用,用于编译和运行测试代码。不会随项目发布。

打包命令示例: mvn package -Dmaven.test.skip=true

system, 类似provided,需要显式提供包含依赖的jar,Maven不会在Repository中查找它。
import, 引入一个父类项目pom,选择性的继承,达到类似parent标签的作用,解决了单继承问题

解决工程默认java编译版本:

<plugin>
<!--org\apache\maven\plugins\maven-compiler-plugin\3.6.0-->
 <artifactId>maven-compiler-plugin</artifactId>
    <version>3.6.0</version>
    <inherited>true</inherited>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
    </configuration>
</plugin>                              

9 编写一个微服务工程

9.1,数据库表及数据:

CREATE TABLE tb_order (
id int(11) PRIMARY key NOT NULL AUTO_INCREMENT COMMENT '订单id' ,
member_id int(10) NOT NULL ,
shop_id int(10) NULL DEFAULT NULL ,
group_promotion_id int(10) NULL DEFAULT NULL COMMENT '拼团活动ID' ,
coupon_id int(10) NULL DEFAULT NULL COMMENT '促销活动ID' ,
order_sn varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '订单编号' ,
member_username varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户帐号' ,
total_amount decimal(10,2) NULL DEFAULT NULL COMMENT '订单总金额'
);
INSERT INTO  tb_order (id, member_id, shop_id, group_promotion_id, coupon_id, order_sn, member_username, total_amount) VALUES ('1', '1', '1', '1', '1', 'order001', 'admin1', '101.00');
INSERT INTO  tb_order (id, member_id, shop_id, group_promotion_id, coupon_id, order_sn, member_username, total_amount) VALUES ('2', '1', '1', '1', '1', 'order002', 'admin2', '102.00');
INSERT INTO  tb_order (id, member_id, shop_id, group_promotion_id, coupon_id, order_sn, member_username, total_amount) VALUES ('3', '1', '1', '1', '1', 'order003', 'admin3', '103.00');

9.2 ,创建一个micro_services引入jar

(父类jar管理项目):

<dependencies>
    <!--springboot  web包-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--springboot整合druid包-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
    </dependency>
    <!--mysql驱动包-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!--lombok 简化实体写法包-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <!--mybatisplus整合springboot的包-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
    </dependency>
    <!-- swagger-spring-boot-starter -->
    <dependency>
        <groupId>com.spring4all</groupId>
        <artifactId>swagger-spring-boot-starter</artifactId>
    </dependency>
</dependencies>

9.3,创建子项目,配置application.yml:

#当前服务端口号
server:
  port: 14121
#  servlet:
#    #配置上下文对象  访问的项目名称
#    context-path: /ordera
#阿里druid连接池配置
spring:
  datasource:
    druid:
      url: jdbc:mysql://localhost:3306/db_qy141?useUnicode=true&characterEncoding=utf8
      username: root
      password: root
      initial-size: 5
      max-active: 20
      min-idle: 10
      max-wait: 10
mybatis-plus:
  # mapper.xml配置
  mapper-locations: classpath:mapper/*.xml
  configuration:
    #控制台日志输出配置
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  #别名包配置
  type-aliases-package: com.aaa.os.entity
#swagger配置
swagger:
  base-package: com.aaa.os.controller
  title: "电商项目-订单模块-订单swagger"
  description: "描述"
  version: "3.0"
  contact:
    name: "AAA"
    email: "test@163.com"
    url: "https://www.baidu.com"
  terms-of-service-url: "服务条款:https://www.baidu.com"

9.4,编写代码(实体和业务分开)

使用EasyCode自动生成(省略)

分页插件配置(了解):

package com.aaa.os.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @ fileName:MyBatisPlusPageConfig
 * @ description:
 * @ author:zhz
 * @ createTime:2022/2/17 9:34
 * @ version:1.0.0
 */
@Configuration
public class MyBatisPlusPageConfig {
    /**
     *  最新版 mp分页插件配置
     * @return
     */
    @Bean //<bean id=mybatisPlusInterceptor class='com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor'
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

测试:

10 整合swagger

最外层父项目需要引入:
       <swagger-spring-boot>2.0.2.RELEASE</swagger-spring-boot>
       <!-- swagger-spring-boot-starter -->
         <dependency>
             <groupId>com.spring4all</groupId>
             <artifactId>swagger-spring-boot-starter</artifactId>
             <version>${swagger-spring-boot}</version>
         </dependency>
micro_services 引入:
         <!-- swagger-spring-boot-starter -->
   <dependency>
       <groupId>com.spring4all</groupId>
       <artifactId>swagger-spring-boot-starter</artifactId>
   </dependency>

10.2 application.yml配置

#swagger配置
swagger:
  base-package: com.aaa.order.controller
  title: "swagger标题"
  description: "描述"
  version: "3.0"
  contact:
    name: "AAA"
    email: "test@163.com"
    url: "https://www.baidu.com"
  terms-of-service-url: "服务条款:https://www.baidu.com"

10.3 启动类配置

@EnableSwagger2 //开启swagger

10.4 测试

http://localhost:xxxx(port)/swagger-ui/index.html

easycode模板


dao\

##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Dao"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/dao"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}dao;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})表数据库访问层
 *
 * @author $!author
 * @since $!time.currTime()
 */
public interface $!{tableName} {

    /**
     * 通过ID查询单条数据
     *
     * @param $!pk.name 主键
     * @return 实例对象
     */
    $!{tableInfo.name} queryById($!pk.shortType $!pk.name);

    /**
     * 查询指定行数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条件
     * @param pageable         分页对象
     * @return 对象列表
     */
    List<$!{tableInfo.name}> queryAllByLimit($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 统计总行数
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条件
     * @return 总行数
     */
    long count($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 新增数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 影响行数
     */
    int insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 批量新增数据(MyBatis原生foreach方法)
     *
     * @param entities List<$!{tableInfo.name}> 实例对象列表
     * @return 影响行数
     */
    int insertBatch(@Param("entities") List<$!{tableInfo.name}> entities);

    /**
     * 批量新增或按主键更新数据(MyBatis原生foreach方法)
     *
     * @param entities List<$!{tableInfo.name}> 实例对象列表
     * @return 影响行数
     * @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参
     */
    int insertOrUpdateBatch(@Param("entities") List<$!{tableInfo.name}> entities);

    /**
     * 修改数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 影响行数
     */
    int update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 通过主键删除数据
     *
     * @param $!pk.name 主键
     * @return 影响行数
     */
    int deleteById($!pk.shortType $!pk.name);

}


entity


##引入宏定义
$!{define.vm}

##使用宏定义设置回调(保存位置与文件后缀)
#save("/entity", ".java")

##使用宏定义设置包后缀
#setPackageSuffix("entity")

##使用全局变量实现默认包导入
$!{autoImport.vm}
import java.io.Serializable;

##使用宏定义实现类注释信息
#tableComment("实体类")
public class $!{tableInfo.name} implements Serializable {
    private static final long serialVersionUID = $!tool.serial();
#foreach($column in $tableInfo.fullColumn)
    #if(${column.comment})/**
     * ${column.comment}
     */#end

    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end

#foreach($column in $tableInfo.fullColumn)
##使用宏定义实现get,set方法
#getSetMethod($column)
#end

}


mapper


##引入mybatis支持
$!{mybatisSupport.vm}

##设置保存名称与保存位置
$!callback.setFileName($tool.append($!{tableInfo.name}, "Dao.xml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mapper"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="$!{tableInfo.savePackageName}.dao.$!{tableInfo.name}Dao">

    <resultMap type="$!{tableInfo.savePackageName}.entity.$!{tableInfo.name}" id="$!{tableInfo.name}Map">
#foreach($column in $tableInfo.fullColumn)
        <result property="$!column.name" column="$!column.obj.name" jdbcType="$!column.ext.jdbcType"/>
#end
    </resultMap>

    <!--查询单个-->
    <select id="queryById" resultMap="$!{tableInfo.name}Map">
        select
          #allSqlColumn()

        from $!tableInfo.obj.name
        where $!pk.obj.name = #{$!pk.name}
    </select>

    <!--查询指定行数据-->
    <select id="queryAllByLimit" resultMap="$!{tableInfo.name}Map">
        select
          #allSqlColumn()

        from $!tableInfo.obj.name
        <where>
#foreach($column in $tableInfo.fullColumn)
            <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
                and $!column.obj.name = #{$!column.name}
            </if>
#end
        </where>
        limit #{pageable.offset}, #{pageable.pageSize}
    </select>

    <!--统计总行数-->
    <select id="count" resultType="java.lang.Long">
        select count(1)
        from $!tableInfo.obj.name
        <where>
#foreach($column in $tableInfo.fullColumn)
            <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
                and $!column.obj.name = #{$!column.name}
            </if>
#end
        </where>
    </select>

    <!--新增所有列-->
    <insert id="insert" keyProperty="$!pk.name" useGeneratedKeys="true">
        insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)
        values (#foreach($column in $tableInfo.otherColumn)#{$!{column.name}}#if($velocityHasNext), #end#end)
    </insert>

    <insert id="insertBatch" keyProperty="$!pk.name" useGeneratedKeys="true">
        insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)
        values
        <foreach collection="entities" item="entity" separator=",">
        (#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($velocityHasNext), #end#end)
        </foreach>
    </insert>

    <insert id="insertOrUpdateBatch" keyProperty="$!pk.name" useGeneratedKeys="true">
        insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)
        values
        <foreach collection="entities" item="entity" separator=",">
            (#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($velocityHasNext), #end#end)
        </foreach>
        on duplicate key update
        #foreach($column in $tableInfo.otherColumn)$!column.obj.name = values($!column.obj.name)#if($velocityHasNext),
        #end#end

    </insert>

    <!--通过主键修改数据-->
    <update id="update">
        update $!{tableInfo.obj.name}
        <set>
#foreach($column in $tableInfo.otherColumn)
            <if test="$!column.name != null#if($column.type.equals("java.lang.String")) and $!column.name != ''#end">
                $!column.obj.name = #{$!column.name},
            </if>
#end
        </set>
        where $!pk.obj.name = #{$!pk.name}
    </update>

    <!--通过主键删除-->
    <delete id="deleteById">
        delete from $!{tableInfo.obj.name} where $!pk.obj.name = #{$!pk.name}
    </delete>

</mapper>


service


##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Service"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import com.aaa.common.vo.QueryPage;
import com.github.pagehelper.PageInfo;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})表服务接口
 *
 * @author $!author
 * @since $!time.currTime()
 */
public interface $!{tableName} {

    /**
     * 通过ID查询单条数据
     *
     * @param $!pk.name 主键
     * @return 实例对象
     */
    $!{tableInfo.name} queryById($!pk.shortType $!pk.name);

    /**
     * 分页查询
     *
     * @param queryPage 筛选条件
     * @return 查询结果
     */
    PageInfo queryByPage(QueryPage<$!{tableInfo.name}> queryPage);

    /**
     * 新增数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 实例对象
     */
    $!{tableInfo.name} insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 修改数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 实例对象
     */
    $!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));

    /**
     * 通过主键删除数据
     *
     * @param $!pk.name 主键
     * @return 是否成功
     */
    boolean deleteById($!pk.shortType $!pk.name);

}


serviceImpl


##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "ServiceImpl"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service/impl"))

##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())
    #set($pk = $tableInfo.pkColumn.get(0))
#end

#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl;

import $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.dao.$!{tableInfo.name}Dao;
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.aaa.common.util.CustomException;
import com.aaa.common.util.ResultStatus;
import com.aaa.common.vo.QueryPage;


import javax.annotation.Resource;

/**
 * $!{tableInfo.comment}($!{tableInfo.name})表服务实现类
 *
 * @author $!author
 * @since $!time.currTime()
 */
@Service("$!tool.firstLowerCase($!{tableInfo.name})Service")
public class $!{tableName} implements $!{tableInfo.name}Service {
    @Resource
    private $!{tableInfo.name}Dao $!tool.firstLowerCase($!{tableInfo.name})Dao;

    /**
     * 通过ID查询单条数据
     *
     * @param $!pk.name 主键
     * @return 实例对象
     */
    @Override
    public $!{tableInfo.name} queryById($!pk.shortType $!pk.name) {
        return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.queryById($!pk.name);
    }

    /**
     * 分页查询
     *
     * @param queryPage 筛选条件
     * @return 查询结果
     */
    @Override
    public PageInfo queryByPage(QueryPage<$!{tableInfo.name}> queryPage) {
       //分页操作  分页参数一定要进行传递
        if(queryPage==null||queryPage.getPageNo()==0||queryPage.getPageSize()==0){
            //进行业务编写时,可以抛出自定义异常
            throw new CustomException(ResultStatus.ARGUMENT_IS_NOT_NULL.getReturnCode(),
                    ResultStatus.ARGUMENT_IS_NOT_NULL.getReturnMessage());
        }
        PageHelper.startPage(queryPage.getPageNo(),queryPage.getPageSize());
        //获取查询对象
        $!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}) = queryPage.getData();
        return new PageInfo($!{tool.firstLowerCase($!{tableInfo.name})}Dao.queryAllByLimit($!tool.firstLowerCase($!{tableInfo.name})));
    }

    /**
     * 新增数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 实例对象
     */
    @Override
    public $!{tableInfo.name} insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.insert($!tool.firstLowerCase($!{tableInfo.name}));
        return $!tool.firstLowerCase($!{tableInfo.name});
    }

    /**
     * 修改数据
     *
     * @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象
     * @return 实例对象
     */
    @Override
    public $!{tableInfo.name} update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {
        this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.update($!tool.firstLowerCase($!{tableInfo.name}));
        return this.queryById($!{tool.firstLowerCase($!{tableInfo.name})}.get$!tool.firstUpperCase($pk.name)());
    }

    /**
     * 通过主键删除数据
     *
     * @param $!pk.name 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById($!pk.shortType $!pk.name) {
        return this.$!{tool.firstLowerCase($!{tableInfo.name})}Dao.deleteById($!pk.name) > 0;
    }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杵意

谢谢金主打赏呀!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值