栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot+MyBatis-Plus+Redis+统一http返回+LomBook+log4j2+sl4j+自定义异常,环境搭建-------保姆教程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot+MyBatis-Plus+Redis+统一http返回+LomBook+log4j2+sl4j+自定义异常,环境搭建-------保姆教程

目录

SpringBoot项目初始搭建

1.快速构建SpringBoot项目:

2.结构介绍:

2.整合Mybatis-Plus:

3.LomBook插件

4.统一HTTP响应体

5.集成Redis

--------------------------------------------------更新-----------------------------------------------------------

5.集成log4j2+sl4j

6.自定义异常


SpringBoot项目初始搭建

SpringBoot+MyBatis-Plus+Redis+统一http返回+LomBook

1.快速构建SpringBoot项目:
1.打开idea
2.选择spring Initializr
3.构建包路径:
    3.1例:Group:com.baidu Artifact:model---即com.baidu.model
4.如有WEB需求,就选择web->spring web
  • 构建完成-->结构如图:

2.结构介绍:
1.pom.xml--->maven工程(jar包)管理配置文件
2.MyDemoApplication.java--->项目启动类
3.static--->静态文件存放地址
4.templates--->前端页面编写地址
5.application.properties--->配置文件

注释:application.properties默认为空,且端口号默认8080,可以加配置任意更改

2.整合Mybatis-Plus:
1.添加依赖:
 
 
 mysql
 mysql-connector-java
 runtime
 
 
 
 org.projectlombok
 lombok
 true
 
 
 
 com.baomidou
 mybatis-plus-boot-starter
 3.2.0
 
 
 
 com.baomidou
 mybatis-plus-generator
 3.2.0
 
 
 
 org.freemarker
 freemarker
 2.3.28
 
 
 
 com.alibaba
 fastjson
 1.2.47
 
2.添加配置
    2.1 yml配置
server:
  #服务端口
  port: 8001
  servlet:
    #默认访问
    context-path: /

spring:
  #数据源
  datasource:
    #数据源驱动
    driver-class-name: com.mysql.cj.jdbc.Driver
    #数据库连接
    url: jdbc:mysql://127.0.0.1:3306/mydemo?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
    #数据库账号
    username: root
    #数据库密码
    password: 123456
  jackson:
    #全局设置@JsonFormat的格式pattern
    date-format: yyyy-MM-dd HH:mm:ss
    # 设置全局时区
    time-zone: GMT+8
    serialization:
      # 不返回java.util.date转换成timestamp
      write-dates-as-timestamps: false

mybatis-plus:
  configuration:
    # 开启驼峰命名
    map-underscore-to-camel-case: true
    # 代码生成自动映射表结构
    auto-mapping-behavior: full
    # 日志工厂
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    # mapper文件位置
  #mapper-locations: classpath*:mapper*Mapper.xml
  global-config:
    # 逻辑删除配置
    db-config:
      # 删除前
      logic-not-delete-value: 1
      # 删除后
      logic-delete-value: 0

    2.2 config 配置文件
package com.mylife.lifemodel.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class MybatisPlusConfig {
    
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}
3.代码自生成
package com.mylife.lifemodel.config;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.Scanner;


public class GeneratorCodeConfig {
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("astupidcoder");
        gc.setOpen(false);
        //实体属性 Swagger2 注解
        gc.setSwagger2(false);
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mydemo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
//        pc.setModuleName(scanner("模块名"));
        pc.setParent("com.mylife.lifemodel");
        pc.setEntity("model.domain");
        pc.setMapper("service.mapper");
        pc.setService("service");
        pc.setServiceImpl("service.impl");
        mpg.setPackageInfo(pc);

        // 自定义配置
//        InjectionConfig cfg = new InjectionConfig() {
//            @Override
//            public void initMap() {
//                // to do nothing
//            }
//        };

        // 如果模板引擎是 freemarker
//        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // 自定义输出配置
//        List focList = new ArrayList<>();
        // 自定义配置会被优先输出
//        focList.add(new FileOutConfig(templatePath) {
//            @Override
//            public String outputFile(TableInfo tableInfo) {
//                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
//                return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
//                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
//            }
//        });
        
//        cfg.setFileOutConfigList(focList);
//        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定义输出模板
        //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setSuperEntityClass("com.baomidou.mybatisplus.extension.activerecord.Model");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);

        strategy.setEntityLombokModel(true);
        // 公共父类
//        strategy.setSuperControllerClass("com.baomidou.ant.common.baseController");
        // 写于父类中的公共字段
//        strategy.setSuperEntityColumns("id");
        strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }
}
4.启动GeneratorCodeConfig,并测试生成
5.LambdaQueryWrapper常见用法

