首页 > 其他分享 >谈springboot两种实现结构

谈springboot两种实现结构

时间:2024-05-07 22:33:45浏览次数:32  
标签:两种 springboot ReturnResult region name public import id 结构

概述

最近由于入职华海智汇,所以文章也少了,并不是自己懈怠了,而是华海的保密措施不允许我上班写文章了,更何况还有无尽的加班。。。。。。。。。唉,所幸现在习惯了好多,现在觉着该记录一下知识了。目前市场上,要实现Java项目主要有Maven和Gradle两种框架,其中Gradle是新兴势力,Maven是老牌势力,其实我更加喜欢用Gradle,因为更加便捷,无奈,现在市面上Maven仍然是主流,因为稳定,更因为许多老项目都是Maven搭建的。。。。。。今天这篇文章主要是介绍两种实现springboot的方式,以防以后忘记

第一种:Domain(entity)-Mapper-Service-Controller

这种方式是我的老师教给我的方式,我也认为是最简单的方式,也是我的最爱,不过却是不常见的
例如:

实体类层:Domain(entity)

package com.example.pmxt.domain;

import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
@TableName("sys_region")
public class Region {

    @NotNull(message = "id不能为空")
//    @NotBlank(message = "id不能为空")
//    @Length(min = 6,max = 6,message = "长度必须为6")
    @ExcelProperty("编号")
    private Integer id;

    @NotNull(message = "名称不能为空")
    @NotBlank(message = "名称不能为空")
    @ExcelProperty("名称")
    private String name;

    @NotNull(message = "父类id不能为空")
//    @NotBlank(message = "父类id不能为空")
//    @Length(min = 6,max = 6,message = "长度必须为6")
    @ExcelProperty("父类id")
    private Integer parentId;

    @ExcelProperty("备注")
    private String remark;

}

这一层在两种方式中并无区别,就是建立实体类,方便管理。

Mapper层

这一层主要有两种实现方式:注解和写<这种标签,注解比较多,因为简便,标签的话,应该是老程序员专属吧,注解如下:

package com.example.pmxt.modules.region;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.pmxt.domain.Region;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface RegionMapper extends BaseMapper<Region> {

//    @Select("SELECT sys_region.id,sys_region.name,sys_region.parent_id from sys_region,busi_bd.szd where sys_region.id = busi_bd.szd union SELECT sys_region.id,sys_region.name,sys_region.parent_id from sys_region,busi_bd where sys_region.id = concat(left(busi_bd.szd,4),'00') union SELECT sys_region.id,sys_region.name,sys_region.parent_id from sys_region,busi_bd where sys_region.id = concat(left(busi_bd.szd,2),'0000');")
//    List<Region> selectbybd();

    @Select("select * from sys_region where name = #{name}")
    Region getByname(String name);

    @Select("select parent_id from sys_region where name = #{name};")
    Integer getparentIdByName(String name);

    @Select("select id from sys_region where name = #{name};")
    Integer getIdByName(String name);

    @Select("select * from sys_region where concat(id) like concat(left(concat(#{id}),2),'%');")
    List<Region> getByProvince(Integer id);

    @Select("select * from sys_region where concat(id) like concat(left(concat(#{id}),4),'%');")
    List<Region> getByCity(Integer id);

    @Select("select * from sys_region where id = #{id}")
    List<Region> getByCounty(Integer id);


}

注意BaseMapper来自于Mybatis-plus导包

主要就是注解+SQL语句后,下面跟个方法名

Service层

这块是两种方式差别最大的一个,这种方式只需要一个Service类就好了,但是需要一个工具类BaseService。

BaseService:

package com.example.pmxt.common;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

public class BaseService<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> {
}

所有的Service都可以继承这个BaseService,这样就不用写ServiceImpl了,只需要卸载Service中就行了

Service:

package com.example.pmxt.modules.region;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.example.pmxt.common.BaseService;
import com.example.pmxt.domain.Region;
import lombok.SneakyThrows;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@Service
@Transactional
public class RegionService extends BaseService<RegionMapper,Region> {

    private final RegionMapper mapper;

    @Autowired
    public RegionService(RegionMapper mapper) {
        this.mapper = mapper;
    }


