既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
<parent>
<groupId>com.micromaple</groupId>
<artifactId>my-project-dependencies</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../my-project-dependencies/pom.xml</relativePath>
</parent>
<artifactId>my-project-common</artifactId>
<packaging>jar</packaging>
<name>my-project-common</name>
<dependencies>
<!-- Commons Begin-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!-- Commons End-->
<!-- Environment Begin -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</dependency>
<!-- Environment End -->
<!-- Apache Http Begin -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
</dependency>
<!-- Apache Http End -->
</dependencies>
#### 3.2、Maven托管
可以使用右侧的`Maven` 的 `+` 号来进行项目的托管。
![在这里插入图片描述](https://img-blog.csdnimg.cn/e6d964c9663c4e17aecf822b0df36b88.jpeg#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/48820b316d13497db8a59176725852fd.jpeg#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/53fc71f01ed14ddebadaa061c059949b.jpeg#pic_center)
#### 3.3、完善目录结构
创建 `src/main/java` 目录后,创建包名,包名为:`com.micromaple.my.project.common`
此工程是放一些通用的类库或者是工具类之类的。
#### 3.4、定义通用类库
##### 3.4.1、返回状态码
创建常量包`constant`。
通用常量返回状态码`HttpStatus`
package com.micromaple.my.project.common.constant;
/**
* 返回状态码
* Title: HttpStatus
* Description:
*
* @author Micromaple
*/
public class HttpStatus {
/**
* 操作成功
*/
public static final int SUCCESS = 200;
/\*\*
* 对象创建成功
*/
public static final int CREATED = 201;
/\*\*
* 请求已经被接受
*/
public static final int ACCEPTED = 202;
/\*\*
* 操作已经执行成功,但是没有返回数据
*/
public static final int NO_CONTENT = 204;
/\*\*
* 资源已被移除
*/
public static final int MOVED_PERM = 301;
/\*\*
* 重定向
*/
public static final int SEE_OTHER = 303;
/\*\*
* 资源没有被修改
*/
public static final int NOT_MODIFIED = 304;
/\*\*
* 参数列表错误(缺少,格式不匹配)
*/
public static final int BAD_REQUEST = 400;
/\*\*
* 未授权
*/
public static final int UNAUTHORIZED = 401;
/\*\*
* 访问受限,授权过期
*/
public static final int FORBIDDEN = 403;
/\*\*
* 资源,服务未找到
*/
public static final int NOT_FOUND = 404;
/\*\*
* 不允许的http方法
*/
public static final int BAD_METHOD = 405;
/\*\*
* 资源冲突,或者资源被锁
*/
public static final int CONFLICT = 409;
/\*\*
* 不支持的数据,媒体类型
*/
public static final int UNSUPPORTED_TYPE = 415;
/\*\*
* 系统内部错误
*/
public static final int ERROR = 500;
/\*\*
* 接口未实现
*/
public static final int NOT_IMPLEMENTED = 501;
}
##### 3.4.2、通用返回结果
创建数据传输包`dto`。
通用数据传输返回结果`BaseResult`
package com.micromaple.my.project.common.dto;
import com.micromaple.my.project.common.constant.HttpStatus;
import java.util.HashMap;
/**
* 返回结果
* Title: BaseResult
* Description:
*
* @author Micromaple
*/
public class BaseResult extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
/\*\*
* 状态码
*/
public static final String CODE_TAG = “code”;
/\*\*
* 返回内容
*/
public static final String MSG_TAG = “msg”;
/\*\*
* 数据对象
*/
public static final String DATA_TAG = “data”;
/\*\*
* 初始化一个新创建的 BaseResult 对象,使其表示一个空消息。
*/
public BaseResult() {
}
/\*\*
* 初始化一个新创建的 BaseResult 对象
*
* @param code 状态码
* @param msg 返回内容
*/
public BaseResult(int code, String msg) {
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
}
/\*\*
* 初始化一个新创建的 BaseResult 对象
*
* @param code 状态码
* @param msg 返回内容
* @param data 数据对象
*/
public BaseResult(int code, String msg, Object data) {
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
super.put(DATA_TAG, data);
}
/\*\*
* 返回成功消息
*
* @return 成功消息
*/
public static BaseResult success() {
return BaseResult.success(“操作成功”);
}
/\*\*
* 返回成功数据
*
* @return 成功消息
*/
public static BaseResult success(Object data) {
return BaseResult.success(“操作成功”, data);
}
/\*\*
* 返回成功消息
*
* @param msg 返回内容
* @return 成功消息
*/
public static BaseResult success(String msg) {
return BaseResult.success(msg, null);
}
/\*\*
* 返回成功消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 成功消息
*/
public static BaseResult success(String msg, Object data) {
return new BaseResult(HttpStatus.SUCCESS, msg, data);
}
/\*\*
* 返回错误消息
*
* @return
*/
public static BaseResult error() {
return BaseResult.error(“操作失败”);
}
/\*\*
* 返回错误消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static BaseResult error(String msg) {
return BaseResult.error(msg, null);
}
/\*\*
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static BaseResult error(String msg, Object data) {
return new BaseResult(HttpStatus.ERROR, msg, data);
}
/\*\*
* 返回错误消息
*
* @param code 状态码
* @param msg 返回内容
* @return 警告消息
*/
public static BaseResult error(int code, String msg) {
return new BaseResult(code, msg, null);
}
}
##### 3.4.3、通用工具类
创建工具类包`utils`。
通用`Jackson`工具类`MapperUtils`
package com.micromaple.my.project.common.utils;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Jackson 工具类
* Title: MapperUtils
* Description:
*
* @author Micromaple
*/
public class MapperUtils {
private final static ObjectMapper objectMapper = new ObjectMapper();
public static ObjectMapper getInstance() {
return objectMapper;
}
/\*\*
* 转换为 JSON 字符串
*
* @param obj
* @return
* @throws Exception
*/
public static String obj2json(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (Exception e) {
e.printStackTrace();
}
return “”;
}
/\*\*
* 转换为 JSON 字符串,忽略空值
*
* @param obj
* @return
* @throws Exception
*/
public static String obj2jsonIgnoreNull(Object obj) throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return mapper.writeValueAsString(obj);
}
/\*\*
* 转换为 JavaBean
*
* @param jsonString
* @param clazz
* @return
* @throws Exception
*/
public static T json2pojo(String jsonString, Class clazz){
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
try{
return objectMapper.readValue(jsonString, clazz);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
/\*\*
* 字符串转换为 Map<String, Object>
*
* @param jsonString
* @return
* @throws Exception
*/
public static Map<String, Object> json2map(String jsonString){
if(StringUtils.isBlank(jsonString)) return null;
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
try {
return mapper.readValue(jsonString, Map.class);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/\*\*
* 深度转换 JSON 成 Map
*
* @param json
* @return
*/
public static Map<String, Object> json2mapDeeply(String json) throws Exception {
return json2MapRecursion(json, objectMapper);
}
/\*\*
* 把 JSON 解析成 List,如果 List 内部的元素存在 jsonString,继续解析
*
* @param json
* @param mapper 解析工具
* @return
* @throws Exception
*/
private static List json2ListRecursion(String json, ObjectMapper mapper) throws Exception {
if (json == null) {
return null;
}
List<Object> list = mapper.readValue(json, List.class);
for (Object obj : list) {
if (obj != null && obj instanceof String) {
String str = (String) obj;
if (str.startsWith("[")) {
obj = json2ListRecursion(str, mapper);
} else if (obj.toString().startsWith("{")) {
obj = json2MapRecursion(str, mapper);
}
}
}
return list;
}
/\*\*
* 把 JSON 解析成 Map,如果 Map 内部的 Value 存在 jsonString,继续解析
*
* @param json
* @param mapper
* @return
* @throws Exception
*/
private static Map<String, Object> json2MapRecursion(String json, ObjectMapper mapper) throws Exception {
if (json == null) {
return null;
}
Map<String, Object> map = mapper.readValue(json, Map.class);
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object obj = entry.getValue();
if (obj != null && obj instanceof String) {
String str = ((String) obj);
if (str.startsWith("[")) {
List<?> list = json2ListRecursion(str, mapper);
map.put(entry.getKey(), list);
} else if (str.startsWith("{")) {
Map<String, Object> mapRecursion = json2MapRecursion(str, mapper);
map.put(entry.getKey(), mapRecursion);
}
}
}
return map;
}
/\*\*
* 将 JSON 数组转换为集合
*
* @param jsonArrayStr
* @param clazz
* @return
* @throws Exception
*/
public static List json2list(String jsonArrayStr, Class clazz) throws Exception {
JavaType javaType = getCollectionType(ArrayList.class, clazz);
List list = (List) objectMapper.readValue(jsonArrayStr, javaType);
return list;
}
/\*\*
* 获取泛型的 Collection Type
*
* @param collectionClass 泛型的Collection
* @param elementClasses 元素类
* @return JavaType Java类型
* @since 1.0
*/
public static JavaType getCollectionType(Class<?> collectionClass, Class<?>… elementClasses) {
return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
}
/\*\*
* 将 Map 转换为 JavaBean
*
* @param map
* @param clazz
* @return
*/
public static T map2pojo(T map, Class clazz) {
return objectMapper.convertValue(map, clazz);
}
/\*\*
* 将 Map 转换为 JSON
*
* @param map
* @return
*/
public static String mapToJson(Map map) {
try {
return objectMapper.writeValueAsString(map);
} catch (Exception e) {
e.printStackTrace();
}
return “”;
}
/\*\*
* 将 JSON 对象转换为 JavaBean
*
* @param obj
* @param clazz
* @return
*/
public static T obj2pojo(Object obj, Class clazz) {
return objectMapper.convertValue(obj, clazz);
}
}
`HttpClient` 工具类
package com.micromaple.my.project.common.utils;
import com.google.common.collect.Maps;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
/**
* HttpClient 工具类
* Title: HttpClientUtils
* Description:
*
* @author Micromaple
*/
public class HttpClientUtils {
public static final String GET = "get";
public static final String POST = "post";
public static final String REQUEST_HEADER_CONNECTION = "keep-alive";
public static final String REQUEST_HEADER_CONTENTTYPE = "application/json;charset=UTF-8";
public static final String REQUEST_HEADER_CONSUMES = "application/json";
//设置连接超时时间,单位毫秒。
public static final int CONNECTTIMEOUT = 18000;
//请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。
public static final int SOCKETTIMEOUT = 60000;
//设置从connect Manager获取Connection 超时时间,单位毫秒
public static final int CONNECTIONREQUESTTIMEOUT = 18000;
/\*\*
* GET 请求
*
* @param url 请求地址
* @return
*/
public static String doGet(String url) {
return createRequest(url, GET, null, false, null, 0);
}
/\*\*
* GET 请求 - 代理
*
* @param url 请求地址
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @return
*/
public static String doGet(String url, boolean useProxy, String proxyHost, int proxyPort) {
return createRequest(url, GET, null, useProxy, proxyHost, proxyPort);
}
/\*\*
* GET 请求
*
* @param url 请求地址
* @param cookie cookie
* @return
*/
public static String doGet(String url, String cookie) {
return createRequest(url, GET, cookie, false, null, 0);
}
/\*\*
* POST 请求
*
* @param url 请求地址
* @param params 请求参数(可选)
* @return
*/
public static String doPost(String url, BasicNameValuePair… params) {
return createRequest(url, POST, null, false, null, 0, params);
}
/\*\*
* POST 请求 - 代理
*
* @param url 请求地址
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @param params 请求参数(可选)
* @return
*/
public static String doPost(String url, boolean useProxy, String proxyHost, int proxyPort, BasicNameValuePair… params) {
return createRequest(url, POST, null, useProxy, proxyHost, proxyPort, params);
}
/\*\*
* POST 请求
*
* @param url 请求地址
* @param cookie cookie
* @param params 请求参数(可选)
* @return
*/
public static String doPost(String url, String cookie, BasicNameValuePair… params) {
return createRequest(url, POST, cookie, false, null, 0, params);
}
/\*\*
* POST 请求 - 文本 方式
*
* @param url 请求地址
* @param jsonBodyParams 请求参数 (JSON 格式)
* @return
*/
public static String doPostForRow(String url, String jsonBodyParams) {
return createRequestForRow(url, jsonBodyParams, false, null, 0);
}
/\*\*
* POST 请求 - 文本 方式 - 代理
*
* @param url 请求地址
* @param jsonBodyParams 请求参数
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @return
*/
public static String doPostForRow(String url, String jsonBodyParams, boolean useProxy, String proxyHost, int proxyPort) {
return createRequestForRow(url, jsonBodyParams, useProxy, proxyHost, proxyPort);
}
/\*\*
* POST 请求
*
* @param url 请求地址
* @param pMap 请求参数
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @return
*/
public static Map<String, Object> doPost(String url, Map<String, String> pMap, boolean useProxy, String proxyHost, int proxyPort) {
String str = HttpClientUtils.doPost(url, useProxy, proxyHost, proxyPort, generatNameValuePair(pMap));
Map<String, Object> rtnMap = Maps.newHashMap();
try {
rtnMap = MapperUtils.json2map(str);
} catch (Exception e) {
e.printStackTrace();
}
return rtnMap;
}
/\*\*
* 创建请求
*
* @param url 请求地址
* @param requestMethod 请求方式 GET/POST
* @param cookie cookie
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @param params 请求参数 仅限于 POST 请求用
* @return
*/
private static String createRequest(String url, String requestMethod, String cookie, boolean useProxy, String proxyHost, int proxyPort, BasicNameValuePair… params) {
//创建 HTTPClient 客户端
// CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpClient httpClient = getHttpClient(useProxy, proxyHost, proxyPort);
String result = null;
try {
//请求结果
result = null;
//请求方式
HttpGet httpGet = null;
HttpPost httpPost = null;
//响应
CloseableHttpResponse httpResponse = null;
// GET 请求
if (GET.equals(requestMethod)) {
httpGet = new HttpGet(url);
httpGet.setHeader("Connection", REQUEST_HEADER_CONNECTION);
httpGet.setHeader("Cookie", cookie);
httpResponse = httpClient.execute(httpGet);
}
// POST 请求
else if (POST.equals(requestMethod)) {
httpPost = new HttpPost(url);
httpPost.setHeader("Connection", REQUEST_HEADER_CONNECTION);
httpPost.setHeader("Cookie", cookie);
//有参数进来
if (params != null && params.length > 0) {
httpPost.setEntity(new UrlEncodedFormEntity(Arrays.asList(params), "UTF-8"));
}
httpResponse = httpClient.execute(httpPost);
}
HttpEntity httpEntity = httpResponse.getEntity();
result = EntityUtils.toString(httpEntity);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
/\*\*
* 创建 ROW POST 请求
*
* @param url 请求地址
* @param jsonBodyParam 请求参数 (JSON 格式)
* @param useProxy 是否需要代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @return
*/
private static String createRequestForRow(String url, String jsonBodyParam, boolean useProxy, String proxyHost, int proxyPort) {
//创建 HTTPClient 客户端
// CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpClient httpClient = getHttpClient(useProxy, proxyHost, proxyPort);
String result = null;
try {
//请求结果
result = null;
//请求方式
HttpPost httpPost = null;
//响应
CloseableHttpResponse httpResponse = null;
httpPost = new HttpPost(url);
httpPost.setHeader("Connection", REQUEST_HEADER_CONNECTION);
httpPost.setHeader("Content-Type", REQUEST_HEADER_CONTENTTYPE);
httpPost.setHeader("consumes", REQUEST_HEADER_CONSUMES);
httpPost.setEntity(new StringEntity(jsonBodyParam, "UTF-8"));
httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
result = EntityUtils.toString(httpEntity);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (httpClient != null) {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
/\*\*
* 创建 HttpClient 客户端
*
* @param useProxy 是否代理
* @param proxyHost 代理地址
* @param proxyPort 代理端口
* @return
*/
private static CloseableHttpClient getHttpClient(boolean useProxy, String proxyHost, int proxyPort) {
CloseableHttpClient httpClient = null;
if (useProxy) {
//设置代理IP、端口、协议
HttpHost proxy = new HttpHost(proxyHost, proxyPort, “http”);
//把代理设置到请求配置
//setConnectTimeout:设置连接超时时间,单位毫秒。
//setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。
//setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(CONNECTTIMEOUT)
.setSocketTimeout(SOCKETTIMEOUT)
.setConnectionRequestTimeout(CONNECTIONREQUESTTIMEOUT)
.setProxy(proxy)
.build();
//创建 HTTPClient 客户端
httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
} else {
//setConnectTimeout:设置连接超时时间,单位毫秒。
//setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。
//setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(CONNECTTIMEOUT)
.setSocketTimeout(SOCKETTIMEOUT)
.setConnectionRequestTimeout(CONNECTIONREQUESTTIMEOUT)
.build();
//创建 HTTPClient 客户端
httpClient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();
}
return httpClient;
}
/\*\*
* MAP类型数组转换成BasicNameValuePair类型
*
* @param properties MAP类型数组
* @return BasicNameValuePair类型数组
*/
private static BasicNameValuePair[] generatNameValuePair(Map<String, String> properties) {
BasicNameValuePair[] basicNameValuePairs = new BasicNameValuePair[properties.size()];
int i = 0;
for (Map.Entry<String, String> entry : properties.entrySet()) {
basicNameValuePairs[i++] = new BasicNameValuePair(entry.getKey(), entry.getValue());
}
return basicNameValuePairs;
}
}
创建好后,目录结构效果如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/3fb4d3708568469ca43fafd133e5ccc9.jpeg#pic_center)
### 四、创建项目服务模块
#### 4.1、创建项目服务模块工程
创建一个名称为 `my-project-server`的项目,该项目负责实现具体业务,以及提供服务。
`pom.xml`内容如下:
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
<parent>
<groupId>com.micromaple</groupId>
<artifactId>my-project-dependencies</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../my-project-dependencies/pom.xml</relativePath>
</parent>
<artifactId>my-project-server</artifactId>
<packaging>jar</packaging>
<name>my-project-server</name>
<dependencies>
<!-- Project Begin -->
<dependency>
<groupId>com.micromaple</groupId>
<artifactId>my-project-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<!-- Project End -->
<!-- Spring Boot Begin -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Spring Boot End -->
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<!-- Environment Begin -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Environment End -->
<!-- Common Begin -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
<!-- Common End -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass></mainClass>
</configuration>
</plugin>
</plugins>
</build>
#### 4.2、Maven托管
可以使用右侧的`Maven` 的 `+` 号来进行项目的托管。
#### 4.3、完善目录结构
创建 `src/main/java` 和 `src/main/resource` 目录
在 `src/main/java` 目录下创建包名,包名为:`com.micromaple.my.project.server`
在 `src/main/resource` 目录下创建`application.yml`,内容如下:
Spring配置
spring:
jackson:
#时间戳统一转换为指定格式
date-format: yyyy-MM-dd HH:mm:ss
# 时区修改为东8区
time-zone: GMT+8
server:
port: 8899
#### 4.4、创建 Application
这里使用 Spring 提供的 MyBatis 包扫面注解
package com.micromaple.my.project.server;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(value = “com.micromaple.my.project.server.mapper”)
public class MyProjectServerApplication {
public static void main(String[] args) {
SpringApplication.run(MyProjectServerApplication.class, args);
}
}
在 `pom.xml` 中的 mainClass 指定该 Application
org.springframework.boot spring-boot-maven-plugin com.micromaple.my.project.server.MyProjectServerApplication
#### 4.5、整合 Logback
在 `src/main/resource` 目录下创建`logback-spring.xml`,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${logPatternExp}</pattern>
</encoder>
</appender>
<appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logBase}${logName}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${logBase}${logName}-%d{yyyy-MM-dd}-%i.zip</fileNamePattern>
<maxHistory>180</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>30MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>${logPatternExp}</pattern>
</encoder>
</appender>
<!-- project default level -->
<logger name="com.micromaple.my.project.server" level="DEBUG" />
<logger name="org.springframework" level="ERROR" />
<!-- root -->
<root level="DEBUG">
<appender-ref ref="console" />
<appender-ref ref="rollingFile" />
</root>
在`application.yml`增加配置:
logging:
config: classpath:logback-spring.xml
#### 4.6、整合 Druid 数据库连接池
在 `src/main/resource` 目录下创建`application-druid.yml`,内容如下:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.110.135:3306/my-project?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 123456
druid:
#连接池配置 初始化连接池的连接数量 大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall’用于防火墙
filter:
stat:
merge-sql: true
slow-sql-millis: 5000
#3.基础监控配置
web-stat-filter:
enabled: true
url-pattern: /*
#设置不统计哪些URL
exclusions: “*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*”
session-stat-enable: true
session-stat-max-count: 100
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filter:
stat:
merge-sql: true
slow-sql-millis: 5000
#3.基础监控配置
web-stat-filter:
enabled: true
url-pattern: /*
#设置不统计哪些URL
exclusions: "\*.js,\*.gif,\*.jpg,\*.png,\*.css,\*.ico,/druid/\*"
session-stat-enable: true
session-stat-max-count: 100
[外链图片转存中…(img-ky4DJVlk-1715756744920)]
[外链图片转存中…(img-yt0X59CA-1715756744920)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!