feat: 练题模块框架
This commit is contained in:
@@ -18,11 +18,6 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>3.8.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
package com.landaiqing;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hello world!
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class App
|
|
||||||
{
|
|
||||||
public static void main( String[] args )
|
|
||||||
{
|
|
||||||
System.out.println( "Hello World!" );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,38 +0,0 @@
|
|||||||
package com.landaiqing;
|
|
||||||
|
|
||||||
import junit.framework.Test;
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
import junit.framework.TestSuite;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unit test for simple App.
|
|
||||||
*/
|
|
||||||
public class AppTest
|
|
||||||
extends TestCase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Create the test case
|
|
||||||
*
|
|
||||||
* @param testName name of the test case
|
|
||||||
*/
|
|
||||||
public AppTest( String testName )
|
|
||||||
{
|
|
||||||
super( testName );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the suite of tests being tested
|
|
||||||
*/
|
|
||||||
public static Test suite()
|
|
||||||
{
|
|
||||||
return new TestSuite( AppTest.class );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rigourous Test :-)
|
|
||||||
*/
|
|
||||||
public void testApp()
|
|
||||||
{
|
|
||||||
assertTrue( true );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -18,11 +18,6 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>3.8.1</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
package com.landaiqing;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hello world!
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class App
|
|
||||||
{
|
|
||||||
public static void main( String[] args )
|
|
||||||
{
|
|
||||||
System.out.println( "Hello World!" );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,38 +0,0 @@
|
|||||||
package com.landaiqing;
|
|
||||||
|
|
||||||
import junit.framework.Test;
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
import junit.framework.TestSuite;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unit test for simple App.
|
|
||||||
*/
|
|
||||||
public class AppTest
|
|
||||||
extends TestCase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Create the test case
|
|
||||||
*
|
|
||||||
* @param testName name of the test case
|
|
||||||
*/
|
|
||||||
public AppTest( String testName )
|
|
||||||
{
|
|
||||||
super( testName );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the suite of tests being tested
|
|
||||||
*/
|
|
||||||
public static Test suite()
|
|
||||||
{
|
|
||||||
return new TestSuite( AppTest.class );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rigourous Test :-)
|
|
||||||
*/
|
|
||||||
public void testApp()
|
|
||||||
{
|
|
||||||
assertTrue( true );
|
|
||||||
}
|
|
||||||
}
|
|
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>8</maven.compiler.source>
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
<maven.compiler.target>8</maven.compiler.target>
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
50
qing-yu-practice/pom.xml
Normal file
50
qing-yu-practice/pom.xml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.landaiqing</groupId>
|
||||||
|
<artifactId>qing-yu-practice</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<modules>
|
||||||
|
<module>qing-yu-practice-api</module>
|
||||||
|
<module>qing-yu-practice-server</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<spring-boot.version>2.4.2</spring-boot.version>
|
||||||
|
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
|
||||||
|
<spring-cloud.version>2020.0.6</spring-cloud.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>2.4.2</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>central</id>
|
||||||
|
<name>aliyun maven</name>
|
||||||
|
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||||
|
<layout>default</layout>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
</project>
|
26
qing-yu-practice/qing-yu-practice-api/pom.xml
Normal file
26
qing-yu-practice/qing-yu-practice-api/pom.xml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.landaiqing</groupId>
|
||||||
|
<artifactId>qing-yu-practice</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>qing-yu-practice-api</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.28</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
@@ -0,0 +1,29 @@
|
|||||||
|
package com.landaiqing.practice.api.common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页请求实体
|
||||||
|
*
|
||||||
|
* @author: landaiqing
|
||||||
|
*/
|
||||||
|
public class PageInfo {
|
||||||
|
|
||||||
|
private Integer pageNo = 1;
|
||||||
|
|
||||||
|
private Integer pageSize = 20;
|
||||||
|
|
||||||
|
public Integer getPageNo() {
|
||||||
|
if (pageNo == null || pageNo < 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return pageNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getPageSize() {
|
||||||
|
if (pageSize == null || pageSize < 1 || pageSize > Integer.MAX_VALUE) {
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
return pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,57 @@
|
|||||||
|
package com.landaiqing.practice.api.common;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页返回实体
|
||||||
|
*
|
||||||
|
* @author: landaiqing
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PageResult<T> implements Serializable {
|
||||||
|
|
||||||
|
private Integer pageNo = 1;
|
||||||
|
|
||||||
|
private Integer pageSize = 20;
|
||||||
|
|
||||||
|
private Integer total = 0;
|
||||||
|
|
||||||
|
private Integer totalPages = 0;
|
||||||
|
|
||||||
|
private List<T> result = Collections.emptyList();
|
||||||
|
|
||||||
|
private Integer start = 1;
|
||||||
|
|
||||||
|
private Integer end = 0;
|
||||||
|
|
||||||
|
public void setRecords(List<T> result) {
|
||||||
|
this.result = result;
|
||||||
|
if (result != null && result.size() > 0) {
|
||||||
|
setTotal(result.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotal(Integer total) {
|
||||||
|
this.total = total;
|
||||||
|
if (this.pageSize > 0) {
|
||||||
|
this.totalPages = (total / this.pageSize) + (total % this.pageSize == 0 ? 0 : 1);
|
||||||
|
} else {
|
||||||
|
this.totalPages = 0;
|
||||||
|
}
|
||||||
|
this.start = (this.pageSize > 0 ? (this.pageNo - 1) * this.pageSize : 0) + 1;
|
||||||
|
this.end = (this.start - 1 + this.pageSize * (this.pageNo > 0 ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPageSize(Integer pageSize) {
|
||||||
|
this.pageSize = pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPageNo(Integer pageNo) {
|
||||||
|
this.pageNo = pageNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,50 @@
|
|||||||
|
package com.landaiqing.practice.api.common;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Result<T> {
|
||||||
|
|
||||||
|
private Boolean success;
|
||||||
|
|
||||||
|
private Integer code;
|
||||||
|
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
public static Result ok(){
|
||||||
|
Result result = new Result();
|
||||||
|
result.setSuccess(true);
|
||||||
|
result.setCode(ResultCodeEnum.SUCCESS.getCode());
|
||||||
|
result.setMessage(ResultCodeEnum.SUCCESS.getDesc());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result ok(T data){
|
||||||
|
Result result = new Result();
|
||||||
|
result.setSuccess(true);
|
||||||
|
result.setCode(ResultCodeEnum.SUCCESS.getCode());
|
||||||
|
result.setMessage(ResultCodeEnum.SUCCESS.getDesc());
|
||||||
|
result.setData(data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result fail(){
|
||||||
|
Result result = new Result();
|
||||||
|
result.setSuccess(false);
|
||||||
|
result.setCode(ResultCodeEnum.FAIL.getCode());
|
||||||
|
result.setMessage(ResultCodeEnum.FAIL.getDesc());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Result fail(T data){
|
||||||
|
Result result = new Result();
|
||||||
|
result.setSuccess(false);
|
||||||
|
result.setCode(ResultCodeEnum.FAIL.getCode());
|
||||||
|
result.setMessage(ResultCodeEnum.FAIL.getDesc());
|
||||||
|
result.setData(data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
package com.landaiqing.practice.api.common;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public enum ResultCodeEnum {
|
||||||
|
|
||||||
|
SUCCESS(200,"成功"),
|
||||||
|
FAIL(500,"失败");
|
||||||
|
|
||||||
|
public int code;
|
||||||
|
|
||||||
|
public String desc;
|
||||||
|
|
||||||
|
ResultCodeEnum(int code,String desc){
|
||||||
|
this.code = code;
|
||||||
|
this.desc = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResultCodeEnum getByCode(int codeVal){
|
||||||
|
for(ResultCodeEnum resultCodeEnum : ResultCodeEnum.values()){
|
||||||
|
if(resultCodeEnum.code == codeVal){
|
||||||
|
return resultCodeEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,30 @@
|
|||||||
|
package com.landaiqing.practice.api.enums;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 删除状态枚举
|
||||||
|
*
|
||||||
|
* @author landaiqing
|
||||||
|
* @date: 2024/2/14 15:02
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum IsDeletedFlagEnum {
|
||||||
|
DELETED(1,"已删除"),
|
||||||
|
UN_DELETED(0,"未删除");
|
||||||
|
private int code;
|
||||||
|
private String desc;
|
||||||
|
|
||||||
|
IsDeletedFlagEnum(int code, String desc){
|
||||||
|
this.code=code;
|
||||||
|
this.desc=desc;
|
||||||
|
}
|
||||||
|
public static IsDeletedFlagEnum getByCode(int codeVal){
|
||||||
|
for(IsDeletedFlagEnum resultCodeEnum: IsDeletedFlagEnum.values()){
|
||||||
|
if(resultCodeEnum.code==codeVal){
|
||||||
|
return resultCodeEnum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1 @@
|
|||||||
|
api的入参实体
|
@@ -0,0 +1 @@
|
|||||||
|
api的出参实体
|
169
qing-yu-practice/qing-yu-practice-server/pom.xml
Normal file
169
qing-yu-practice/qing-yu-practice-server/pom.xml
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.landaiqing</groupId>
|
||||||
|
<artifactId>qing-yu-practice</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>qing-yu-practice-server</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>qing-yu-practice-server</name>
|
||||||
|
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<spring-boot.version>2.4.2</spring-boot.version>
|
||||||
|
<spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
|
||||||
|
<spring-cloud.version>2020.0.6</spring-cloud.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<version>2.4.2</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>spring-boot-starter-logging</artifactId>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.18.28</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct</artifactId>
|
||||||
|
<version>1.4.2.Final</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mapstruct</groupId>
|
||||||
|
<artifactId>mapstruct-processor</artifactId>
|
||||||
|
<version>1.4.2.Final</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||||
|
<version>2.4.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>1.2.79</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>19.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.11</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.8.6</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
<version>2.4.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-pool2</artifactId>
|
||||||
|
<version>2.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||||
|
<version>2.4.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
|
<version>1.1.22</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.33</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
<version>3.4.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||||
|
<version>3.0.6</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>${spring-cloud.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||||
|
<version>${spring-cloud-alibaba.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<!--打包成jar包时的名字-->
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<version>2.3.0.RELEASE</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@@ -0,0 +1,21 @@
|
|||||||
|
package com.landaiqing.practice.server;
|
||||||
|
|
||||||
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 练习微服务启动类
|
||||||
|
*
|
||||||
|
* @author: landaiqing
|
||||||
|
* @date: 2024/2/7
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
@ComponentScan("com.landaiqing")
|
||||||
|
@MapperScan("com.landaiqing.**.dao")
|
||||||
|
public class PracticeApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(PracticeApplication.class);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,44 @@
|
|||||||
|
package com.landaiqing.practice.server.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import com.landaiqing.practice.server.config.interceptor.LoginInterceptor;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Classname GlobalConfig
|
||||||
|
* @BelongsProject: qing-yu-club
|
||||||
|
* @BelongsPackage: com.landaiqing.subject.application.config
|
||||||
|
* @Author: landaiqing
|
||||||
|
* @CreateTime: 2024-02-16 15:57
|
||||||
|
* @Description: MVC全局处理
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class GlobalConfig extends WebMvcConfigurationSupport {
|
||||||
|
@Override
|
||||||
|
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
|
super.configureMessageConverters(converters);
|
||||||
|
converters.add(mappingJackson2HttpMessageConverter());
|
||||||
|
}
|
||||||
|
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
|
||||||
|
ObjectMapper objectMapper=new ObjectMapper();
|
||||||
|
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
|
||||||
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||||
|
MappingJackson2HttpMessageConverter converter=new MappingJackson2HttpMessageConverter(objectMapper);
|
||||||
|
return converter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
registry.addInterceptor(new LoginInterceptor())
|
||||||
|
.addPathPatterns("/**");
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,42 @@
|
|||||||
|
package com.landaiqing.practice.server.config.context;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Classname LoginContextHolder
|
||||||
|
* @BelongsProject: qing-yu-club
|
||||||
|
* @BelongsPackage: com.landaiqing.subject.application.context
|
||||||
|
* @Author: landaiqing
|
||||||
|
* @CreateTime: 2024-03-03 18:11
|
||||||
|
* @Description: 登录上下文对象
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
public class LoginContextHolder {
|
||||||
|
private static final InheritableThreadLocal <Map<String,Object>> THREAD_LOCAL=new InheritableThreadLocal<>();
|
||||||
|
|
||||||
|
public static void set(String key,Object val){
|
||||||
|
Map<String,Object> map=getThreadLoacalMap();
|
||||||
|
map.put(key, val);
|
||||||
|
}
|
||||||
|
public static Object get(String key){
|
||||||
|
Map<String,Object> threadLoacalMap=getThreadLoacalMap();
|
||||||
|
return threadLoacalMap.get(key);
|
||||||
|
}
|
||||||
|
public static void remove(){
|
||||||
|
THREAD_LOCAL.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLoginId(){
|
||||||
|
return (String) getThreadLoacalMap().get("loginId");
|
||||||
|
}
|
||||||
|
public static Map<String,Object> getThreadLoacalMap(){
|
||||||
|
Map<String,Object> map =THREAD_LOCAL.get();
|
||||||
|
if (Objects.isNull(map)){
|
||||||
|
map=new ConcurrentHashMap<>();
|
||||||
|
THREAD_LOCAL.set(map);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,35 @@
|
|||||||
|
package com.landaiqing.practice.server.config.interceptor;
|
||||||
|
|
||||||
|
|
||||||
|
import com.landaiqing.practice.server.config.context.LoginContextHolder;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Classname LoginInterceptor
|
||||||
|
* @BelongsProject: qing-yu-club
|
||||||
|
* @BelongsPackage: com.landaiqing.subject.application.interceptor
|
||||||
|
* @Author: landaiqing
|
||||||
|
* @CreateTime: 2024-03-03 18:05
|
||||||
|
* @Description: 登录拦截器
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
public class LoginInterceptor implements HandlerInterceptor {
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
String loginId = request.getHeader("loginId");
|
||||||
|
if (StringUtils.isNotBlank(loginId)) {
|
||||||
|
LoginContextHolder.set("loginId", loginId);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
|
||||||
|
LoginContextHolder.remove();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,17 @@
|
|||||||
|
package com.landaiqing.practice.server.config.mybatis;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class MybatisConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MybatisPlusInterceptor mybatisPlusInterceptor(){
|
||||||
|
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
|
||||||
|
mybatisPlusInterceptor.addInnerInterceptor(new MybatisPlusAllSqlLog());
|
||||||
|
return mybatisPlusInterceptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,116 @@
|
|||||||
|
package com.landaiqing.practice.server.config.mybatis;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
|
||||||
|
import org.apache.ibatis.executor.Executor;
|
||||||
|
import org.apache.ibatis.mapping.BoundSql;
|
||||||
|
import org.apache.ibatis.mapping.MappedStatement;
|
||||||
|
import org.apache.ibatis.mapping.ParameterMapping;
|
||||||
|
import org.apache.ibatis.reflection.MetaObject;
|
||||||
|
import org.apache.ibatis.session.Configuration;
|
||||||
|
import org.apache.ibatis.session.ResultHandler;
|
||||||
|
import org.apache.ibatis.session.RowBounds;
|
||||||
|
import org.apache.ibatis.type.TypeHandlerRegistry;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
public class MybatisPlusAllSqlLog implements InnerInterceptor {
|
||||||
|
public static final Logger log = LoggerFactory.getLogger("sys-sql");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
|
||||||
|
logInfo(boundSql, ms, parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) throws SQLException {
|
||||||
|
BoundSql boundSql = ms.getBoundSql(parameter);
|
||||||
|
logInfo(boundSql, ms, parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void logInfo(BoundSql boundSql, MappedStatement ms, Object parameter) {
|
||||||
|
try {
|
||||||
|
log.info("parameter = " + parameter);
|
||||||
|
// 获取到节点的id,即sql语句的id
|
||||||
|
String sqlId = ms.getId();
|
||||||
|
log.info("sqlId = " + sqlId);
|
||||||
|
// 获取节点的配置
|
||||||
|
Configuration configuration = ms.getConfiguration();
|
||||||
|
// 获取到最终的sql语句
|
||||||
|
String sql = getSql(configuration, boundSql, sqlId);
|
||||||
|
log.info("完整的sql:{}", sql);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("异常:{}", e.getLocalizedMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 封装了一下sql语句,使得结果返回完整xml路径下的sql语句节点id + sql语句
|
||||||
|
public static String getSql(Configuration configuration, BoundSql boundSql, String sqlId) {
|
||||||
|
return sqlId + ":" + showSql(configuration, boundSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进行?的替换
|
||||||
|
public static String showSql(Configuration configuration, BoundSql boundSql) {
|
||||||
|
// 获取参数
|
||||||
|
Object parameterObject = boundSql.getParameterObject();
|
||||||
|
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
|
||||||
|
// sql语句中多个空格都用一个空格代替
|
||||||
|
String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
|
||||||
|
if (!CollectionUtils.isEmpty(parameterMappings) && parameterObject != null) {
|
||||||
|
// 获取类型处理器注册器,类型处理器的功能是进行java类型和数据库类型的转换
|
||||||
|
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
|
||||||
|
// 如果根据parameterObject.getClass()可以找到对应的类型,则替换
|
||||||
|
if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
|
||||||
|
sql = sql.replaceFirst("\\?",
|
||||||
|
Matcher.quoteReplacement(getParameterValue(parameterObject)));
|
||||||
|
} else {
|
||||||
|
// MetaObject主要是封装了originalObject对象,提供了get和set的方法用于获取和设置originalObject的属性值,主要支持对JavaBean、Collection、Map三种类型对象的操作
|
||||||
|
MetaObject metaObject = configuration.newMetaObject(parameterObject);
|
||||||
|
for (ParameterMapping parameterMapping : parameterMappings) {
|
||||||
|
String propertyName = parameterMapping.getProperty();
|
||||||
|
if (metaObject.hasGetter(propertyName)) {
|
||||||
|
Object obj = metaObject.getValue(propertyName);
|
||||||
|
sql = sql.replaceFirst("\\?",
|
||||||
|
Matcher.quoteReplacement(getParameterValue(obj)));
|
||||||
|
} else if (boundSql.hasAdditionalParameter(propertyName)) {
|
||||||
|
// 该分支是动态sql
|
||||||
|
Object obj = boundSql.getAdditionalParameter(propertyName);
|
||||||
|
sql = sql.replaceFirst("\\?",
|
||||||
|
Matcher.quoteReplacement(getParameterValue(obj)));
|
||||||
|
} else {
|
||||||
|
// 打印出缺失,提醒该参数缺失并防止错位
|
||||||
|
sql = sql.replaceFirst("\\?", "缺失");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果参数是String,则添加单引号, 如果是日期,则转换为时间格式器并加单引号; 对参数是null和不是null的情况作了处理
|
||||||
|
private static String getParameterValue(Object obj) {
|
||||||
|
String value;
|
||||||
|
if (obj instanceof String) {
|
||||||
|
value = "'" + obj.toString() + "'";
|
||||||
|
} else if (obj instanceof Date) {
|
||||||
|
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT,
|
||||||
|
DateFormat.DEFAULT, Locale.CHINA);
|
||||||
|
value = "'" + formatter.format(new Date()) + "'";
|
||||||
|
} else {
|
||||||
|
if (obj != null) {
|
||||||
|
value = obj.toString();
|
||||||
|
} else {
|
||||||
|
value = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,52 @@
|
|||||||
|
package com.landaiqing.practice.server.config.mybatis;
|
||||||
|
|
||||||
|
import org.apache.ibatis.cache.CacheKey;
|
||||||
|
import org.apache.ibatis.executor.Executor;
|
||||||
|
import org.apache.ibatis.mapping.BoundSql;
|
||||||
|
import org.apache.ibatis.mapping.MappedStatement;
|
||||||
|
import org.apache.ibatis.plugin.*;
|
||||||
|
import org.apache.ibatis.session.ResultHandler;
|
||||||
|
import org.apache.ibatis.session.RowBounds;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
|
||||||
|
@Intercepts({
|
||||||
|
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class,
|
||||||
|
Object.class}),
|
||||||
|
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class,
|
||||||
|
Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})})
|
||||||
|
public class SqlStatementInterceptor implements Interceptor {
|
||||||
|
|
||||||
|
public static final Logger log = LoggerFactory.getLogger("sys-sql");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object intercept(Invocation invocation) throws Throwable {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
return invocation.proceed();
|
||||||
|
} finally {
|
||||||
|
long timeConsuming = System.currentTimeMillis() - startTime;
|
||||||
|
log.info("执行SQL:{}ms", timeConsuming);
|
||||||
|
if (timeConsuming > 999 && timeConsuming < 5000) {
|
||||||
|
log.info("执行SQL大于1s:{}ms", timeConsuming);
|
||||||
|
} else if (timeConsuming >= 5000 && timeConsuming < 10000) {
|
||||||
|
log.info("执行SQL大于5s:{}ms", timeConsuming);
|
||||||
|
} else if (timeConsuming >= 10000) {
|
||||||
|
log.info("执行SQL大于10s:{}ms", timeConsuming);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object plugin(Object target) {
|
||||||
|
return Plugin.wrap(target, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties(Properties properties) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,46 @@
|
|||||||
|
package com.landaiqing.practice.server.config.redis;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
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.RedisSerializer;
|
||||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis的config处理
|
||||||
|
*
|
||||||
|
* @author: landaiqing
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RedisConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||||
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||||
|
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
|
||||||
|
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||||
|
redisTemplate.setKeySerializer(redisSerializer);
|
||||||
|
redisTemplate.setHashKeySerializer(redisSerializer);
|
||||||
|
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
|
||||||
|
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer());
|
||||||
|
return redisTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() {
|
||||||
|
Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||||
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||||
|
jsonRedisSerializer.setObjectMapper(objectMapper);
|
||||||
|
return jsonRedisSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,141 @@
|
|||||||
|
package com.landaiqing.practice.server.config.redis;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.data.redis.core.Cursor;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.ScanOptions;
|
||||||
|
import org.springframework.data.redis.core.ZSetOperations;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RedisUtil工具类
|
||||||
|
*
|
||||||
|
* @author: landaiqing
|
||||||
|
* @date: 2024/2/19
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class RedisUtil {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
private static final String CACHE_KEY_SEPARATOR = ".";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建缓存key
|
||||||
|
*/
|
||||||
|
public String buildKey(String... strObjs) {
|
||||||
|
return Stream.of(strObjs).collect(Collectors.joining(CACHE_KEY_SEPARATOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否存在key
|
||||||
|
*/
|
||||||
|
public boolean exist(String key) {
|
||||||
|
return redisTemplate.hasKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除key
|
||||||
|
*/
|
||||||
|
public boolean del(String key) {
|
||||||
|
return redisTemplate.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set(不带过期)
|
||||||
|
*/
|
||||||
|
public void set(String key, String value) {
|
||||||
|
redisTemplate.opsForValue().set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set(带过期)
|
||||||
|
*/
|
||||||
|
public boolean setNx(String key, String value, Long time, TimeUnit timeUnit) {
|
||||||
|
return redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取string类型缓存
|
||||||
|
*/
|
||||||
|
public String get(String key) {
|
||||||
|
return (String) redisTemplate.opsForValue().get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean zAdd(String key, String value, Long score) {
|
||||||
|
return redisTemplate.opsForZSet().add(key, value, Double.valueOf(String.valueOf(score)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long countZset(String key) {
|
||||||
|
return redisTemplate.opsForZSet().size(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> rangeZset(String key, long start, long end) {
|
||||||
|
return redisTemplate.opsForZSet().range(key, start, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long removeZset(String key, Object value) {
|
||||||
|
return redisTemplate.opsForZSet().remove(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeZsetList(String key, Set<String> value) {
|
||||||
|
value.stream().forEach((val) -> redisTemplate.opsForZSet().remove(key, val));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double score(String key, Object value) {
|
||||||
|
return redisTemplate.opsForZSet().score(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> rangeByScore(String key, long start, long end) {
|
||||||
|
return redisTemplate.opsForZSet().rangeByScore(key, Double.valueOf(String.valueOf(start)), Double.valueOf(String.valueOf(end)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object addScore(String key, Object obj, double score) {
|
||||||
|
return redisTemplate.opsForZSet().incrementScore(key, obj, score);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object rank(String key, Object obj) {
|
||||||
|
return redisTemplate.opsForZSet().rank(key, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Set rankWithScore(String key, long start, long end) {
|
||||||
|
Set<ZSetOperations.TypedTuple<String>> set = redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putHash(String key, String hashKey, Object hashVal) {
|
||||||
|
redisTemplate.opsForHash().put(key, hashKey, hashVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getInt(String key) {
|
||||||
|
return (Integer) redisTemplate.opsForValue().get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void increment(String key, Integer count) {
|
||||||
|
redisTemplate.opsForValue().increment(key,count);
|
||||||
|
}
|
||||||
|
public Map<Object, Object> getHashAndDelete(String key) {
|
||||||
|
Map<Object, Object> map = new HashMap<>();
|
||||||
|
Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(key, ScanOptions.NONE);
|
||||||
|
while (cursor.hasNext()) {
|
||||||
|
Map.Entry<Object, Object> entry = cursor.next();
|
||||||
|
Object hashKey = entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
map.put(hashKey, value);
|
||||||
|
redisTemplate.opsForHash().delete(key, hashKey);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,24 @@
|
|||||||
|
package com.landaiqing.practice.server.controller;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Classname DemoController
|
||||||
|
* @BelongsProject: qing-yu-club
|
||||||
|
* @BelongsPackage: com.landaiqing.practice.server.controller
|
||||||
|
* @Author: landaiqing
|
||||||
|
* @CreateTime: 2024-03-10 17:22
|
||||||
|
* @Description: 测试controller启动
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("practice")
|
||||||
|
@Slf4j
|
||||||
|
public class DemoController {
|
||||||
|
@RequestMapping("/test")
|
||||||
|
public String isLogin() {
|
||||||
|
return "test " ;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1 @@
|
|||||||
|
存放dao
|
@@ -0,0 +1 @@
|
|||||||
|
存放实体
|
@@ -0,0 +1 @@
|
|||||||
|
存放service
|
@@ -0,0 +1,48 @@
|
|||||||
|
package com.landaiqing.practice.server.util;
|
||||||
|
|
||||||
|
import com.alibaba.druid.filter.config.ConfigTools;
|
||||||
|
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库加密util
|
||||||
|
*
|
||||||
|
* @author: landaiqing
|
||||||
|
* @date: 2024/2/7
|
||||||
|
*/
|
||||||
|
public class DruidEncryptUtil {
|
||||||
|
|
||||||
|
private static String publicKey;
|
||||||
|
|
||||||
|
private static String privateKey;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
String[] keyPair = ConfigTools.genKeyPair(512);
|
||||||
|
privateKey=keyPair[0];
|
||||||
|
System.out.println("privateKey:"+privateKey);
|
||||||
|
publicKey=keyPair[1];
|
||||||
|
System.out.println("publicKey:"+publicKey);
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} catch (NoSuchProviderException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static String encrypt(String plainText) throws Exception {
|
||||||
|
String encrypt = ConfigTools.encrypt(privateKey, plainText);
|
||||||
|
System.out.println("encrypt:"+encrypt);
|
||||||
|
return encrypt;
|
||||||
|
}
|
||||||
|
public static String decrypt(String encryptText) throws Exception {
|
||||||
|
String decrypt = ConfigTools.decrypt(publicKey, encryptText);
|
||||||
|
System.out.println("decrypt:"+decrypt);
|
||||||
|
return decrypt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
String encrypt = encrypt("$LDQ20020618xxx$");
|
||||||
|
System.out.println("encrypt:"+encrypt);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,54 @@
|
|||||||
|
server:
|
||||||
|
port: 3012
|
||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
username: landaiqing
|
||||||
|
password: HvUtEzfJSLoCY8Oe+6BFhen8RM90h0Jmz/a8uHR/z90Ech1iksWHTeroWXjY+OZhsamVwDmJzPGJfKf2RiXFgA==
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://116.196.80.239:3306/qing-yu-club?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true
|
||||||
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
druid:
|
||||||
|
initial-size: 20
|
||||||
|
min-idle: 20
|
||||||
|
max-active: 100
|
||||||
|
max-wait: 60000
|
||||||
|
connectionProperties: config.decrypt=true;config.decrypt.key=${publicKey};
|
||||||
|
stat-view-servlet:
|
||||||
|
enabled: true
|
||||||
|
url-pattern: /druid/*
|
||||||
|
login-username: admin
|
||||||
|
login-password: 123456
|
||||||
|
filter:
|
||||||
|
stat:
|
||||||
|
enabled: true
|
||||||
|
slow-sql-millis: 2000
|
||||||
|
log-slow-sql: true
|
||||||
|
wall:
|
||||||
|
enabled: true
|
||||||
|
config:
|
||||||
|
enabled: true
|
||||||
|
# redis配置
|
||||||
|
redis:
|
||||||
|
# Redis数据库索引(默认为0)
|
||||||
|
database: 0
|
||||||
|
# Redis服务器地址
|
||||||
|
host: 116.196.80.239
|
||||||
|
# Redis服务器连接端口
|
||||||
|
port: 6379
|
||||||
|
# Redis服务器连接密码(默认为空)
|
||||||
|
password: LDQ20020618xxx
|
||||||
|
# 连接超时时间
|
||||||
|
timeout: 2s
|
||||||
|
lettuce:
|
||||||
|
pool:
|
||||||
|
# 连接池最大连接数
|
||||||
|
max-active: 200
|
||||||
|
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||||
|
max-wait: -1ms
|
||||||
|
# 连接池中的最大空闲连接
|
||||||
|
max-idle: 10
|
||||||
|
# 连接池中的最小空闲连接
|
||||||
|
min-idle: 0
|
||||||
|
publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJ9zUefu5PFeiy4nNNRCIaNT5IY3IxRrlHMiotffSPstMensKg4PoSWJsRRrp/zQEzWegxz2Bkv3F5vfGqqM9N0CAwEAAQ==
|
||||||
|
logging:
|
||||||
|
config: classpath:log4j2-spring.xml
|
@@ -0,0 +1,17 @@
|
|||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: qing-yu-club-practice-dev
|
||||||
|
profiles:
|
||||||
|
active: dev
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
config:
|
||||||
|
server-addr: 116.196.80.239:8848
|
||||||
|
prefix: ${spring.application.name}
|
||||||
|
group: DEFAULT_GROUP
|
||||||
|
namespace:
|
||||||
|
file-extension: yaml
|
||||||
|
discovery:
|
||||||
|
enabled: true
|
||||||
|
server-addr: 116.196.80.239:8848
|
||||||
|
|
@@ -0,0 +1,87 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
|
||||||
|
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
|
||||||
|
<configuration status="INFO" monitorInterval="5">
|
||||||
|
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
|
||||||
|
<!--变量配置-->
|
||||||
|
<Properties>
|
||||||
|
<!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
|
||||||
|
<!-- %logger{36} 表示 Logger 名字最长36个字符 -->
|
||||||
|
<property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} %X{PFTID} [%thread] %-5level %logger{36} - %msg%n" />
|
||||||
|
<!-- 定义日志存储的路径 -->
|
||||||
|
<property name="FILE_PATH" value="../log" />
|
||||||
|
<property name="FILE_NAME" value="qing-yuClub-Practice.log" />
|
||||||
|
</Properties>
|
||||||
|
|
||||||
|
<!--https://logging.apache.org/log4j/2.x/manual/appenders.html-->
|
||||||
|
<appenders>
|
||||||
|
|
||||||
|
<console name="Console" target="SYSTEM_OUT">
|
||||||
|
<!--输出日志的格式-->
|
||||||
|
<PatternLayout pattern="${LOG_PATTERN}"/>
|
||||||
|
<!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
|
||||||
|
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||||
|
</console>
|
||||||
|
|
||||||
|
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
|
||||||
|
<File name="fileLog" fileName="${FILE_PATH}/temp.log" append="false">
|
||||||
|
<PatternLayout pattern="${LOG_PATTERN}"/>
|
||||||
|
</File>
|
||||||
|
|
||||||
|
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
|
||||||
|
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz">
|
||||||
|
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
|
||||||
|
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||||
|
<PatternLayout pattern="${LOG_PATTERN}"/>
|
||||||
|
<Policies>
|
||||||
|
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
|
||||||
|
<TimeBasedTriggeringPolicy interval="1"/>
|
||||||
|
<SizeBasedTriggeringPolicy size="10MB"/>
|
||||||
|
</Policies>
|
||||||
|
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
|
||||||
|
<DefaultRolloverStrategy max="15"/>
|
||||||
|
</RollingFile>
|
||||||
|
|
||||||
|
<!-- 这个会打印出所有的warn及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
|
||||||
|
<RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz">
|
||||||
|
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
|
||||||
|
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||||
|
<PatternLayout pattern="${LOG_PATTERN}"/>
|
||||||
|
<Policies>
|
||||||
|
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
|
||||||
|
<TimeBasedTriggeringPolicy interval="1"/>
|
||||||
|
<SizeBasedTriggeringPolicy size="10MB"/>
|
||||||
|
</Policies>
|
||||||
|
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
|
||||||
|
<DefaultRolloverStrategy max="15"/>
|
||||||
|
</RollingFile>
|
||||||
|
|
||||||
|
<!-- 这个会打印出所有的error及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
|
||||||
|
<RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz">
|
||||||
|
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
|
||||||
|
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
|
||||||
|
<PatternLayout pattern="${LOG_PATTERN}"/>
|
||||||
|
<Policies>
|
||||||
|
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
|
||||||
|
<TimeBasedTriggeringPolicy interval="1"/>
|
||||||
|
<SizeBasedTriggeringPolicy size="10MB"/>
|
||||||
|
</Policies>
|
||||||
|
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
|
||||||
|
<DefaultRolloverStrategy max="15"/>
|
||||||
|
</RollingFile>
|
||||||
|
|
||||||
|
</appenders>
|
||||||
|
|
||||||
|
<!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
|
||||||
|
<!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
|
||||||
|
<loggers>
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="Console"/>
|
||||||
|
<appender-ref ref="RollingFileInfo"/>
|
||||||
|
<appender-ref ref="RollingFileWarn"/>
|
||||||
|
<appender-ref ref="RollingFileError"/>
|
||||||
|
<appender-ref ref="fileLog"/>
|
||||||
|
</root>
|
||||||
|
</loggers>
|
||||||
|
|
||||||
|
</configuration>
|
Reference in New Issue
Block a user