    @SneakyThrows
    public boolean importFileToDB(boolean deleteHistory, MultipartFile file) {
    //是否删除数据库表中历史数据
        if (deleteHistory) {
            this.remove(null);
        }
    //读取excel表格中数据
        EasyExcel.read(file.getInputStream(), Region.class, new ReadListener<Region>() {
            //定义一个常量BATCH_SIZE与一个列表ls
            private static final int BATCH_SIZE = 1000;
            private List<Region> ls = Lists.newArrayList();
            //重写invoke方法
            @Override
            public void invoke(Region data, AnalysisContext context) {
                //System.err.println(data);
                //列表里添加Flowfee类的数据
                ls.add(data);
                //每1000条放到数据库里面
                if (ls.size() >= BATCH_SIZE) {
                    RegionService.this.saveBatch(ls);
                    ls.clear();
                }
            }
            //重写doAfterAllAnalysed方法,处理剩下的数据,例如1050条,其中1000条在上面已经放到数据库,剩下的50条下面处理
            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                RegionService.this.saveBatch(ls);
            }
        }).sheet().doRead();
        return true;
    }

    public Integer getparentIdByName(String name){
        return mapper.getparentIdByName(name);
    }
    public Integer getIdByName(String name){
        return mapper.getIdByName(name);
    }

    public List<Region> gettable(String name){
        if (mapper.getByname(name)==null){
            return null;
        }
        Integer id = mapper.getIdByName(name);
        if ("0000".equals(String.valueOf(id).substring(2))){
            return mapper.getByProvince(id);
        }else if ("00".equals(String.valueOf(id).substring(4))){
            return mapper.getByCity(id);
        }else {
            return mapper.getByCounty(id);
        }
    }
}

Controller层

这一层是用于给前端写接口的类,两种方法基本一致

package com.example.pmxt.modules.region;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.example.pmxt.common.ReturnResult;
import com.example.pmxt.domain.Region;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Validated
@RequestMapping("/regions")
public class RegionController {

    private final RegionService service;

    @Autowired
    public RegionController(RegionService service) {
        this.service = service;
    }

    @GetMapping()
    public ReturnResult getAllRegion(){
        //这里用的MyBatis Plus
        List<Region> dtos = service.list();
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都要默认值的
        treeNodeConfig.setIdKey("id");
        // 最大递归深度
        treeNodeConfig.setDeep(4);
        //转换器
        List<Tree<Integer>> treeNodes = TreeUtil.build(dtos, 0, treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId());
                    tree.setParentId(treeNode.getParentId());
                    tree.setName(treeNode.getName());
                });
        return ReturnResult.buildSuccessResult(treeNodes);
    }

    @GetMapping("/name")
    public ReturnResult getByName(@NotNull(message = "parentid不能为空") String name){
        Integer parentid = service.getparentIdByName(name);
        //这里用的MyBatis Plus
        List<Region> dtos = service.gettable(name);
        if (dtos == null){
            return ReturnResult.buildFailureResult("该地区不存在");
        }
        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 自定义属性名 都要默认值的
        treeNodeConfig.setIdKey("id");
        // 最大递归深度
        treeNodeConfig.setDeep(3);
        //转换器
        List<Tree<Integer>> treeNodes = TreeUtil.build(dtos, parentid, treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId());
                    tree.setParentId(treeNode.getParentId());
                    tree.setName(treeNode.getName());
                });
        return ReturnResult.buildSuccessResult(treeNodes);

    }

//    @GetMapping("/selectbybd")
//    public ReturnResult selectbybd(){
//        return ReturnResult.buildSuccessResult(service.selectbybd());
//    }

    @PostMapping()
    public ReturnResult addRegion(@RequestBody @Validated Region region){
        if (region == null){
            return ReturnResult.buildFailureResult("行政区划不能为空");
        }
            return ReturnResult.buildSuccessResult(service.save(region));

    }

    @DeleteMapping("/{id}")
    public ReturnResult deleteRegionById(@PathVariable @NotNull(message = "id不能为空") Integer id){
        if(id == null){
            return ReturnResult.buildFailureResult("id不能为空");
        }
        Region r = service.getById(id);
        if (r != null){
            return ReturnResult.buildSuccessResult(service.removeById(id));
        }else {
            return ReturnResult.buildFailureResult("id不存在");
        }
    }

    @PutMapping()
    public ReturnResult updateRegion(@RequestBody Region region){
        if (region == null){
            return ReturnResult.buildFailureResult("行政区划不能为空");
        }
        Region r = service.getById(region.getId());
        if (r != null) {
            return ReturnResult.buildSuccessResult(service.updateById(region));
        }else {
            return ReturnResult.buildFailureResult("id不存在");
        }
    }


    //@PostMapping定义IP地址映射方法与位置,@ApiOperation是swagger测试注解
    @PostMapping("/uploadregion")
    public ReturnResult excelToDatabase( @RequestParam boolean deleteHistory,
                                         @RequestPart("file") MultipartFile file) {
        if(service.importFileToDB(deleteHistory, file)){
            return ReturnResult.buildSuccessResult("添加成功",null);
        }else {
            return ReturnResult.buildFailureResult("添加失败",null);
        }
    }


    @DeleteMapping("deletes")
    public ReturnResult deleteregions(Integer [] ids){
        if (ids.length == 0){
            return ReturnResult.buildFailureResult("行政区划不能为空");
        }else {
            return ReturnResult.buildSuccessResult(service.removeBatchByIds(Arrays.asList(ids)));
        }
    }
}