3.LomBook插件
1.pom.xml
    
        
            org.projectlombok
            lombok
            true
        
2.lombook常用注解
 
 @Data 
 
 
 @NonNull
 
 
 @Cleanup
 
 
 @Getter
 @Setter
 
 
 @ToString
 
 
 @EqualsAndHashCode
 
 
 @NoArgsConstructor
 
 
 @AllArgsConstructor
 
 
 @RequiredArgsConstructor
 
 
 @Data
 
 
 @Value
 
 
 @Builder
 
 
 @SneakyThrows
 
 
 @Synchronized
 
 
 @Getter(lazy=true)
 
 
 @Log
 
 @CommonsLog 
 Creates log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
 
 @Log 
 Creates log = java.util.logging.Logger.getLogger(LogExample.class.getName());
 
 @Log4j 
 Creates log = org.apache.log4j.Logger.getLogger(LogExample.class);
 
 @Log4j2 
 Creates log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
 
 @Slf4j 
 Creates log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
 
 @XSlf4j 
 Creates log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

4.统一HTTP响应体
1.定义响应参数-实体类
2.定义响应枚举

5.集成Redis
1.pom.xml
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
        
            com.fasterxml.jackson.core
            jackson-annotations
        
2.Redis配置及configer
    2.1 yml
redis:
    host: localhost # Redis服务器地址
    database: 6 # Redis数据库索引(默认为0)
    port: 6379 # Redis服务器连接端口
    password: # Redis服务器连接密码(默认为空)
    jedis:
      pool:
        max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
        max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-idle: 8 # 连接池中的最大空闲连接
        min-idle: 0 # 连接池中的最小空闲连接
    timeout: 3000ms # 连接超时时间(毫秒)
  cache:
    # spring cache 缓存类型为redis  也可以是其他的实现
    type: redis
    2.2 config
package com.mylife.lifemodel.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypevalidator;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;


@Configuration
public class RedisConfig {

    @Bean
    @SuppressWarnings("all")
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate template = new RedisTemplate();
        template.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);

        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);

        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);

        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }
}
3.RedisUtils工具类
package com.mylife.lifemodel.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.support.atomic.RedisAtomicLong;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;


@Component
public class RedisUtils {
    @Autowired
    private RedisTemplate redisTemplate;
    
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    
    public boolean set(final String key, Object value, Long expireTime) {
        boolean result = false;
        try {
            ValueOperations operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }
    
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }
    
    public  T get(final String key) {
        Object result = null;
        ValueOperations operations = redisTemplate.opsForValue();
        result = operations.get(key);
        if (null == result) {
            return null;
        }
        return (T)result;
    }
    
    public void hmSet(String key, Object hashKey, Object value) {
        HashOperations hash = redisTemplate.opsForHash();
        hash.put(key,hashKey,value);
    }

    
    public Object hmGet(String key, Object hashKey) {
        HashOperations hash = redisTemplate.opsForHash();
        return hash.get(key,hashKey);
    }

    
    public void lPush(String k, Object v) {
        ListOperations list = redisTemplate.opsForList();
        list.rightPush(k,v);
    }

    
    public List lRange(String k, long l, long l1) {
        ListOperations list = redisTemplate.opsForList();
        return list.range(k,l,l1);
    }

    
    public void add(String key, Object value) {
        SetOperations set = redisTemplate.opsForSet();
        set.add(key,value);
    }

    
    public Set setMembers(String key) {
        SetOperations set = redisTemplate.opsForSet();
        return set.members(key);
    }

    
    public void zAdd(String key, Object value, double scoure) {
        ZSetOperations zset = redisTemplate.opsForZSet();
        zset.add(key,value,scoure);
    }

    
    public Set rangeByScore(String key, double scoure, double scoure1) {
        ZSetOperations zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }

    
    public Long incr(String key){
        RedisAtomicLong entityIdCounter = new RedisAtomicLong(key, redisTemplate.getConnectionFactory());
        Long increment = entityIdCounter.getAndIncrement();
        return increment;
    }
}
 
4.编写测试
package com.mylife.lifemodel.model;

import com.mylife.lifemodel.utils.RedisUtils;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


  @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
  public class Test01 {
  @Autowired
  private RedisUtils redisUtils;

  @Test
  public void redisConnectTest(){
  String testKey = "test";
  //        Long time = (long)10;
  //        redisUtils.set(testKey, "***Test01",time);
  //        redisUtils.remove(testKey);
  String result = redisUtils.get(testKey);
  System.out.println("获取redis测试数据:" + result);
  }
  }
  • 展示: 

