【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

相关推荐
uzong1 小时前
技术故障复盘模版
后端
GetcharZp1 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程2 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研2 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi2 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
阿华的代码王国3 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy3 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack4 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt
bobz9655 小时前
pip install 已经不再安全
后端
寻月隐君5 小时前
硬核实战:从零到一,用 Rust 和 Axum 构建高性能聊天服务后端
后端·rust·github