目录
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.定义响应枚举
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
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.");
}
}
}
输出:
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海量存储
这些技术只有用户基数大,数据体量巨大的时候才能用到
一般中小型企业,考虑到开发成本维护成本等,不会选择
当然有志向进大厂,拿高薪的小伙伴可以自行摸索评论区探讨



