主要包含:springboot+jpa+hibernate+mysql+lombok
(两年前写过一个,现在重新记录一个)
- 目录结构:
- pom 文件
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <groupId>com.test</groupId>
6 <artifactId>demo</artifactId>
7 <version>0.0.1-SNAPSHOT</version>
8 <name>demo</name>
9 <description>demo for Spring Boot</description>
10 <properties>
11 <java.version>1.8</java.version>
12 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
14 <spring-boot.version>2.6.13</spring-boot.version>
15 </properties>
16 <dependencies>
17 <dependency>
18 <groupId>org.springframework.boot</groupId>
19 <artifactId>spring-boot-starter-web</artifactId>
20 </dependency>
21 <dependency>
22 <groupId>org.springframework.boot</groupId>
23 <artifactId>spring-boot-starter-data-jpa</artifactId>
24 </dependency>
25 <dependency>
26 <groupId>com.querydsl</groupId>
27 <artifactId>querydsl-jpa</artifactId>
28 <version>4.1.4</version>
29 </dependency>
30 <dependency>
31 <groupId>com.querydsl</groupId>
32 <artifactId>querydsl-apt</artifactId>
33 <version>4.1.4</version>
34 </dependency>
35 <dependency>
36 <groupId>com.alibaba</groupId>
37 <artifactId>fastjson</artifactId>
38 <version>2.0.32</version>
39 </dependency>
40 <dependency>
41 <groupId>commons-lang</groupId>
42 <artifactId>commons-lang</artifactId>
43 <version>2.6</version>
44 </dependency>
45 <dependency>
46 <groupId>org.apache.httpcomponents</groupId>
47 <artifactId>httpclient</artifactId>
48 <version>4.5.13</version>
49 </dependency>
50 <dependency>
51 <groupId>mysql</groupId>
52 <artifactId>mysql-connector-java</artifactId>
53 <version>8.0.19</version>
54 </dependency>
55 <dependency>
56 <groupId>org.projectlombok</groupId>
57 <artifactId>lombok</artifactId>
58 <optional>true</optional>
59 </dependency>
60 <dependency>
61 <groupId>org.springframework.boot</groupId>
62 <artifactId>spring-boot-starter-test</artifactId>
63 <scope>test</scope>
64 </dependency>
65 </dependencies>
66 <dependencyManagement>
67 <dependencies>
68 <dependency>
69 <groupId>org.springframework.boot</groupId>
70 <artifactId>spring-boot-dependencies</artifactId>
71 <version>${spring-boot.version}</version>
72 <type>pom</type>
73 <scope>import</scope>
74 </dependency>
75 </dependencies>
76 </dependencyManagement>
77
78 <build>
79 <plugins>
80 <plugin>
81 <groupId>org.apache.maven.plugins</groupId>
82 <artifactId>maven-compiler-plugin</artifactId>
83 <version>3.8.1</version>
84 <configuration>
85 <source>1.8</source>
86 <target>1.8</target>
87 <encoding>UTF-8</encoding>
88 </configuration>
89 </plugin>
90 <plugin>
91 <groupId>org.springframework.boot</groupId>
92 <artifactId>spring-boot-maven-plugin</artifactId>
93 <version>${spring-boot.version}</version>
94 <configuration>
95 <includeSystemScope>true</includeSystemScope>
96 <mainClass>com.tst.demo.demoApplication</mainClass>
97 </configuration>
98 <executions>
99 <execution>
100 <id>repackage</id>
101 <goals>
102 <goal>repackage</goal>
103 </goals>
104 </execution>
105 </executions>
106 </plugin>
107 </plugins>
108 </build>
109 <!-- 配置阿里云仓库 -->
110 <repositories>
111 <repository>
112 <id>dzh-public</id>
113 <name>dzh maven</name>
114 <url>https://maven.aliyun.com/repository/public/</url>
115 <releases>
116 <enabled>true</enabled>
117 </releases>
118 </repository>
119 </repositories>
120
121 <pluginRepositories>
122 <pluginRepository>
123 <id>dzh-public-plugin</id>
124 <name>dzh nexus plugin</name>
125 <url>https://maven.aliyun.com/repository/public/</url>
126 <releases>
127 <enabled>true</enabled>
128 </releases>
129 <snapshots>
130 <enabled>false</enabled>
131 </snapshots>
132 </pluginRepository>
133 </pluginRepositories>
134
135 </project>
View Code
- 启动类
package com.test.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
- 配置文件
application.yml
server:
websocket:
max-text-message-buffer-size: 9MB
max-binary-message-buffer-size: 9MB
application:
target-url: https://xxx # 全局配置逻辑配置
spring:
resources:
static-locations: file:D:\\\\demo\\static\\ #对应服务器内映射的实际路径
mvc:
static-path-pattern: /static/** #对应服务通过url访问静态文件夹时的前缀
servlet:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 100MB
jpa:
database: MYSQL
profiles:
active: dev
application-dev.yml
server:
port: 8081
# ssl: # 证书自行配置
# key-store: classpath:keystore.p12
# key-store-password: 123456
# key-password: 123456
# key-store-type: PKCS12
# key-alias: tomcat
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: xxx
application-prod.yml与上述基本一致,部分配置自行调整
- 配置类
package com.test.demo.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "application", ignoreUnknownFields = false)
public class ApplicationProperties {
private String targetUrl;
}
View Code
静态文件夹
package com.test.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//将所有/static/** 访问都映射到classpath:/static/ 目录下
registry.addResourceHandler("/static/**").addResourceLocations("file:D:\\demo\\static\\");
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
// .allowedOrigins("*")
.allowedOriginPatterns("*")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.maxAge(3600)
.allowCredentials(true);
}
}
View Code
RestTemplate全局配置(忽略证书验证)
package com.test.demo.config;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.SSLContext;
import java.nio.charset.Charset;
import java.util.List;
@Configuration
public class RestTemplateConfig {
@Bean("restTemplate")
public RestTemplate RestTemplate() {
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(30000);
httpRequestFactory.setConnectTimeout(30000);
httpRequestFactory.setReadTimeout(30000);
return new RestTemplate(httpRequestFactory);
}
/**
* 用于https请求,忽略认证
* @return unSSLRestTemplate
*/
@Bean("unSSLRestTemplate")
public RestTemplate restTemplateHttps() {
RestTemplate restTemplate = null;
try {
TrustStrategy acceptingTrustStrategy = (chain, authType) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
HttpClientBuilder clientBuilder = HttpClients.custom();
CloseableHttpClient httpClient = clientBuilder.setSSLSocketFactory(sslsf).build();
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(30000);
httpRequestFactory.setConnectTimeout(30000);
httpRequestFactory.setReadTimeout(30000);
httpRequestFactory.setHttpClient(httpClient);
restTemplate = new RestTemplate(httpRequestFactory);
//解决乱码
List<HttpMessageConverter<?>> httpMessageConverters = restTemplate.getMessageConverters();
httpMessageConverters.stream().forEach(httpMessageConverter ->{
if(httpMessageConverter instanceof StringHttpMessageConverter){
StringHttpMessageConverter messageConverter = (StringHttpMessageConverter)httpMessageConverter;
messageConverter.setDefaultCharset(Charset.forName("UTF-8"));
}
});
} catch (Exception e) {
e.printStackTrace();
}
return restTemplate;
}
}
View Code
- 实体类
示例
package com.test.demo.domain;
import lombok.Data;
import javax.persistence.*;
import java.time.Instant;
@Data
@Entity
@Table(name = "xxx_log")
public class XXXLog {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "default")
@TableGenerator(name = "default")
@SequenceGenerator(name = "default", sequenceName = "HIBERNATE_SEQUENCE")
private Long id;
private int status_code;
private Instant create_time = Instant.now();
private String event_type;
private String event_desc;
private String target_url;
}
View Code
- repository
示例
package com.test.demo.repository;
import com.test.demo.domain.XXXLog;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface XXXLogRepository extends JpaRepository<XXXLog, String> {
List<XXXLog> findAll();
}
View Code
- service
示例
package com.test.demo.service;
import com.test.demo.domain.XXXLog;
import com.test.demo.repository.XXXLogRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.UUID;
@Service
@Slf4j
public class LogService {
@Autowired
private XXXLogRepository xxxLogRepository;
public String save(HttpServletRequest request) {
String eventUid = String.valueOf(UUID.randomUUID());
log.info("记录开始时间 uid : " + eventUid + "事件ID codeId: " + eventUid + " start");
XXXLog xxxLog = new XXXLog();
xxxLog.setTarget_url("xxx");
xxxLog.setEvent_desc("xxx");
xxxLogRepository.save(xxxLog);
log.info("记录停止时间 uid : " + eventUid + "事件ID codeId: " + eventUid + " start");
return eventUid;
}
}
View Code
- 测试接口(get & post)
package com.test.demo.demos.web;
import com.test.demo.bean.ApiResult;
import com.test.demo.bean.XXXData;
import com.test.demo.service.LogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@Slf4j
@RestController
@RequestMapping("evn")
public class EventDemoController {
@Autowired
private LogService logService;
@GetMapping("/test")
@ResponseBody
public ApiResult getMeetingInfo(String xx) throws IOException {
log.info("XX: start");
// xx
log.info("XX: end");
return ApiResult.ok("ok");
}
@PostMapping("/log")
@ResponseBody
public ApiResult login(@RequestBody XXXData data, HttpServletRequest request) {
log.info("visit save -----------start");
String eventUid = logService.save(request);
log.info("visit save -----------end");
return ApiResult.ok(eventUid);
}
}
View Code
- 测试Bean
ApiResult
package com.test.demo.bean;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiResult implements Serializable {
private int code;
private String msg;
private Object data;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime timestamp;
public static <T> ApiResult ok() {
ApiResult apiResult = new ApiResult();
apiResult.setCode(ApiStatus.OK.getCode());
apiResult.setMsg(ApiStatus.OK.getMsg());
apiResult.setData(null);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult ok(String msg) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(ApiStatus.OK.getCode());
apiResult.setMsg(msg);
apiResult.setData(null);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult ok(int code, T data) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(code);
apiResult.setMsg(ApiStatus.OK.getMsg());
apiResult.setData(data);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult ok(T data) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(ApiStatus.OK.getCode());
apiResult.setMsg(ApiStatus.OK.getMsg());
apiResult.setData(data);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult ok(String msg, Object data) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(ApiStatus.OK.getCode());
apiResult.setMsg(msg);
apiResult.setData(data);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult fail() {
ApiResult apiResult = new ApiResult();
apiResult.setCode(ApiStatus.FAIL.getCode());
apiResult.setMsg(ApiStatus.FAIL.getMsg());
apiResult.setData(null);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult fail(String failMsg) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(ApiStatus.FAIL.getCode());
apiResult.setMsg(failMsg);
apiResult.setData(null);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult fail(int code, String failMsg) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(code);
apiResult.setMsg(failMsg);
apiResult.setData(null);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult fail(int code, String failMsg, T data) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(code);
apiResult.setMsg(failMsg);
apiResult.setData(data);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult fail(String failMsg, T data) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(ApiStatus.FAIL.getCode());
apiResult.setMsg(failMsg);
apiResult.setData(data);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult error() {
ApiResult apiResult = new ApiResult();
apiResult.setCode(ApiStatus.ERROR.getCode());
apiResult.setMsg(ApiStatus.ERROR.getMsg());
apiResult.setData(null);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult error(String exMsg) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(ApiStatus.ERROR.getCode());
apiResult.setMsg(exMsg);
apiResult.setData(null);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult error(String exMsg, T data) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(ApiStatus.ERROR.getCode());
apiResult.setMsg(exMsg);
apiResult.setData(data);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public static <T> ApiResult instance(ApiStatus apiStatus) {
ApiResult apiResult = new ApiResult();
apiResult.setCode(apiStatus.getCode());
apiResult.setMsg(apiStatus.getMsg());
apiResult.setData(null);
apiResult.setTimestamp(LocalDateTime.now());
return apiResult;
}
public boolean isFail() {
return this.code != ApiStatus.OK.getCode();
}
public boolean isSuccess() {
return this.code == ApiStatus.OK.getCode();
}
}
View Code
ApiStatus
package com.test.demo.bean;
import org.springframework.http.HttpStatus;
public enum ApiStatus {
OK(200, "请求成功"),
FAIL(400, "请求失败"),
UNAUTHORIZED(HttpStatus.UNAUTHORIZED.value(), "非法访问"),
FORBIDDEN(HttpStatus.FORBIDDEN.value(), "无权访问"),
NOT_FOUND(HttpStatus.NOT_FOUND.value(), "请求资源不存在"),
ERROR(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务内部异常");
private final int code;
private final String msg;
ApiStatus(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
View Code
XXXData
package com.test.demo.bean;
import lombok.Data;
@Data
public class XXXData {
private String codeId;
private String target;
}
View Code
- 数据库SQL
CREATE DATABASE IF NOT EXISTS `demo` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `demo`;
DROP TABLE IF EXISTS `c_sys_conf`;
CREATE TABLE `xxx_log` (
`id` decimal(38,0) NOT NULL COMMENT '主键',
`status_code` int DEFAULT NULL COMMENT '状态码',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`event_type` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '操作类型',
`event_desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '操作描述',
`target_url` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '目的地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='测试的日志记录表';
DROP TABLE IF EXISTS `hibernate_sequence`;
CREATE TABLE `hibernate_sequence` (
`next_val` bigint DEFAULT NULL,
`sequence_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
PRIMARY KEY (`sequence_name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
LOCK TABLES `hibernate_sequence` WRITE;
INSERT INTO `hibernate_sequence` VALUES (1,'default');
UNLOCK TABLES;
12 .gitignore
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
View Code