第二种:Domain(entity)-Mapper-Service-ServiceImpl-Controller

这种方法主要就差在Service层,其余层可以参考上面

Service层

Service:

public interface UserSerivce extends IService<User> {
}

这种方法Service要先继承IService工具类,实际上ServiceImpl已将包含了IService中的所有方法

ServiceImpl:

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserSerivce {

}

这就需要多写一个Impl类,实际上两者原理一样,第二种多了个ServiceImpl<UserMapper, User> 实现 UserSerivce接口,而UserSerivce接口又要继承IService,比较麻烦,不喜欢。。。。。,但是无奈,这是主流,尤其大厂还有代码检视,第一种会被认为不对,但我个人觉得能实现功能就是好方法,你认为呢?

最后说明这两种方法应该在Maven和Gradle框架中都可以使用,至少Maven是都可以的,因为我试过了,,Gradle中我用过第一种,第二种还没用过,不过既然原理一致,应该都可以使用;

这篇文章只当自己对喜爱方法的纪念吧。。。。

标签:两种,springboot,ReturnResult,region,name,public,import,id,结构
From: https://www.cnblogs.com/beijie/p/18178469

相关文章

  • 软件设计师:结构化开发方法
    模块化模块独立软件模块应尽量做到高内聚、低耦合,提高模块的独立性耦合性无直接耦合:没有直接关系数据耦合:传递简单的数据值标记耦合:传递数据结构控制耦合:传递控制变量外部耦合:软件之外的环境联结公共耦合:公共数据环境内容耦合:通过非正常入口/直接访问内部数据内聚......
  • 常用的数据结构
    日常开发中,可能会用到的数据结构类型数组一组相同类型的元素的集合,可以通过下标进行访问和操作。在C#中,有Array、ArrayList、List时间复杂度:查找是O(N)。插入和删除是O(N)。数组通过下标直接访问元素,时间复杂度是O(1)。数据的每次新增或者删除,数据需要重新排列顺序,时间复杂......
  • MySQL同步故障:“ Slave_SQL_Running:No“ 两种解决办法
    进入slave服务器,运行: ​mysql>showslave status\G            .......              Relay_Log_File:localhost-relay-bin.000535               Relay_Log_Pos:21795072       Relay_Ma......
  • 数据结构
    前缀和结构特征:连续子数组的元素和技巧:len(前缀和)=len(list)+1前缀和可以作为list的v,也可做为list的index!----哈希表(问的是xxx的数目)presum=[0]+list(accumulate(nums))---得到前缀和数组accumulate函数可以累加nums的值哈希表使用......
  • SpringBoot+Thymeleaf渲染下拉框异常解决
    常规方式<selectclass="form-control"name="operationType"th:field="${itemTemp.operationType}"style="width:80%"th:disabled="${readonly}"><optionvalue="">选......
  • Springboot+Netty实现http和ws统一端口处理
    http:/localhost:8080/apiws:/localhost:8080/ws核心就是两个channel处理器,http和wswebsocketpackagecom.example.netty;importio.netty.channel.ChannelHandlerContext;importio.netty.channel.SimpleChannelInboundHandler;importio.netty.handler.codec.http.HttpH......
  • SpringBoot集成WebSocket
    SpringBoot集成WebSocket1.引jar包<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency&......
  • 已知前中后序遍历的其中两种推断出最后一种序遍历
    已知二叉树后序遍历序列是dabec,中序遍历序列是debac,它的前序遍历序列是?方法1:首先可以确定c为根d为最左子树由中序debac假设b为第2排的子树那么后序的后两位应该是bcyu本题题目后序不符合由中序debac假设e为第2排的字数那么后序的后两位应该是ec符合本题题目后序由后......
  • springboot在2.4以后版本使用application.yml替换bootstrap.yml
    首先确认你的springboot版本是高于2.4的版本的,然后移除以下依赖<!--<dependency>--><!--<groupId>org.springframework.cloud</groupId>--><!--<artifactId>spring-cloud-starter-bootstrap</artifactId>--><!--</d......
  • 路由跳转、相关api、路由守卫、路由两种工作模式
    【router基本使用(路由跳转,携带数据)】#######跳转#######-js跳转this.$router.push(路径)this.$router.push(对象)-this.$router.push({name:'路由别名'})-this.$router.push({path:'路径'})-组件跳转......