--------------------------------------------------更新-----------------------------------------------------------

5.集成log4j2+sl4j
1.pom.xml
        
        
            org.apache.logging.log4j
            log4j-api
            2.16.0
        
        
            org.apache.logging.log4j
            log4j-core
            2.16.0
        
        
            org.apache.logging.log4j
            log4j-web
            2.16.0
        
        
        
            org.apache.logging.log4j
            log4j-slf4j-impl
            2.16.0
        
        
        
            org.slf4j
            slf4j-api
        
        
        
        
        
        
        
        
        
            com.lmax
            disruptor
            3.4.2
        
2.log4j2.xml





    
        
        logs
        %d{yyyyMMdd-HHmmss.SSS} [%level] %c{1} - %msg%n
    
    
    
        
        
            
            
            
        

        
        
            
            
        

        
        
            
        

        
        
            
            
            
            
            
                
                
                    
                    
                
            
        
        
        
            
            
            
            
            
                
                
                
                
            
            
            
        
        
            
            
            
                
                
            

        
        
            
            
            
                
                
            
        
    
    
    
        
        
        
            
            
        
        
        
        
        
        
        
        
        
        
            
            
        
    

        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        

        
        
        
        
        
        
        
        
        
        
        
        
        
3.测试
package com.mylife.lifemodel;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class log4j2Test {

    private static Logger logger= LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    @Test
    public void log4j2Test() {
        for(int i=0;i<3;i++){
            // 记录trace级别的信息
            logger.trace("log4j2日志输出:This is trace message.");
            // 记录debug级别的信息
            logger.debug("log4j2日志输出:This is debug message.");
            // 记录info级别的信息
            logger.info("log4j2日志输出:This is info message.");
            // 记录error级别的信息
            logger.error("log4j2日志输出:This is error message.");
        }
    }
}
输出:

6.自定义异常
1.错误枚举类
package com.mylife.lifemodel.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;


  @Getter
  @AllArgsConstructor
  public enum ErrorType {
  
      OBJECT_NOT_FOUND(0,"对象不存在"),

  INVALID_PARAMS(1,"参数不正确"),

  result_not_exist(2,"记录不存在")

           ;

  
      private int code;

  
      private String msg;
      }
2.自定义异常
package com.mylife.lifemodel.api;

import com.mylife.lifemodel.enums.ErrorType;
import lombok.Getter;

  @Getter
  public class MyLifeException extends RuntimeException{
  private Integer code;

  
      public MyLifeException(ErrorType type){
      super(type.getMsg());
      this.code = type.getCode();
      }

  
      public MyLifeException(Integer code, String msg){
      super(msg);
      this.code = code;
      }
      }
3.响应参数--一般除了我代码里贴出来的
还有success状态码,成功或失败
响应时间,分页等,我这里从简了
其实就算不写也行,返回的比较难看而已
package com.mylife.lifemodel.api;

import lombok.Data;


@Data
public class Response {
    
    private Integer code;

    
    private T data;

    
    private String msg;

}
4.工具类
package com.mylife.lifemodel.api;


public class MyLifeUtils {
    
    private static final String SUCCESS = "调用成功!";

    public static Response success(Object obj){
        Response res = new Response();
        res.setCode(200);
        res.setData(obj);
        res.setMsg(SUCCESS);
        return res;
    }

    public static Response success(){
        return success(null);
    }

    public static Response error(Integer code, String msg){
        Response res = new Response();
        res.setCode(code);
        res.setMsg(msg);
        return res;
    }

}
5.异常处理类
package com.mylife.lifemodel.api;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


  @ControllerAdvice
  public class ServiceExceptionHandler {
  
      @ExceptionHandler(MyLifeException.class)
      @ResponseBody
      public Response handle(MyLifeException me){
      return MyLifeUtils.error(me.getCode(),me.getMessage());
      }
      }
  • 测试
1.main方法测试

2.@SpringBootTest测试

3.Controller测试

以上就是springBoot项目完整搭建的过程

上面是最基础的也是最简化的模拟企业级开发搭建的框架

实际开发中比这搭建的要更加底层,更加复杂得多

而且有很多关键的分布式技术我都没有进行搭建

例如:zookeeper分布式协调服务,RabbitMQ消息列队,MongDB海量存储

这些技术只有用户基数大,数据体量巨大的时候才能用到

一般中小型企业,考虑到开发成本维护成本等,不会选择

当然有志向进大厂,拿高薪的小伙伴可以自行摸索评论区探讨

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号