Bootstrap

spring-cloud+ nacos+feign 增删改查(多表)

spring-cloud+ nacos+feign 增删改查(多表)

环境准备

  • 数据库
    学生自行创建数据库,根据提供的sql创建表和数据,每个表单独一个数据库
  • 后台
    学生自行搭建SpringCloud+Feign+Nacos+GateWay+MyBatis后台环境
  • 前台
    学生自行创建前台vue环境,实现测试要求

后端:以book和category为例

如图所示:book 是主,category是从

在这里插入图片描述

book.pom文件 和category.pom文件

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
         <!--这个是你自己的 feign-apl -->
        <dependency>
            <groupId>book-parent</groupId>
            <artifactId>feign-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--阿里 spring cloud-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--通用mapper-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
        </dependency>
        <!--spring boot 启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mysql 启动器-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!--nacos配置管理依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

feign(远程调用)和getaway(网关)


红色的不用写 那是过滤器

feign 和getaway的pom文件

 <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.6.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <!--引入feign的starter依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

        <!-- 时间所需的jar @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!-- 通用mysql-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.5</version>
        </dependency>

    </dependencies>

getaway·:内容

   
    <dependencies>
    <!--网关-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
        <version>2.2.6.RELEASE</version>
    </dependency>
    <!--nacos服务发现依赖-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>2.2.6.RELEASE</version>
    </dependency>
