【SpringBoot Demo】MySQL + JPA + Hibernate + Springboot + Maven Demo

主要包含:springboot+jpa+hibernate+mysql+lombok

(两年前写过一个,现在重新记录一个)

  1. 目录结构:
  1. 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

  1. 启动类
复制代码
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);
    }

}
  1. 配置文件

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与上述基本一致,部分配置自行调整

  1. 配置类
复制代码
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

  1. 实体类

示例

复制代码
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

  1. 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

  1. 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

  1. 测试接口(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

  1. 测试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

  1. 数据库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

相关推荐
hanglove_lucky37 分钟前
本地摄像头视频流在html中打开
前端·后端·html
皓木.2 小时前
(自用)配置文件优先级、SpringBoot原理、Maven私服
java·spring boot·后端
i7i8i9com2 小时前
java 1.8+springboot文件上传+vue3+ts+antdv
java·spring boot·后端
秋意钟2 小时前
Spring框架处理时间类型格式
java·后端·spring
我叫啥都行2 小时前
计算机基础复习12.22
java·jvm·redis·后端·mysql
Stark、3 小时前
【Linux】文件IO--fcntl/lseek/阻塞与非阻塞/文件偏移
linux·运维·服务器·c语言·后端
coding侠客3 小时前
Spring Boot 多数据源解决方案:dynamic-datasource-spring-boot-starter 的奥秘
java·spring boot·后端
37手游后端团队5 小时前
谈谈golang的错误处理
后端
Q_19284999065 小时前
基于Spring Boot的大学就业信息管理系统
java·spring boot·后端