</dependencies>
父类(项目类)

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <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>Hoxton.SR10</spring-cloud.version>
        <mysql.version>8.0.27</mysql.version>
        <mybatis.version>2.1.1</mybatis.version>
        <mapper.starter.version>2.0.2</mapper.starter.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- springCloud  阿里 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.2.6.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <!-- 通用Mapper启动器 -->
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
                <version>${mapper.starter.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

创建数据库:一个表 一个数据库
在这里插入图片描述
好了环境准备,已经做完了下面就是写代码了

BookController.java

package com.czxy.controller;

import com.czxy.Vo.BookVo;
import com.czxy.domain.Book;
import com.czxy.service.BookService;
import com.github.pagehelper.PageInfo;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/book")
public class BookController {

    @Resource
    private BookService bookService;

    @GetMapping
    public List<Book> findSchoolAll(){
        List<Book> list = bookService.findSchoolAll();
        return list;
    }
    @GetMapping("/{id}")
    public Book findSchoolById(@PathVariable("id") Integer id){
        Book book = bookService.findSchoolById(id);
        return book;
    }

    @PutMapping
    Integer Up(@RequestBody Book book){
        Integer up = bookService.Up(book);
        return up;
    }
    @PostMapping("/{pageNum}/{pageSize}")
    PageInfo<Book> pageIn(
            @PathVariable Integer pageNum,
            @PathVariable Integer pageSize,
            @RequestBody BookVo bookVo
    ){
        PageInfo<Book> bookPageInfo = bookService.pageIn(pageNum, pageSize, bookVo);
        return bookPageInfo;
    }


    @PostMapping
    Integer insert(@RequestBody Book book){
        Integer insert = bookService.insert(book);
        return insert;
    }


    @DeleteMapping("/{id}")
    Integer daleTe(@PathVariable("id") Integer id){
        Integer daleTe = bookService.daleTe(id);
        return daleTe;
    }

    @DeleteMapping("/batchDelete/{ids}")
    void daleAll(@PathVariable("ids") String ids){
        bookService.daleAll(ids);
    }

}

BookMapper.java

package com.czxy.dao;

import com.czxy.domain.Book;
import com.czxy.domain.Category;
import tk.mybatis.mapper.common.Mapper;

@org.apache.ibatis.annotations.Mapper
public interface BookMapper extends Mapper<Book> {
}

bookservice.java

package com.czxy.service;

import com.czxy.Vo.BookVo;
import com.czxy.dao.BookMapper;
import com.czxy.domain.Book;
import com.czxy.domain.Category;
import com.czxy.feign.BookFeign;
import com.czxy.feign.CategoryClient;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.List;

@Service
@Transactional
public class BookService implements BookFeign {

    @Resource
    private BookMapper bookMapper;

    @Resource
    private CategoryClient categoryClient;
    @Override
    public List<Book> findSchoolAll() {
        List<Book> list = bookMapper.selectAll();
        for (Book book : list) {
            Category category = categoryClient.queryByTid(book.getCid());
            book.setCategory(category);
        }
        return list;
    }

    @Override
    public Book findSchoolById(Integer id) {
        Book book = bookMapper.selectByPrimaryKey(id);
        Category category = categoryClient.queryByTid(book.getCid());
        book.setCategory(category);
        return book;
    }

    @Override
    public Integer Up(Book book) {
        int i = bookMapper.updateByPrimaryKey(book);
        return i;
    }

    @Override
    public Integer daleTe(Integer id) {
        int i = bookMapper.deleteByPrimaryKey(id);
        return i;
    }

    @Override
    public void daleAll(String ids) {
        String[] split = ids.split(",");
        for (String s : split) {
            bookMapper.deleteByPrimaryKey(s);
        }
    }

    @Override
    public PageInfo<Book> pageIn(Integer pageNum, Integer pageSize, BookVo bookVo) {

        Example example = new Example(Book.class);

        Example.Criteria criteria = example.createCriteria();

        if (bookVo.getCid()!=null && !"".equals(bookVo.getCid())){
            criteria.andEqualTo("cid",bookVo.getCid());
        }

        if (bookVo.getName()!=null&& !"".equals(bookVo.getName())){
            criteria.andLike("name","%"+bookVo.getName()+"%");
        }
        if (bookVo.getStaPrice()!= null && !"".equals(bookVo.getStaPrice())){
            criteria.andGreaterThanOrEqualTo("price",bookVo.getStaPrice());
        }
        if (bookVo.getEntPrice()!= null && !"".equals(bookVo.getEntPrice())){
            criteria.andLessThanOrEqualTo("price",bookVo.getEntPrice());
        }

        PageHelper.startPage(pageNum,pageSize);

        List<Book> list = bookMapper.selectByExample(example);
        for (Book book : list) {
            Category category = categoryClient.queryByTid(book.getCid());
            book.setCategory(category);
        }


        return new PageInfo<>(list);
    }

    @Override
    public Integer insert(Book book) {
        int insert = bookMapper.insert(book);
        return insert;
    }

}

启动类:BookApplication

package com.czxy;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients(basePackages = "com.czxy.feign")
@SpringBootApplication
public class BookApplication {
    public static void main(String[] args) {
        SpringApplication.run(BookApplication.class,args);
    }
}

B:application.yml

server:
  port: 8081
spring:
  application:
    name: bookservice
  datasource:
    url: jdbc:mysql://localhost:3306/cloud-book?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
      config:
        file-extension: yaml # 文件后缀名
mybatis:
  type-aliases-package: com.czxy.domain
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
feign:
  client:
    config:
      default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
        loggerLevel: FULL #  日志级别

CategoryController.java

package com.czxy.controller;

import com.czxy.dao.CategoryMapper;
import com.czxy.domain.Book;
import com.czxy.domain.Category;
import com.czxy.service.CategoryService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/category")
public class CategoryController {

    @Resource
    private CategoryService categoryService;



    @GetMapping
    List<Category> All(){
        List<Category> all = categoryService.All();
        return all;
    }

    @PostMapping
    Integer insert(@RequestBody Category category){
        return categoryService.insert(category);
    }

    @GetMapping("/{cid}")
    Category queryByTid(@PathVariable Integer cid){
        Category category = categoryService.queryByTid(cid);
        return category;
    }
    @PutMapping
    Integer Up(@RequestBody Category category){
        return categoryService.Up(category);
    }

    @DeleteMapping("/{cid}")
    Integer Up(@PathVariable("cid")  Integer cid){
        return categoryService.date(cid);
    }
}

CategoryService.java

package com.czxy.service;

import com.czxy.dao.CategoryMapper;
import com.czxy.domain.Category;
import com.czxy.feign.CategoryClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

@Service
@Transactional
public class CategoryService implements CategoryClient {

    @Resource
    private CategoryMapper categoryMapper;


    @Override
    public Category queryByTid(Integer cid) {
        Category category = categoryMapper.selectByPrimaryKey(cid);
        return category;
    }

    @Override
    public List<Category> All() {
        List<Category> categories = categoryMapper.selectAll();
        return categories;
    }

    @Override
    public Integer insert(Category category) {
        return categoryMapper.insert(category);
    }
    @Override
    public Integer Up(Category category) {
        return categoryMapper.updateByPrimaryKey(category);
    }
    @Override
    public Integer date(Integer cid) {
        return categoryMapper.deleteByPrimaryKey(cid);
    }
}

CategoryMapper.java

package com.czxy.dao;

import com.czxy.domain.Category;
import tk.mybatis.mapper.common.Mapper;

@org.apache.ibatis.annotations.Mapper
public interface CategoryMapper extends Mapper<Category> {
}

CategoryApplication.java

package com.czxy;

import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients(basePackages = "com.czxy.feign")
@SpringBootApplication
public class CategoryApplication {
    public static void main(String[] args) {
        SpringApplication.run(CategoryApplication.class,args);
    }
}

C:application.yml

server:
  port: 8082
spring:
  application:
    name: categoryservice
  datasource:
    url: jdbc:mysql://localhost:3306/cloud-category?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
      config:
        file-extension: yaml # 文件后缀名
mybatis:
  type-aliases-package: com.czxy.domain
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
feign:
  client:
    config:
      default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
        loggerLevel: FULL #  日志级别

在feign中创建实体类:book
在这里插入图片描述
在feign中创建实体类:category
在这里插入图片描述
BookFeign.java

package com.czxy.feign;

import com.czxy.Vo.BookVo;
import com.czxy.domain.Book;
import com.github.pagehelper.PageInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

//微服务的地址
@FeignClient(value="bookservice")
public interface BookFeign {
    //todo 查询所有
    @GetMapping("/book")
    public List<Book> findSchoolAll();

    //todo 分页查询+ 模糊查询
    @PostMapping("/book/{pageNum}/{pageSize}")
    PageInfo<Book>pageIn(
            @PathVariable Integer pageNum,
            @PathVariable Integer pageSize,
            @RequestBody  BookVo bookVo
            );

    //todo 添加
    @PostMapping("/book")
    Integer insert(@RequestBody Book book);

    //todo 根据id 查询
    @GetMapping("/book/{id}")
    public Book findSchoolById(@PathVariable("id") Integer id);

    //todo 修改
    @PutMapping("/book")
    Integer Up(@RequestBody Book book);

    //todo 删除
    @DeleteMapping("/book/{id}")
    Integer daleTe(@PathVariable("id") Integer id);

    //todo 批量删除
    @DeleteMapping("/book/batchDelete/{ids}")
    void daleAll(@PathVariable("ids") String ids);

}

CategoryClient.java

package com.czxy.feign;

import com.czxy.domain.Category;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.List;

//微服务的地址
@FeignClient(value = "categoryservice")
public interface CategoryClient {

    //todo 根据id 查询
    @GetMapping("/category/{cid}")
    Category queryByTid(@PathVariable Integer cid);

    //todo 查询所有
    @GetMapping("/category")
    List<Category> All();

    //todo 添加
    @PostMapping("/category")
    Integer insert(@RequestBody Category category);

    //todo 修改
    @PutMapping("/category")
    Integer Up(@RequestBody Category category);

    //todo 删除
    @DeleteMapping("/category/{cid}")
    Integer date(@PathVariable Integer cid);
}

分页所需要的Vo类
在这里插入图片描述
getaway的启动类
在这里插入图片描述
G:application.yml

server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # Nacos地址
    gateway:
      routes: # 网关路由配置
        - id: book-service # 路由id,自定义,只要唯一即可
            # uri: http://127.0.0.1:8082 # 路由的目标地址 http就是固定地址
          uri: lb://bookservice/ # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/book/** # 这个是按照路径匹配,只要以/user/开头就符合要求
        - id: category-service # 路由id,自定义,只要唯一即可
                  # uri: http://127.0.0.1:8082 # 路由的目标地址 http就是固定地址
          uri: lb://categoryservice/ # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
          - Path=/category/** # 这个是按照路径匹配,只要以/user/开头就符合要求
      # 网关解决跨域
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求
              - "http://localhost:8080"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期
;