generated from mingliqiye/lib-tem
no message
All checks were successful
Gitea Actions Build / Build (push) Successful in 4m11s
All checks were successful
Gitea Actions Build / Build (push) Successful in 4m11s
This commit is contained in:
parent
d991b4077b
commit
fb4e103da8
2
.gitignore
vendored
2
.gitignore
vendored
@ -44,4 +44,4 @@ log
|
||||
.idea
|
||||
node_modules
|
||||
*lock*
|
||||
|
||||
.kotlin
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils
|
||||
* CurrentFile build.gradle.kts
|
||||
* LastUpdate 2025-09-12 14:06:21
|
||||
* LastUpdate 2025-09-13 10:11:22
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
@ -59,10 +59,6 @@ sourceSets {
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
|
||||
}
|
||||
|
||||
java {
|
||||
withSourcesJar()
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(8))
|
||||
@ -81,8 +77,11 @@ dependencies {
|
||||
implementation("com.github.f4b6a3:uuid-creator:6.1.0")
|
||||
implementation("org.mindrot:jbcrypt:0.4")
|
||||
implementation("org.jetbrains:annotations:24.0.0")
|
||||
implementation("net.java.dev.jna:jna:5.17.0")
|
||||
compileOnly("net.java.dev.jna:jna:5.17.0")
|
||||
implementation("jakarta.annotation:jakarta.annotation-api:2.1.1")
|
||||
implementation("org.slf4j:slf4j-api:2.0.17")
|
||||
implementation("com.mingliqiye.utils.jna:WinKernel32Api:1.0.1")
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -90,26 +89,10 @@ tasks.withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
tasks.register<Jar>("javaDocJar") {
|
||||
group = "build"
|
||||
archiveClassifier.set("javadoc")
|
||||
dependsOn(tasks.dokkaGfm, tasks.dokkaHtml, tasks.dokkaJavadoc, tasks.dokkaJekyll)
|
||||
from(buildDir.resolve("dokka/javadoc"))
|
||||
}
|
||||
tasks.register<Jar>("kotlinDocJar") {
|
||||
group = "build"
|
||||
archiveClassifier.set("kotlindoc")
|
||||
dependsOn(tasks.dokkaHtml)
|
||||
from(buildDir.resolve("dokka/html"))
|
||||
}
|
||||
tasks.build {
|
||||
dependsOn("javaDocJar", "kotlinDocJar")
|
||||
}
|
||||
|
||||
tasks.withType<JavaExec>().configureEach {
|
||||
jvmArgs = listOf(
|
||||
"-Dfile.encoding=UTF-8",
|
||||
"-Dsun.stdout.encoding=UTF-8",
|
||||
"-Dsun.stderr.encoding=UTF-8"
|
||||
"-Dfile.encoding=UTF-8", "-Dsun.stdout.encoding=UTF-8", "-Dsun.stderr.encoding=UTF-8"
|
||||
)
|
||||
}
|
||||
|
||||
@ -142,6 +125,7 @@ tasks.withType<org.gradle.jvm.tasks.Jar> {
|
||||
)
|
||||
}
|
||||
}
|
||||
val isJdk8Build = project.findProperty("buildForJdk8") == "true"
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
@ -150,6 +134,18 @@ repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
tasks.register<Jar>("javaDocJar") {
|
||||
group = "build"
|
||||
archiveClassifier.set("javadoc")
|
||||
dependsOn(tasks.dokkaJavadoc)
|
||||
from(buildDir.resolve("dokka/javadoc"))
|
||||
}
|
||||
tasks.register<Jar>("kotlinDocJar") {
|
||||
group = "build"
|
||||
archiveClassifier.set("kotlindoc")
|
||||
dependsOn(tasks.dokkaHtml)
|
||||
from(buildDir.resolve("dokka/html"))
|
||||
}
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
@ -160,39 +156,34 @@ publishing {
|
||||
publications {
|
||||
create<MavenPublication>("mavenJava") {
|
||||
from(components["java"])
|
||||
groupId = GROUPSID
|
||||
artifactId = ARTIFACTID
|
||||
version = VERSIONS
|
||||
artifact(tasks.named("javaDocJar"))
|
||||
artifact(tasks.named("kotlinDocJar"))
|
||||
pom {
|
||||
name.set(project.name)
|
||||
url.set("https://github.com/minglipro/mingli-utils")
|
||||
|
||||
licenses {
|
||||
license {
|
||||
name.set("Apache-2.0")
|
||||
url.set("https://opensource.org/licenses/Apache-2.0")
|
||||
}
|
||||
}
|
||||
}
|
||||
artifactId = ARTIFACTID
|
||||
java.toolchain.languageVersion.set(JavaLanguageVersion.of(8))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.build {
|
||||
dependsOn("javaDocJar", "kotlinDocJar")
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
tasks.processResources {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
outputs.upToDateWhen { false }
|
||||
filesMatching("META-INF/meta-data") {
|
||||
expand(
|
||||
mapOf(
|
||||
"buildTime" to LocalDateTime.now()
|
||||
.format(
|
||||
DateTimeFormatter.ofPattern(
|
||||
"yyyy-MM-dd HH:mm:ss.SSSSSSS"
|
||||
)
|
||||
project.properties + mapOf(
|
||||
"buildTime" to LocalDateTime.now().format(
|
||||
DateTimeFormatter.ofPattern(
|
||||
"yyyy-MM-dd HH:mm:ss.SSSSSSS"
|
||||
)
|
||||
) + project.properties
|
||||
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,10 +16,10 @@
|
||||
# ProjectName mingli-utils
|
||||
# ModuleName mingli-utils
|
||||
# CurrentFile gradle.properties
|
||||
# LastUpdate 2025-09-12 14:10:24
|
||||
# LastUpdate 2025-09-13 10:14:51
|
||||
# UpdateUser MingLiPro
|
||||
#
|
||||
JDKVERSIONS=1.8
|
||||
GROUPSID=com.mingliqiye.utils
|
||||
ARTIFACTID=mingli-utils
|
||||
VERSIONS=3.2.7
|
||||
VERSIONS=3.3.1
|
||||
|
||||
57
jdk8/build.gradle.kts
Normal file
57
jdk8/build.gradle.kts
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.jdk8
|
||||
* CurrentFile build.gradle.kts
|
||||
* LastUpdate 2025-09-14 18:19:04
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
plugins {
|
||||
id("java-library")
|
||||
id("maven-publish")
|
||||
}
|
||||
val GROUPSID = project.properties["GROUPSID"] as String
|
||||
val VERSIONS = project.properties["VERSIONS"] as String
|
||||
val ARTIFACTID = project.properties["ARTIFACTID"] as String
|
||||
version = VERSIONS
|
||||
group = GROUPSID
|
||||
|
||||
base.archivesName.set(ARTIFACTID)
|
||||
|
||||
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
name = "MavenRepositoryRaw"
|
||||
url = uri("C:/data/git/maven-repository-raw")
|
||||
}
|
||||
}
|
||||
publications {
|
||||
create<MavenPublication>("mavenJava") {
|
||||
from(components["java"])
|
||||
artifactId = "$ARTIFACTID-win-jdk8"
|
||||
groupId = GROUPSID
|
||||
version = VERSIONS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
java.toolchain.languageVersion.set(JavaLanguageVersion.of(8))
|
||||
dependencies {
|
||||
api(rootProject)
|
||||
implementation("com.mingliqiye.utils.jna:WinKernel32Platform:1.0.1")
|
||||
}
|
||||
@ -16,9 +16,10 @@
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils
|
||||
* CurrentFile settings.gradle.kts
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* LastUpdate 2025-09-13 02:37:04
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
include("jdk8")
|
||||
val ARTIFACTID: String by settings.extra
|
||||
rootProject.name = ARTIFACTID
|
||||
|
||||
@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile AesUtils.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.aes;
|
||||
|
||||
import com.mingliqiye.utils.base64.Base64Utils;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
public class AesUtils {
|
||||
|
||||
private static final String ALGORITHM = "AES";
|
||||
private static final String TRANSFORMATION = "AES/GCM/NoPadding";
|
||||
private static final int GCM_IV_LENGTH = 12;
|
||||
private static final int GCM_TAG_LENGTH = 16;
|
||||
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
|
||||
|
||||
/**
|
||||
* AES加密方法(使用GCM模式)
|
||||
* @param sSrc 待加密的字符串
|
||||
* @param sKey 加密密钥
|
||||
* @return 加密后的字符串,格式为 IV:EncryptedData+Tag(均为Base64编码)
|
||||
* @throws GeneralSecurityException 加密错误
|
||||
*/
|
||||
public static String encrypt(String sSrc, String sKey)
|
||||
throws GeneralSecurityException {
|
||||
if (sKey == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 生成密钥
|
||||
SecretKeySpec secretKeySpec = createSecretKey(sKey);
|
||||
|
||||
// 生成安全随机IV
|
||||
byte[] iv = new byte[GCM_IV_LENGTH];
|
||||
SECURE_RANDOM.nextBytes(iv);
|
||||
|
||||
// 初始化加密器
|
||||
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(
|
||||
GCM_TAG_LENGTH * 8,
|
||||
iv
|
||||
);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, gcmParameterSpec);
|
||||
|
||||
// 执行加密
|
||||
byte[] encrypted = cipher.doFinal(
|
||||
sSrc.getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
|
||||
// 将IV和加密数据(包含认证标签)组合返回
|
||||
return Base64Utils.encode(
|
||||
(Base64Utils.encode(iv) +
|
||||
":" +
|
||||
Base64Utils.encode(encrypted)).getBytes()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* AES解密方法(使用GCM模式)
|
||||
* @param sSrc 待解密的字符串,格式为 IV:EncryptedData+Tag(均为Base64编码)
|
||||
* @param sKey 解密密钥
|
||||
* @return 解密后的原始字符串
|
||||
*/
|
||||
public static String decrypt(String sSrc, String sKey) {
|
||||
if (sKey == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// 分割IV和加密数据
|
||||
String sSrcs = new String(Base64Utils.decode(sSrc));
|
||||
String[] parts = sSrcs.split(":", 2);
|
||||
if (parts.length != 2) {
|
||||
return null;
|
||||
}
|
||||
byte[] iv = Base64Utils.decode(parts[0]);
|
||||
byte[] encryptedData = Base64Utils.decode(parts[1]);
|
||||
if (iv.length != GCM_IV_LENGTH) {
|
||||
return null;
|
||||
}
|
||||
SecretKeySpec secretKeySpec = createSecretKey(sKey);
|
||||
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(
|
||||
GCM_TAG_LENGTH * 8,
|
||||
iv
|
||||
);
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec);
|
||||
byte[] original = cipher.doFinal(encryptedData);
|
||||
return new String(original, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建AES密钥,支持任意长度的密钥
|
||||
* @param sKey 字符串密钥
|
||||
* @return SecretKeySpec对象
|
||||
* @throws Exception 可能抛出的异常
|
||||
*/
|
||||
private static SecretKeySpec createSecretKey(String sKey)
|
||||
throws GeneralSecurityException {
|
||||
byte[] key = sKey.getBytes(StandardCharsets.UTF_8);
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] digest = md.digest(key);
|
||||
return new SecretKeySpec(digest, ALGORITHM);
|
||||
}
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile ByteUtil.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.bytes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author MingLiPro
|
||||
*
|
||||
* 字节数组处理工具类
|
||||
*/
|
||||
public class ByteUtil {
|
||||
|
||||
public static final byte ESC_ASC = 0x1A;
|
||||
public static final byte ESC_DESC = 0x1B;
|
||||
public static final byte ESC_NONE = 0x00;
|
||||
public static final byte ESC_START = 0x01;
|
||||
public static final byte ESC_END = 0x02;
|
||||
public static final byte ESC_ESC = 0x03;
|
||||
public static final byte ESC_CONTROL = 0x04;
|
||||
public static final byte ESC_DATA = 0x05;
|
||||
public static final byte ESC_RESERVED = 0x06;
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串列表
|
||||
* <p>
|
||||
* 每个字节都会被转换为两位的十六进制字符串表示形式
|
||||
* 例如: 字节值为10的字节会被转换为"0a",值为255的字节会被转换为"ff"
|
||||
*
|
||||
* @param bytes 输入的字节数组
|
||||
* @return 包含每个字节对应十六进制字符串的列表
|
||||
*/
|
||||
public static List<String> getByteArrayString(byte[] bytes) {
|
||||
List<Byte> byteList = new ArrayList<>(bytes.length);
|
||||
for (byte aByte : bytes) {
|
||||
byteList.add(aByte);
|
||||
}
|
||||
return byteList
|
||||
.stream()
|
||||
.map(a -> String.format("%02x", a & 0xFF))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@ -16,22 +16,20 @@
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile Lists.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* LastUpdate 2025-09-13 00:26:11
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.collection;
|
||||
|
||||
import static com.mingliqiye.utils.collection.Collection.findFirst;
|
||||
|
||||
import com.github.f4b6a3.uuid.util.internal.RandomUtil;
|
||||
import com.mingliqiye.utils.random.RandomInt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Lists工具类提供了一系列创建List实现的便捷方法。
|
||||
@ -457,6 +455,12 @@ public class Lists {
|
||||
return list;
|
||||
}
|
||||
|
||||
public static <T> List<T> toList(Iterator<T> iterator) {
|
||||
List<T> list = newArrayList(10);
|
||||
ForEach.forEach(iterator, item -> list.add(item));
|
||||
return list;
|
||||
}
|
||||
|
||||
public <T> T getFirst(Collection<T> collectors) {
|
||||
return com.mingliqiye.utils.collection.Collection.getFirst(collectors);
|
||||
}
|
||||
|
||||
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile FieldStructure.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.jna;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author MingLiPro
|
||||
*/
|
||||
public class FieldStructure extends Structure {
|
||||
|
||||
@Override
|
||||
protected List<String> getFieldOrder() {
|
||||
List<String> fieldOrderList = new ArrayList<>();
|
||||
for (
|
||||
Class<?> cls = getClass();
|
||||
!cls.equals(FieldStructure.class);
|
||||
cls = cls.getSuperclass()
|
||||
) {
|
||||
Field[] fields = cls.getDeclaredFields();
|
||||
int modifiers;
|
||||
for (Field field : fields) {
|
||||
modifiers = field.getModifiers();
|
||||
if (
|
||||
Modifier.isStatic(modifiers) ||
|
||||
!Modifier.isPublic(modifiers)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
fieldOrderList.add(field.getName());
|
||||
}
|
||||
}
|
||||
return fieldOrderList;
|
||||
}
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile WinKernel32.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.jna.time;
|
||||
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.ptr.LongByReference;
|
||||
|
||||
/**
|
||||
* @author MingLiPro
|
||||
*/
|
||||
public interface WinKernel32 extends Library {
|
||||
static WinKernel32 load() {
|
||||
return Native.load("kernel32", WinKernel32.class);
|
||||
}
|
||||
|
||||
boolean QueryPerformanceCounter(LongByReference lpPerformanceCount);
|
||||
boolean QueryPerformanceFrequency(LongByReference lpFrequency);
|
||||
void GetSystemTimePreciseAsFileTime(byte[] lpSystemTimeAsFileTime);
|
||||
}
|
||||
@ -16,22 +16,26 @@
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile AutoConfiguration.java
|
||||
* LastUpdate 2025-09-09 08:37:34
|
||||
* LastUpdate 2025-09-13 01:23:09
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.springboot.autoconfigure;
|
||||
|
||||
import com.mingliqiye.utils.collection.ForEach;
|
||||
import com.mingliqiye.utils.collection.Lists;
|
||||
import com.mingliqiye.utils.system.SystemUtil;
|
||||
import com.mingliqiye.utils.time.DateTime;
|
||||
import com.mingliqiye.utils.time.Formatter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import lombok.val;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@org.springframework.boot.autoconfigure.AutoConfiguration
|
||||
@EnableConfigurationProperties(AutoConfiguration.class)
|
||||
@ComponentScan(
|
||||
@ -80,7 +84,10 @@ public class AutoConfiguration {
|
||||
while ((readlen = inputStream.read(buffer)) != -1) {
|
||||
metaData.append(new String(buffer, 0, readlen));
|
||||
}
|
||||
ForEach.forEach(metaData.toString().split("\n"), (s, i) -> {
|
||||
val da = Lists.toList(metaData.toString().split("\n"));
|
||||
da.add("time=" + DateTime.now().format(Formatter.STANDARD_DATETIME_MILLISECOUND7));
|
||||
da.add("jdkRuntime=" + SystemUtil.getJdkVersion());
|
||||
ForEach.forEach(da, (s, i) -> {
|
||||
String[] d = s.trim().split("=", 2);
|
||||
if (d.length >= 2) {
|
||||
String content = "| " + d[0] + ": " + d[1];
|
||||
@ -100,9 +107,8 @@ public class AutoConfiguration {
|
||||
e.printStackTrace();
|
||||
}
|
||||
banner2 = bannerBuilder.toString();
|
||||
System.out.printf(
|
||||
banner2,
|
||||
DateTime.now().format(Formatter.STANDARD_DATETIME_MILLISECOUND7)
|
||||
System.out.print(
|
||||
banner2
|
||||
);
|
||||
System.out.println(
|
||||
"---------------------------------------------------------"
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile Main.java
|
||||
* LastUpdate 2025-09-12 12:19:48
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.test;
|
||||
|
||||
import com.mingliqiye.utils.version.VersionUtils;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(VersionUtils.is("1.3", "1.2.3"));
|
||||
}
|
||||
}
|
||||
@ -16,14 +16,22 @@
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile DateTime.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* LastUpdate 2025-09-13 10:14:09
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.time;
|
||||
|
||||
import com.mingliqiye.utils.jna.time.WinKernel32;
|
||||
import com.mingliqiye.utils.jna.WinKernel32Api;
|
||||
import com.mingliqiye.utils.jna.WinKernel32ApiFactory;
|
||||
import com.mingliqiye.utils.system.SystemUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.val;
|
||||
import lombok.var;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
@ -31,10 +39,10 @@ import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Date;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.var;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.mingliqiye.utils.jna.WinKernel32ApiFactory.FILETIME_EPOCH_OFFSET;
|
||||
import static com.mingliqiye.utils.jna.WinKernel32ApiFactory.NANOS_PER_100NS;
|
||||
import static com.mingliqiye.utils.logger.Loggers.getMingLiLoggerFactory;
|
||||
|
||||
/**
|
||||
* 时间类,用于处理日期时间的转换、格式化等操作。
|
||||
@ -54,15 +62,38 @@ import org.jetbrains.annotations.NotNull;
|
||||
@Setter
|
||||
public final class DateTime implements Serializable {
|
||||
|
||||
private static final WinKernel32 WIN_KERNEL_32;
|
||||
private static final long FILETIME_EPOCH_OFFSET = -116444736000000000L;
|
||||
private static final long NANOS_PER_100NS = 100;
|
||||
private static final WinKernel32Api WIN_KERNEL_32_API;
|
||||
|
||||
static {
|
||||
if (!SystemUtil.isJdk8Plus() && SystemUtil.isWindows()) {
|
||||
WIN_KERNEL_32 = WinKernel32.load();
|
||||
if (SystemUtil.getJavaVersionAsInteger() == 8 && SystemUtil.isWindows()) {
|
||||
|
||||
final Logger log = getMingLiLoggerFactory().getLogger(
|
||||
"mingli-utils DateTime"
|
||||
);
|
||||
val a = WinKernel32ApiFactory.getWinKernel32Apis();
|
||||
|
||||
if (a.size() > 1) {
|
||||
log.warn(
|
||||
"Multiple Size:{} WinKernel32Api implementations found.",
|
||||
a.size()
|
||||
);
|
||||
a.forEach(api ->
|
||||
log.warn(
|
||||
"Found WinKernel32Api: {}",
|
||||
api.getClass().getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (a.isEmpty()) {
|
||||
WIN_KERNEL_32_API = null;
|
||||
log.warn("No WinKernel32Api implementation found. Use Jdk1.8 LocalDateTime");
|
||||
} else {
|
||||
WIN_KERNEL_32_API = a.get(a.size() - 1);
|
||||
log.info("Found and Use WinKernel32Api: {}", WIN_KERNEL_32_API.getClass().getName());
|
||||
}
|
||||
} else {
|
||||
WIN_KERNEL_32 = null;
|
||||
WIN_KERNEL_32_API = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,26 +126,9 @@ public final class DateTime implements Serializable {
|
||||
* @return 返回当前时间的 DateTime 实例
|
||||
*/
|
||||
public static DateTime now() {
|
||||
if (WIN_KERNEL_32 != null) {
|
||||
byte[] fileTimeBuffer = new byte[8];
|
||||
WIN_KERNEL_32.GetSystemTimePreciseAsFileTime(fileTimeBuffer);
|
||||
long fileTime =
|
||||
(long) (fileTimeBuffer[0] & 0xFF) |
|
||||
((long) (fileTimeBuffer[1] & 0xFF) << 8) |
|
||||
((long) (fileTimeBuffer[2] & 0xFF) << 16) |
|
||||
((long) (fileTimeBuffer[3] & 0xFF) << 24) |
|
||||
((long) (fileTimeBuffer[4] & 0xFF) << 32) |
|
||||
((long) (fileTimeBuffer[5] & 0xFF) << 40) |
|
||||
((long) (fileTimeBuffer[6] & 0xFF) << 48) |
|
||||
((long) (fileTimeBuffer[7] & 0xFF) << 56);
|
||||
long unixNanos =
|
||||
(fileTime + FILETIME_EPOCH_OFFSET) * NANOS_PER_100NS;
|
||||
Instant instant = Instant.ofEpochSecond(
|
||||
unixNanos / 1_000_000_000L,
|
||||
unixNanos % 1_000_000_000L
|
||||
);
|
||||
if (WIN_KERNEL_32_API != null) {
|
||||
return DateTime.of(
|
||||
instant.atZone(ZoneId.systemDefault()).toLocalDateTime()
|
||||
WIN_KERNEL_32_API.getTime().atZone(ZoneId.systemDefault()).toLocalDateTime()
|
||||
);
|
||||
}
|
||||
return new DateTime();
|
||||
|
||||
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile MysqlUUIDv1.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.uuid;
|
||||
|
||||
import lombok.var;
|
||||
|
||||
/**
|
||||
* MySQL UUID格式与标准UUID格式相互转换工具类
|
||||
* <p>
|
||||
* MySQL使用不同的字节顺序存储UUID,此类提供了在MySQL格式和标准UUID格式之间转换的方法
|
||||
* @author MingLiPro
|
||||
*/
|
||||
public class MysqlUUIDv1 {
|
||||
|
||||
/**
|
||||
* 将标准UUID格式转换为MySQL格式的UUID
|
||||
*
|
||||
* @param uuid 标准UUID格式的字节数组,长度必须为16字节
|
||||
* @return MySQL格式的UUID字节数组,长度为16字节
|
||||
*/
|
||||
public static byte[] uuidToMysql(byte[] uuid) {
|
||||
var reuuid = new byte[16];
|
||||
// 转换时间戳低位部分
|
||||
reuuid[4] = uuid[0];
|
||||
reuuid[5] = uuid[1];
|
||||
reuuid[6] = uuid[2];
|
||||
reuuid[7] = uuid[3];
|
||||
|
||||
// 转换时间戳中位部分
|
||||
reuuid[2] = uuid[4];
|
||||
reuuid[3] = uuid[5];
|
||||
|
||||
// 转换时间戳高位部分
|
||||
reuuid[0] = uuid[6];
|
||||
reuuid[1] = uuid[7];
|
||||
|
||||
// 复制时钟序列和节点标识部分
|
||||
System.arraycopy(uuid, 8, reuuid, 8, 8);
|
||||
return reuuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将MySQL格式的UUID转换为标准UUID格式
|
||||
*
|
||||
* @param uuid MySQL格式的UUID字节数组,长度必须为16字节
|
||||
* @return 标准UUID格式的字节数组,长度为16字节
|
||||
*/
|
||||
public static byte[] mysqlToUuid(byte[] uuid) {
|
||||
var reuuid = new byte[16];
|
||||
// 转换时间戳高位部分
|
||||
reuuid[6] = uuid[0];
|
||||
reuuid[7] = uuid[1];
|
||||
|
||||
// 转换时间戳中位部分
|
||||
reuuid[4] = uuid[2];
|
||||
reuuid[5] = uuid[3];
|
||||
|
||||
// 转换时间戳低位部分
|
||||
reuuid[0] = uuid[4];
|
||||
reuuid[1] = uuid[5];
|
||||
reuuid[2] = uuid[6];
|
||||
reuuid[3] = uuid[7];
|
||||
|
||||
// 复制时钟序列和节点标识部分
|
||||
System.arraycopy(uuid, 8, reuuid, 8, 8);
|
||||
return reuuid;
|
||||
}
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile UUIDException.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.uuid;
|
||||
|
||||
public class UUIDException extends RuntimeException {
|
||||
|
||||
public UUIDException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public UUIDException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile UUIDConverter.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.uuid.typehandlers;
|
||||
|
||||
import com.mingliqiye.utils.uuid.MysqlUUIDv1;
|
||||
import com.mingliqiye.utils.uuid.UUID;
|
||||
|
||||
public class UUIDConverter {
|
||||
|
||||
public static String UUID_TO_STR(UUID uuid) {
|
||||
return uuid.toUUIDString();
|
||||
}
|
||||
|
||||
public static UUID STR_TO_UUID(String string) {
|
||||
return UUID.of(string);
|
||||
}
|
||||
|
||||
public static byte[] UUID_TO_BIN(UUID uuid) {
|
||||
return uuid.toBytes();
|
||||
}
|
||||
|
||||
public static UUID BIN_TO_UUID(byte[] bytes) {
|
||||
return UUID.of(bytes);
|
||||
}
|
||||
|
||||
public static byte[] MYSQL_UUID_TO_BIN(UUID uuid) {
|
||||
return MysqlUUIDv1.uuidToMysql(uuid.toBytes());
|
||||
}
|
||||
|
||||
public static UUID BIN_TO_MYSQL_UUID(byte[] bytes) {
|
||||
return UUID.of(MysqlUUIDv1.mysqlToUuid(bytes));
|
||||
}
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile UUIDBinaryTypeHandler.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.uuid.typehandlers.mysql;
|
||||
|
||||
import com.mingliqiye.utils.uuid.UUID;
|
||||
import com.mingliqiye.utils.uuid.typehandlers.UUIDConverter;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
|
||||
/**
|
||||
* UUIDBinaryTypeHandler 类用于处理 UUID 类型与数据库 BINARY 类型之间的转换
|
||||
* 该类继承自 BaseTypeHandler,专门处理 UUID 对象的序列化和反序列化
|
||||
*
|
||||
* @author MingLiPro
|
||||
*/
|
||||
@MappedTypes({ UUID.class })
|
||||
@MappedJdbcTypes(JdbcType.BINARY)
|
||||
public class UUIDBinaryTypeHandler extends BaseTypeHandler<UUID> {
|
||||
|
||||
/**
|
||||
* 设置非空参数到 PreparedStatement 中
|
||||
*
|
||||
* @param ps PreparedStatement 对象
|
||||
* @param i 参数在 SQL 语句中的位置索引
|
||||
* @param parameter 要设置的 UUID 参数值
|
||||
* @param jdbcType JDBC 类型信息
|
||||
* @throws SQLException 当数据库操作发生错误时抛出
|
||||
*/
|
||||
@Override
|
||||
public void setNonNullParameter(
|
||||
PreparedStatement ps,
|
||||
int i,
|
||||
UUID parameter,
|
||||
JdbcType jdbcType
|
||||
) throws SQLException {
|
||||
ps.setBytes(i, UUIDConverter.UUID_TO_BIN(parameter));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 ResultSet 中根据列名获取可为空的 UUID 结果
|
||||
*
|
||||
* @param rs ResultSet 对象
|
||||
* @param columnName 数据库列名
|
||||
* @return 转换后的 UUID 对象,可能为 null
|
||||
* @throws SQLException 当数据库操作发生错误时抛出
|
||||
*/
|
||||
@Override
|
||||
public UUID getNullableResult(ResultSet rs, String columnName)
|
||||
throws SQLException {
|
||||
return UUIDConverter.BIN_TO_UUID(rs.getBytes(columnName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 ResultSet 中根据列索引获取可为空的 UUID 结果
|
||||
*
|
||||
* @param rs ResultSet 对象
|
||||
* @param columnIndex 数据库列索引
|
||||
* @return 转换后的 UUID 对象,可能为 null
|
||||
* @throws SQLException 当数据库操作发生错误时抛出
|
||||
*/
|
||||
@Override
|
||||
public UUID getNullableResult(ResultSet rs, int columnIndex)
|
||||
throws SQLException {
|
||||
return UUIDConverter.BIN_TO_UUID(rs.getBytes(columnIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 CallableStatement 中根据参数索引获取可为空的 UUID 结果
|
||||
*
|
||||
* @param cs CallableStatement 对象
|
||||
* @param columnIndex 参数索引
|
||||
* @return 转换后的 UUID 对象,可能为 null
|
||||
* @throws SQLException 当数据库操作发生错误时抛出
|
||||
*/
|
||||
@Override
|
||||
public UUID getNullableResult(CallableStatement cs, int columnIndex)
|
||||
throws SQLException {
|
||||
return UUIDConverter.BIN_TO_UUID(cs.getBytes(columnIndex));
|
||||
}
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile UUIDStringTypeHandler.java
|
||||
* LastUpdate 2025-09-09 08:37:33
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.uuid.typehandlers.pgsql;
|
||||
|
||||
import com.mingliqiye.utils.uuid.UUID;
|
||||
import com.mingliqiye.utils.uuid.typehandlers.UUIDConverter;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
|
||||
/**
|
||||
* UUIDBinaryTypeHandler 类用于处理 UUID 类型与数据库 BINARY 类型之间的转换
|
||||
* 该类继承自 BaseTypeHandler,专门处理 UUID 对象的序列化和反序列化
|
||||
*
|
||||
* @author MingLiPro
|
||||
*/
|
||||
@MappedTypes({ UUID.class })
|
||||
@MappedJdbcTypes(JdbcType.VARCHAR)
|
||||
public class UUIDStringTypeHandler extends BaseTypeHandler<UUID> {
|
||||
|
||||
/**
|
||||
* 设置非空参数到 PreparedStatement 中
|
||||
*
|
||||
* @param ps PreparedStatement 对象
|
||||
* @param i 参数在 SQL 语句中的位置索引
|
||||
* @param parameter 要设置的 UUID 参数值
|
||||
* @param jdbcType JDBC 类型信息
|
||||
* @throws SQLException 当数据库操作发生错误时抛出
|
||||
*/
|
||||
@Override
|
||||
public void setNonNullParameter(
|
||||
PreparedStatement ps,
|
||||
int i,
|
||||
UUID parameter,
|
||||
JdbcType jdbcType
|
||||
) throws SQLException {
|
||||
ps.setString(i, UUIDConverter.UUID_TO_STR(parameter));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 ResultSet 中根据列名获取可为空的 UUID 结果
|
||||
*
|
||||
* @param rs ResultSet 对象
|
||||
* @param columnName 数据库列名
|
||||
* @return 转换后的 UUID 对象,可能为 null
|
||||
* @throws SQLException 当数据库操作发生错误时抛出
|
||||
*/
|
||||
@Override
|
||||
public UUID getNullableResult(ResultSet rs, String columnName)
|
||||
throws SQLException {
|
||||
return UUIDConverter.STR_TO_UUID(rs.getString(columnName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 ResultSet 中根据列索引获取可为空的 UUID 结果
|
||||
*
|
||||
* @param rs ResultSet 对象
|
||||
* @param columnIndex 数据库列索引
|
||||
* @return 转换后的 UUID 对象,可能为 null
|
||||
* @throws SQLException 当数据库操作发生错误时抛出
|
||||
*/
|
||||
@Override
|
||||
public UUID getNullableResult(ResultSet rs, int columnIndex)
|
||||
throws SQLException {
|
||||
return UUIDConverter.STR_TO_UUID(rs.getString(columnIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 CallableStatement 中根据参数索引获取可为空的 UUID 结果
|
||||
*
|
||||
* @param cs CallableStatement 对象
|
||||
* @param columnIndex 参数索引
|
||||
* @return 转换后的 UUID 对象,可能为 null
|
||||
* @throws SQLException 当数据库操作发生错误时抛出
|
||||
*/
|
||||
@Override
|
||||
public UUID getNullableResult(CallableStatement cs, int columnIndex)
|
||||
throws SQLException {
|
||||
return UUIDConverter.STR_TO_UUID(cs.getString(columnIndex));
|
||||
}
|
||||
}
|
||||
@ -24,12 +24,9 @@
|
||||
|
||||
package com.mingliqiye.utils
|
||||
|
||||
import com.mingliqiye.utils.path.OsPath
|
||||
import com.mingliqiye.utils.springboot.autoconfigure.AutoConfiguration
|
||||
|
||||
|
||||
fun main() {
|
||||
AutoConfiguration.printBanner()
|
||||
val path = OsPath.getCwd()
|
||||
println(path.toAbsolutePath())
|
||||
}
|
||||
|
||||
123
src/main/kotlin/com/mingliqiye/utils/aes/AesUtils.kt
Normal file
123
src/main/kotlin/com/mingliqiye/utils/aes/AesUtils.kt
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile AesUtils.kt
|
||||
* LastUpdate 2025-09-14 18:19:29
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
|
||||
@file:JvmName("AesUtils")
|
||||
|
||||
package com.mingliqiye.utils.aes
|
||||
|
||||
import com.mingliqiye.utils.base64.Base64Utils
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.security.GeneralSecurityException
|
||||
import java.security.MessageDigest
|
||||
import java.security.SecureRandom
|
||||
import javax.crypto.Cipher
|
||||
import javax.crypto.spec.GCMParameterSpec
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
|
||||
const val ALGORITHM = "AES"
|
||||
const val TRANSFORMATION = "AES/GCM/NoPadding"
|
||||
const val GCM_IV_LENGTH = 12
|
||||
const val GCM_TAG_LENGTH = 16
|
||||
val SECURE_RANDOM = SecureRandom()
|
||||
|
||||
|
||||
/**
|
||||
* AES加密方法(使用GCM模式)
|
||||
* @param sSrc 待加密的字符串
|
||||
* @param sKey 加密密钥
|
||||
* @return 加密后的字符串,格式为 IV:EncryptedData+Tag(均为Base64编码)
|
||||
* @throws GeneralSecurityException 加密错误
|
||||
*/
|
||||
@Throws(GeneralSecurityException::class)
|
||||
fun encrypt(sSrc: String, sKey: String?): String? {
|
||||
if (sKey == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 生成密钥
|
||||
val secretKeySpec = createSecretKey(sKey)
|
||||
|
||||
// 生成安全随机IV
|
||||
val iv = ByteArray(GCM_IV_LENGTH)
|
||||
SECURE_RANDOM.nextBytes(iv)
|
||||
|
||||
// 初始化加密器
|
||||
val cipher = Cipher.getInstance(TRANSFORMATION)
|
||||
val gcmParameterSpec = GCMParameterSpec(
|
||||
GCM_TAG_LENGTH * 8, iv
|
||||
)
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, gcmParameterSpec)
|
||||
|
||||
val encrypted = cipher.doFinal(
|
||||
sSrc.toByteArray(StandardCharsets.UTF_8)
|
||||
)
|
||||
return Base64Utils.encode(
|
||||
"${Base64Utils.encode(iv)}:${Base64Utils.encode(encrypted)}".toByteArray()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* AES解密方法(使用GCM模式)
|
||||
* @param sSrc 待解密的字符串,格式为 IV:EncryptedData+Tag(均为Base64编码)
|
||||
* @param sKey 解密密钥
|
||||
* @return 解密后的原始字符串
|
||||
*/
|
||||
fun decrypt(sSrc: String, sKey: String): String? {
|
||||
try {
|
||||
// 分割IV和加密数据
|
||||
val sSrcs = String(Base64Utils.decode(sSrc))
|
||||
val parts: Array<String?> = sSrcs.split(":".toRegex(), limit = 2).toTypedArray()
|
||||
if (parts.size != 2) {
|
||||
return null
|
||||
}
|
||||
val iv = Base64Utils.decode(parts[0])
|
||||
val encryptedData = Base64Utils.decode(parts[1])
|
||||
if (iv.size != GCM_IV_LENGTH) {
|
||||
return null
|
||||
}
|
||||
val secretKeySpec = createSecretKey(sKey)
|
||||
val cipher = Cipher.getInstance(TRANSFORMATION)
|
||||
val gcmParameterSpec = GCMParameterSpec(
|
||||
GCM_TAG_LENGTH * 8, iv
|
||||
)
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec)
|
||||
val original = cipher.doFinal(encryptedData)
|
||||
return String(original, StandardCharsets.UTF_8)
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建AES密钥,支持任意长度的密钥
|
||||
* @param sKey 字符串密钥
|
||||
* @return SecretKeySpec对象
|
||||
* @throws Exception 可能抛出的异常
|
||||
*/
|
||||
@Throws(GeneralSecurityException::class)
|
||||
private fun createSecretKey(sKey: String): SecretKeySpec {
|
||||
val key = sKey.toByteArray(StandardCharsets.UTF_8)
|
||||
val md = MessageDigest.getInstance("MD5")
|
||||
val digest = md.digest(key)
|
||||
return SecretKeySpec(digest, ALGORITHM)
|
||||
}
|
||||
51
src/main/kotlin/com/mingliqiye/utils/bytes/ByteUtil.kt
Normal file
51
src/main/kotlin/com/mingliqiye/utils/bytes/ByteUtil.kt
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile ByteUtil.kt
|
||||
* LastUpdate 2025-09-14 18:19:29
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
@file:JvmName("ByteUtil")
|
||||
|
||||
package com.mingliqiye.utils.bytes
|
||||
|
||||
import com.mingliqiye.utils.collection.Lists
|
||||
import com.mingliqiye.utils.stream.SuperStream
|
||||
|
||||
const val ESC_ASC: Byte = 0x10
|
||||
const val ESC_DESC: Byte = 0x1B
|
||||
const val ESC_NONE: Byte = 0x00
|
||||
const val ESC_START: Byte = 0x01
|
||||
const val ESC_END: Byte = 0x02
|
||||
const val ESC_ESC: Byte = 0x03
|
||||
const val ESC_CONTROL: Byte = 0x04
|
||||
const val ESC_DATA: Byte = 0x05
|
||||
const val ESC_RESERVED: Byte = 0x06
|
||||
|
||||
|
||||
/**
|
||||
* 将字节数组转换为十六进制字符串列表
|
||||
*
|
||||
* @param bytes 输入的字节数组
|
||||
* @return 包含每个字节对应十六进制字符串的列表
|
||||
*/
|
||||
fun getByteArrayString(bytes: ByteArray): MutableList<String> {
|
||||
return SuperStream.of(Lists.toList(bytes))
|
||||
.map { a -> String.format("%02x", a!!.toInt() and 0xFF) }
|
||||
.collect(SuperStream.Collectors.toList())
|
||||
}
|
||||
|
||||
60
src/main/kotlin/com/mingliqiye/utils/jna/FieldStructure.kt
Normal file
60
src/main/kotlin/com/mingliqiye/utils/jna/FieldStructure.kt
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile FieldStructure.kt
|
||||
* LastUpdate 2025-09-14 18:19:29
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.jna
|
||||
|
||||
import com.sun.jna.Structure
|
||||
import java.lang.reflect.Modifier
|
||||
|
||||
/**
|
||||
* JNA结构体基类,自动处理字段顺序
|
||||
* 该类继承自JNA的Structure类,通过反射自动获取子类的公共非静态字段,
|
||||
* 并按声明顺序返回字段名列表,用于JNA结构体的字段映射。
|
||||
*/
|
||||
class FieldStructure : Structure() {
|
||||
/**
|
||||
* 获取结构体字段顺序列表
|
||||
* 通过反射遍历当前类及其父类的所有声明字段,过滤出公共非静态字段,
|
||||
* 按照字段在类中声明的顺序返回字段名列表。
|
||||
*
|
||||
* @return 包含字段名的列表,按声明顺序排列
|
||||
*/
|
||||
override fun getFieldOrder(): MutableList<String> {
|
||||
val fieldOrderList: MutableList<String> = ArrayList()
|
||||
var cls: Class<*> = javaClass
|
||||
while (cls != FieldStructure::class.java) {
|
||||
val fields = cls.getDeclaredFields()
|
||||
var modifiers: Int
|
||||
for (field in fields) {
|
||||
modifiers = field.modifiers
|
||||
if (Modifier.isStatic(modifiers) ||
|
||||
!Modifier.isPublic(modifiers)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
fieldOrderList.add(field.name)
|
||||
}
|
||||
cls = cls.getSuperclass()
|
||||
}
|
||||
return fieldOrderList
|
||||
}
|
||||
}
|
||||
421
src/main/kotlin/com/mingliqiye/utils/logger/Loggers.kt
Normal file
421
src/main/kotlin/com/mingliqiye/utils/logger/Loggers.kt
Normal file
@ -0,0 +1,421 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile Loggers.kt
|
||||
* LastUpdate 2025-09-14 18:19:29
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
@file:JvmName("Loggers")
|
||||
|
||||
package com.mingliqiye.utils.logger
|
||||
|
||||
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.slf4j.Marker
|
||||
import java.util.*
|
||||
|
||||
enum class MingLiLoggerLevel {
|
||||
TRACE,
|
||||
DEBUG,
|
||||
INFO,
|
||||
WARN,
|
||||
ERROR
|
||||
}
|
||||
|
||||
class MingLiLogger : Logger {
|
||||
override fun getName(): String {
|
||||
return "MingLiLogger"
|
||||
}
|
||||
|
||||
override fun isTraceEnabled(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun trace(msg: String?) {
|
||||
msg?.let { toPrintln(it, MingLiLoggerLevel.TRACE) }
|
||||
}
|
||||
|
||||
override fun trace(format: String?, arg: Any?) {
|
||||
format?.let {
|
||||
val message = format1(it, arg)
|
||||
toPrintln(message, MingLiLoggerLevel.TRACE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun trace(format: String?, arg1: Any?, arg2: Any?) {
|
||||
format?.let {
|
||||
val message = format2(it, arg1, arg2)
|
||||
toPrintln(message, MingLiLoggerLevel.TRACE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun trace(format: String?, vararg arguments: Any?) {
|
||||
format?.let {
|
||||
val message = formatArray(it, arguments)
|
||||
toPrintln(message, MingLiLoggerLevel.TRACE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun trace(msg: String?, t: Throwable?) {
|
||||
msg?.let {
|
||||
val message = if (t != null) "$it: ${t.message}" else it
|
||||
toPrintln(message, MingLiLoggerLevel.TRACE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isTraceEnabled(marker: Marker?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun trace(marker: Marker?, msg: String?) {
|
||||
trace(msg)
|
||||
}
|
||||
|
||||
override fun trace(marker: Marker?, format: String?, arg: Any?) {
|
||||
trace(format, arg)
|
||||
}
|
||||
|
||||
override fun trace(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
|
||||
trace(format, arg1, arg2)
|
||||
}
|
||||
|
||||
override fun trace(marker: Marker?, format: String?, vararg arguments: Any?) {
|
||||
trace(format, *arguments)
|
||||
}
|
||||
|
||||
override fun trace(marker: Marker?, msg: String?, t: Throwable?) {
|
||||
trace(msg, t)
|
||||
}
|
||||
|
||||
override fun isDebugEnabled(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun debug(msg: String?) {
|
||||
msg?.let { toPrintln(it, MingLiLoggerLevel.DEBUG) }
|
||||
}
|
||||
|
||||
override fun debug(format: String?, arg: Any?) {
|
||||
format?.let {
|
||||
val message = format1(it, arg)
|
||||
toPrintln(message, MingLiLoggerLevel.DEBUG)
|
||||
}
|
||||
}
|
||||
|
||||
override fun debug(format: String?, arg1: Any?, arg2: Any?) {
|
||||
format?.let {
|
||||
val message = format2(it, arg1, arg2)
|
||||
toPrintln(message, MingLiLoggerLevel.DEBUG)
|
||||
}
|
||||
}
|
||||
|
||||
override fun debug(format: String?, vararg arguments: Any?) {
|
||||
format?.let {
|
||||
val message = formatArray(it, arguments)
|
||||
toPrintln(message, MingLiLoggerLevel.DEBUG)
|
||||
}
|
||||
}
|
||||
|
||||
override fun debug(msg: String?, t: Throwable?) {
|
||||
msg?.let {
|
||||
val message = if (t != null) "$it: ${t.message}" else it
|
||||
toPrintln(message, MingLiLoggerLevel.DEBUG)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isDebugEnabled(marker: Marker?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun debug(marker: Marker?, msg: String?) {
|
||||
debug(msg)
|
||||
}
|
||||
|
||||
override fun debug(marker: Marker?, format: String?, arg: Any?) {
|
||||
debug(format, arg)
|
||||
}
|
||||
|
||||
override fun debug(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
|
||||
debug(format, arg1, arg2)
|
||||
}
|
||||
|
||||
override fun debug(marker: Marker?, format: String?, vararg arguments: Any?) {
|
||||
debug(format, *arguments)
|
||||
}
|
||||
|
||||
override fun debug(marker: Marker?, msg: String?, t: Throwable?) {
|
||||
debug(msg, t)
|
||||
}
|
||||
|
||||
override fun isInfoEnabled(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun info(msg: String?) {
|
||||
msg?.let { toPrintln(it, MingLiLoggerLevel.INFO) }
|
||||
}
|
||||
|
||||
override fun info(format: String?, arg: Any?) {
|
||||
format?.let {
|
||||
val message = format1(it, arg)
|
||||
toPrintln(message, MingLiLoggerLevel.INFO)
|
||||
}
|
||||
}
|
||||
|
||||
override fun info(format: String?, arg1: Any?, arg2: Any?) {
|
||||
format?.let {
|
||||
val message = format2(it, arg1, arg2)
|
||||
toPrintln(message, MingLiLoggerLevel.INFO)
|
||||
}
|
||||
}
|
||||
|
||||
override fun info(format: String?, vararg arguments: Any?) {
|
||||
format?.let {
|
||||
val message = formatArray(it, arguments)
|
||||
toPrintln(message, MingLiLoggerLevel.INFO)
|
||||
}
|
||||
}
|
||||
|
||||
override fun info(msg: String?, t: Throwable?) {
|
||||
msg?.let {
|
||||
val message = if (t != null) "$it: ${t.message}" else it
|
||||
toPrintln(message, MingLiLoggerLevel.INFO)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isInfoEnabled(marker: Marker?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun info(marker: Marker?, msg: String?) {
|
||||
info(msg)
|
||||
}
|
||||
|
||||
override fun info(marker: Marker?, format: String?, arg: Any?) {
|
||||
info(format, arg)
|
||||
}
|
||||
|
||||
override fun info(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
|
||||
info(format, arg1, arg2)
|
||||
}
|
||||
|
||||
override fun info(marker: Marker?, format: String?, vararg arguments: Any?) {
|
||||
info(format, *arguments)
|
||||
}
|
||||
|
||||
override fun info(marker: Marker?, msg: String?, t: Throwable?) {
|
||||
info(msg, t)
|
||||
}
|
||||
|
||||
override fun isWarnEnabled(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun warn(msg: String?) {
|
||||
msg?.let { toPrintln(it, MingLiLoggerLevel.WARN) }
|
||||
}
|
||||
|
||||
override fun warn(format: String?, arg: Any?) {
|
||||
format?.let {
|
||||
val message = format1(it, arg)
|
||||
toPrintln(message, MingLiLoggerLevel.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
override fun warn(format: String?, vararg arguments: Any?) {
|
||||
format?.let {
|
||||
val message = formatArray(it, arguments)
|
||||
toPrintln(message, MingLiLoggerLevel.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
override fun warn(format: String?, arg1: Any?, arg2: Any?) {
|
||||
format?.let {
|
||||
val message = format2(it, arg1, arg2)
|
||||
toPrintln(message, MingLiLoggerLevel.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
override fun warn(msg: String?, t: Throwable?) {
|
||||
msg?.let {
|
||||
val message = if (t != null) "$it: ${t.message}" else it
|
||||
toPrintln(message, MingLiLoggerLevel.WARN)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isWarnEnabled(marker: Marker?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun warn(marker: Marker?, msg: String?) {
|
||||
warn(msg)
|
||||
}
|
||||
|
||||
override fun warn(marker: Marker?, format: String?, arg: Any?) {
|
||||
warn(format, arg)
|
||||
}
|
||||
|
||||
override fun warn(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
|
||||
warn(format, arg1, arg2)
|
||||
}
|
||||
|
||||
override fun warn(marker: Marker?, format: String?, vararg arguments: Any?) {
|
||||
warn(format, *arguments)
|
||||
}
|
||||
|
||||
override fun warn(marker: Marker?, msg: String?, t: Throwable?) {
|
||||
warn(msg, t)
|
||||
}
|
||||
|
||||
override fun isErrorEnabled(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun error(msg: String?) {
|
||||
msg?.let { toPrintln(it, MingLiLoggerLevel.ERROR) }
|
||||
}
|
||||
|
||||
override fun error(format: String?, arg: Any?) {
|
||||
format?.let {
|
||||
val message = format1(it, arg)
|
||||
toPrintln(message, MingLiLoggerLevel.ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
override fun error(format: String?, arg1: Any?, arg2: Any?) {
|
||||
format?.let {
|
||||
val message = format2(it, arg1, arg2)
|
||||
toPrintln(message, MingLiLoggerLevel.ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
override fun error(format: String?, vararg arguments: Any?) {
|
||||
format?.let {
|
||||
val message = formatArray(it, arguments)
|
||||
toPrintln(message, MingLiLoggerLevel.ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
override fun error(msg: String?, t: Throwable?) {
|
||||
msg?.let {
|
||||
val message = if (t != null) "$it: ${t.message}" else it
|
||||
toPrintln(message, MingLiLoggerLevel.ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isErrorEnabled(marker: Marker?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun error(marker: Marker?, msg: String?) {
|
||||
error(msg)
|
||||
}
|
||||
|
||||
override fun error(marker: Marker?, format: String?, arg: Any?) {
|
||||
error(format, arg)
|
||||
}
|
||||
|
||||
override fun error(marker: Marker?, format: String?, arg1: Any?, arg2: Any?) {
|
||||
error(format, arg1, arg2)
|
||||
}
|
||||
|
||||
override fun error(marker: Marker?, format: String?, vararg arguments: Any?) {
|
||||
error(format, *arguments)
|
||||
}
|
||||
|
||||
override fun error(marker: Marker?, msg: String?, t: Throwable?) {
|
||||
error(msg, t)
|
||||
}
|
||||
|
||||
fun toPrintln(message: String, level: MingLiLoggerLevel) {
|
||||
when (level) {
|
||||
MingLiLoggerLevel.TRACE -> println("[TRACE] $message")
|
||||
MingLiLoggerLevel.DEBUG -> println("[DEBUG] $message")
|
||||
MingLiLoggerLevel.INFO -> println("[INFO] $message")
|
||||
MingLiLoggerLevel.WARN -> println("[WARN] $message")
|
||||
MingLiLoggerLevel.ERROR -> println("[ERROR] $message")
|
||||
}
|
||||
}
|
||||
|
||||
private fun format1(format: String, arg: Any?): String {
|
||||
return if (format.contains("{}")) {
|
||||
format.replaceFirst("{}", arg?.toString() ?: "null")
|
||||
} else {
|
||||
"$format $arg"
|
||||
}
|
||||
}
|
||||
|
||||
private fun format2(format: String, arg1: Any?, arg2: Any?): String {
|
||||
return format.replaceFirst("{}", arg1?.toString() ?: "null")
|
||||
.replaceFirst("{}", arg2?.toString() ?: "null")
|
||||
}
|
||||
|
||||
private fun formatArray(format: String, arguments: Array<out Any?>): String {
|
||||
var result = format
|
||||
for (arg in arguments) {
|
||||
result = result.replaceFirst("{}", arg?.toString() ?: "null")
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class MingLiLoggerFactory {
|
||||
private var hasSLF4JImplementation: Boolean? = null
|
||||
|
||||
// 线程安全的延迟初始化
|
||||
private fun checkSLF4JImplementation(): Boolean {
|
||||
if (hasSLF4JImplementation == null) {
|
||||
synchronized(this) {
|
||||
if (hasSLF4JImplementation == null) {
|
||||
hasSLF4JImplementation = try {
|
||||
// 更可靠的检测方式
|
||||
ServiceLoader.load(
|
||||
Class.forName("org.slf4j.spi.SLF4JServiceProvider")
|
||||
).iterator().hasNext()
|
||||
} catch (e: ClassNotFoundException) {
|
||||
false
|
||||
} catch (e: NoClassDefFoundError) {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return hasSLF4JImplementation ?: false
|
||||
}
|
||||
|
||||
fun getLogger(name: String): Logger {
|
||||
return if (checkSLF4JImplementation()) {
|
||||
LoggerFactory.getLogger(name)
|
||||
} else {
|
||||
MingLiLogger()
|
||||
}
|
||||
}
|
||||
|
||||
fun getLogger(clazz: Class<*>): Logger {
|
||||
return if (checkSLF4JImplementation()) {
|
||||
LoggerFactory.getLogger(clazz)
|
||||
} else {
|
||||
MingLiLogger()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val mingLiLoggerFactory = MingLiLoggerFactory()
|
||||
|
||||
|
||||
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile DateTimeTypeHandler.kt
|
||||
* LastUpdate 2025-09-14 18:19:29
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
@file:JvmName("DateTimeConvertor")
|
||||
|
||||
package com.mingliqiye.utils.mybatis.typehandler.datetime
|
||||
|
||||
import com.mingliqiye.utils.time.DateTime
|
||||
import org.apache.ibatis.type.BaseTypeHandler
|
||||
import org.apache.ibatis.type.JdbcType
|
||||
import org.apache.ibatis.type.MappedTypes
|
||||
import java.sql.CallableStatement
|
||||
import java.sql.PreparedStatement
|
||||
import java.sql.ResultSet
|
||||
import java.sql.SQLException
|
||||
import java.time.LocalDateTime
|
||||
|
||||
/**
|
||||
* 将LocalDateTime对象转换为DateTime对象
|
||||
*
|
||||
* @param localDateTime LocalDateTime对象
|
||||
* @return DateTime对象,如果localDateTime为null则返回null
|
||||
*/
|
||||
fun toDateTime(localDateTime: LocalDateTime?): DateTime? {
|
||||
return localDateTime?.let { DateTime.of(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 将DateTime对象转换为LocalDateTime对象
|
||||
*
|
||||
* @param dateTime DateTime对象
|
||||
* @return LocalDateTime对象,如果dateTime为null则返回null
|
||||
*/
|
||||
fun toLocalDateTime(dateTime: DateTime?): LocalDateTime? {
|
||||
return dateTime?.toLocalDateTime()
|
||||
}
|
||||
|
||||
/**
|
||||
* DateTime类型处理器,用于在数据库和Java对象之间转换DateTime类型
|
||||
* @author MingLiQiye
|
||||
* @date 2025/9/12
|
||||
*/
|
||||
@MappedTypes(DateTime::class)
|
||||
class DateTimeTypeHandler : BaseTypeHandler<DateTime>() {
|
||||
|
||||
@Throws(SQLException::class)
|
||||
override fun setNonNullParameter(
|
||||
ps: PreparedStatement,
|
||||
i: Int,
|
||||
parameter: DateTime, // 移除了 ?,因为这是 non-null 方法
|
||||
jdbcType: JdbcType
|
||||
) {
|
||||
// 使用 setObject 允许传入 null,由数据库处理
|
||||
ps.setObject(i, toLocalDateTime(parameter))
|
||||
}
|
||||
|
||||
@Throws(SQLException::class)
|
||||
override fun getNullableResult(rs: ResultSet, columnName: String): DateTime? {
|
||||
// 安全类型转换和空检查
|
||||
return when (val value = rs.getObject(columnName)) {
|
||||
is LocalDateTime -> toDateTime(value)
|
||||
null -> null
|
||||
else -> throw SQLException("Expected LocalDateTime for column '$columnName', but got ${value.javaClass.name}")
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(SQLException::class)
|
||||
override fun getNullableResult(rs: ResultSet, columnIndex: Int): DateTime? {
|
||||
return when (val value = rs.getObject(columnIndex)) {
|
||||
is LocalDateTime -> toDateTime(value)
|
||||
null -> null
|
||||
else -> throw SQLException("Expected LocalDateTime at column index $columnIndex, but got ${value.javaClass.name}")
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(SQLException::class)
|
||||
override fun getNullableResult(cs: CallableStatement, columnIndex: Int): DateTime? {
|
||||
return when (val value = cs.getObject(columnIndex)) {
|
||||
is LocalDateTime -> toDateTime(value)
|
||||
null -> null
|
||||
else -> throw SQLException("Expected LocalDateTime at column index $columnIndex, but got ${value.javaClass.name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile UUIDTypeHandler.kt
|
||||
* LastUpdate 2025-09-14 18:19:29
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
@file:JvmName("UUIDConvertor")
|
||||
|
||||
package com.mingliqiye.utils.mybatis.typehandler.uuid
|
||||
|
||||
import com.mingliqiye.utils.uuid.UUID
|
||||
import org.apache.ibatis.type.BaseTypeHandler
|
||||
import org.apache.ibatis.type.JdbcType
|
||||
import org.apache.ibatis.type.MappedJdbcTypes
|
||||
import org.apache.ibatis.type.MappedTypes
|
||||
import java.sql.CallableStatement
|
||||
import java.sql.PreparedStatement
|
||||
import java.sql.ResultSet
|
||||
import java.util.UUID as JUUID
|
||||
|
||||
|
||||
/**
|
||||
* 将字节数组转换为UUID对象
|
||||
*
|
||||
* @param byteArray 字节数组
|
||||
* @return UUID对象,如果字节数组为null则返回null
|
||||
*/
|
||||
fun byteArraytoUUID(byteArray: ByteArray?): UUID? {
|
||||
return byteArray?.let { UUID.of(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 将UUID对象转换为字节数组
|
||||
*
|
||||
* @param uuid UUID对象
|
||||
* @return 字节数组,如果UUID为null则返回null
|
||||
*/
|
||||
fun uuidToByteArray(uuid: UUID?): ByteArray? {
|
||||
return uuid?.toBytes()
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串转换为UUID对象
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return UUID对象,如果字符串为null则返回null
|
||||
*/
|
||||
fun stringToUUID(str: String?): UUID? {
|
||||
return str?.let { UUID.of(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 将UUID对象转换为字符串
|
||||
*
|
||||
* @param uuid UUID对象
|
||||
* @return 字符串,如果UUID为null则返回null
|
||||
*/
|
||||
fun uuidToString(uuid: UUID?): String? {
|
||||
return uuid?.getString()
|
||||
}
|
||||
|
||||
/**
|
||||
* 将java UUID转换为UUID对象
|
||||
*
|
||||
* @param uuid JUUID java UUID
|
||||
* @return UUID对象,如果字符串为null则返回null
|
||||
*/
|
||||
fun juuidToUUID(uuid: JUUID?): UUID? {
|
||||
return uuid?.let { UUID(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 将UUID对象转换为java UUID
|
||||
*
|
||||
* @param uuid UUID对象
|
||||
* @return java UUID,如果UUID为null则返回null
|
||||
*/
|
||||
fun uuidToJuuid(uuid: UUID?): JUUID? {
|
||||
return uuid?.getUuid()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* JDBC类型转换 UUID BINARY
|
||||
* @author MingLiQiye
|
||||
* @date 2025/9/12
|
||||
*/
|
||||
@MappedTypes(UUID::class)
|
||||
@MappedJdbcTypes(JdbcType.BINARY)
|
||||
class UUIDBinaryTypeHandler : BaseTypeHandler<UUID>() {
|
||||
/**
|
||||
* 设置非空参数到PreparedStatement中
|
||||
*
|
||||
* @param ps PreparedStatement对象
|
||||
* @param i 参数索引
|
||||
* @param parameter UUID参数值
|
||||
* @param jdbcType JDBC类型
|
||||
*/
|
||||
override fun setNonNullParameter(
|
||||
ps: PreparedStatement, i: Int, parameter: UUID, jdbcType: JdbcType
|
||||
) {
|
||||
ps.setBytes(i, uuidToByteArray(parameter))
|
||||
}
|
||||
|
||||
/**
|
||||
* 从ResultSet中根据列名获取可空的UUID结果
|
||||
*
|
||||
* @param rs ResultSet对象
|
||||
* @param columnName 列名
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(
|
||||
rs: ResultSet, columnName: String
|
||||
): UUID? {
|
||||
return byteArraytoUUID(rs.getBytes(columnName))
|
||||
}
|
||||
|
||||
/**
|
||||
* 从ResultSet中根据列索引获取可空的UUID结果
|
||||
*
|
||||
* @param rs ResultSet对象
|
||||
* @param columnIndex 列索引
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(rs: ResultSet, columnIndex: Int): UUID? {
|
||||
return byteArraytoUUID(rs.getBytes(columnIndex))
|
||||
}
|
||||
|
||||
/**
|
||||
* 从CallableStatement中根据列索引获取可空的UUID结果
|
||||
*
|
||||
* @param cs CallableStatement对象
|
||||
* @param columnIndex 列索引
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(
|
||||
cs: CallableStatement, columnIndex: Int
|
||||
): UUID? {
|
||||
return byteArraytoUUID(cs.getBytes(columnIndex))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* JDBC类型转换 UUID String
|
||||
* @author MingLiQiye
|
||||
* @date 2025/9/12
|
||||
*/
|
||||
@MappedTypes(UUID::class)
|
||||
@MappedJdbcTypes(JdbcType.VARCHAR)
|
||||
class UUIDStringTypeHandler : BaseTypeHandler<UUID>() {
|
||||
/**
|
||||
* 设置非空参数到PreparedStatement中
|
||||
*
|
||||
* @param ps PreparedStatement对象
|
||||
* @param i 参数索引
|
||||
* @param parameter UUID参数值
|
||||
* @param jdbcType JDBC类型
|
||||
*/
|
||||
override fun setNonNullParameter(
|
||||
ps: PreparedStatement, i: Int, parameter: UUID, jdbcType: JdbcType
|
||||
) {
|
||||
ps.setString(i, uuidToString(parameter))
|
||||
}
|
||||
|
||||
/**
|
||||
* 从ResultSet中根据列名获取可空的UUID结果
|
||||
*
|
||||
* @param rs ResultSet对象
|
||||
* @param columnName 列名
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(
|
||||
rs: ResultSet, columnName: String
|
||||
): UUID? {
|
||||
return stringToUUID(rs.getString(columnName))
|
||||
}
|
||||
|
||||
/**
|
||||
* 从ResultSet中根据列索引获取可空的UUID结果
|
||||
*
|
||||
* @param rs ResultSet对象
|
||||
* @param columnIndex 列索引
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(rs: ResultSet, columnIndex: Int): UUID? {
|
||||
return stringToUUID(rs.getString(columnIndex))
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 从CallableStatement中根据列索引获取可空的UUID结果
|
||||
*
|
||||
* @param cs CallableStatement对象
|
||||
* @param columnIndex 列索引
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(
|
||||
cs: CallableStatement, columnIndex: Int
|
||||
): UUID? {
|
||||
return stringToUUID(cs.getString(columnIndex))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* JDBC类型转换 UUID java UUID
|
||||
* @author MingLiQiye
|
||||
* @date 2025/9/12
|
||||
*/
|
||||
@MappedTypes(UUID::class)
|
||||
@MappedJdbcTypes(JdbcType.OTHER)
|
||||
class UUIDTypeHandler : BaseTypeHandler<UUID>() {
|
||||
/**
|
||||
* 设置非空参数到PreparedStatement中
|
||||
*
|
||||
* @param ps PreparedStatement对象
|
||||
* @param i 参数索引
|
||||
* @param parameter UUID参数值
|
||||
* @param jdbcType JDBC类型
|
||||
*/
|
||||
override fun setNonNullParameter(
|
||||
ps: PreparedStatement, i: Int, parameter: UUID, jdbcType: JdbcType
|
||||
) {
|
||||
ps.setObject(i, parameter.getUuid())
|
||||
}
|
||||
|
||||
/**
|
||||
* 从ResultSet中根据列名获取可空的UUID结果
|
||||
*
|
||||
* @param rs ResultSet对象
|
||||
* @param columnName 列名
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(
|
||||
rs: ResultSet,
|
||||
columnName: String
|
||||
): UUID? {
|
||||
return juuidToUUID(rs.getObject(columnName, JUUID::class.java) as JUUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* 从ResultSet中根据列索引获取可空的UUID结果
|
||||
*
|
||||
* @param rs ResultSet对象
|
||||
* @param columnIndex 列索引
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(rs: ResultSet, columnIndex: Int): UUID? {
|
||||
return juuidToUUID(rs.getObject(columnIndex, JUUID::class.java) as JUUID)
|
||||
}
|
||||
|
||||
/**
|
||||
* 从CallableStatement中根据列索引获取可空的UUID结果
|
||||
*
|
||||
* @param cs CallableStatement对象
|
||||
* @param columnIndex 列索引
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(
|
||||
cs: CallableStatement, columnIndex: Int
|
||||
): UUID? {
|
||||
return juuidToUUID(cs.getObject(columnIndex, JUUID::class.java) as JUUID)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile MysqlUUIDBinaryTypeHandler.kt
|
||||
* LastUpdate 2025-09-14 18:19:29
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
|
||||
package com.mingliqiye.utils.mybatis.typehandler.uuid.mysql
|
||||
|
||||
import com.mingliqiye.utils.uuid.UUID
|
||||
import com.mingliqiye.utils.uuid.mysqlToUuid
|
||||
import com.mingliqiye.utils.uuid.uuidToMysql
|
||||
import org.apache.ibatis.type.BaseTypeHandler
|
||||
import org.apache.ibatis.type.JdbcType
|
||||
import org.apache.ibatis.type.MappedTypes
|
||||
import java.sql.CallableStatement
|
||||
import java.sql.PreparedStatement
|
||||
import java.sql.ResultSet
|
||||
|
||||
/**
|
||||
* JDBC类型转换 UUID
|
||||
* @author MingLiQiye
|
||||
* @date 2025/9/12
|
||||
*/
|
||||
@MappedTypes(UUID::class)
|
||||
class MysqlUUIDBinaryTypeHandler : BaseTypeHandler<UUID>() {
|
||||
|
||||
/**
|
||||
* 将字节数组转换为UUID对象
|
||||
*
|
||||
* @param byteArray 字节数组
|
||||
* @return UUID对象,如果字节数组为null则返回null
|
||||
*/
|
||||
private fun toUUID(byteArray: ByteArray?): UUID? {
|
||||
return byteArray?.let { UUID.of(mysqlToUuid(it)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 将UUID对象转换为字节数组
|
||||
*
|
||||
* @param uuid UUID对象
|
||||
* @return 字节数组,如果UUID为null则返回null
|
||||
*/
|
||||
fun toByteArray(uuid: UUID?): ByteArray? {
|
||||
return uuid?.let { uuidToMysql(it.toBytes()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置非空参数到PreparedStatement中
|
||||
*
|
||||
* @param ps PreparedStatement对象
|
||||
* @param i 参数索引
|
||||
* @param parameter UUID参数值
|
||||
* @param jdbcType JDBC类型
|
||||
*/
|
||||
override fun setNonNullParameter(
|
||||
ps: PreparedStatement,
|
||||
i: Int,
|
||||
parameter: UUID,
|
||||
jdbcType: JdbcType
|
||||
) {
|
||||
ps.setBytes(i, toByteArray(parameter))
|
||||
}
|
||||
|
||||
/**
|
||||
* 从ResultSet中根据列名获取可空的UUID结果
|
||||
*
|
||||
* @param rs ResultSet对象
|
||||
* @param columnName 列名
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(
|
||||
rs: ResultSet,
|
||||
columnName: String
|
||||
): UUID? {
|
||||
return toUUID(rs.getBytes(columnName))
|
||||
}
|
||||
|
||||
/**
|
||||
* 从ResultSet中根据列索引获取可空的UUID结果
|
||||
*
|
||||
* @param rs ResultSet对象
|
||||
* @param columnIndex 列索引
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(rs: ResultSet, columnIndex: Int): UUID? {
|
||||
return toUUID(rs.getBytes(columnIndex))
|
||||
}
|
||||
|
||||
/**
|
||||
* 从CallableStatement中根据列索引获取可空的UUID结果
|
||||
*
|
||||
* @param cs CallableStatement对象
|
||||
* @param columnIndex 列索引
|
||||
* @return UUID对象或null
|
||||
*/
|
||||
override fun getNullableResult(
|
||||
cs: CallableStatement,
|
||||
columnIndex: Int
|
||||
): UUID? {
|
||||
return toUUID(cs.getBytes(columnIndex))
|
||||
}
|
||||
|
||||
}
|
||||
53
src/main/kotlin/com/mingliqiye/utils/uuid/MysqlUUIDv1.kt
Normal file
53
src/main/kotlin/com/mingliqiye/utils/uuid/MysqlUUIDv1.kt
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2025 mingliqiye
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* ProjectName mingli-utils
|
||||
* ModuleName mingli-utils.main
|
||||
* CurrentFile MysqlUUIDv1.kt
|
||||
* LastUpdate 2025-09-14 18:19:29
|
||||
* UpdateUser MingLiPro
|
||||
*/
|
||||
@file:JvmName("MysqlUUIDv1")
|
||||
|
||||
package com.mingliqiye.utils.uuid
|
||||
|
||||
|
||||
fun uuidToMysql(uuid: ByteArray): ByteArray {
|
||||
val reuuid = ByteArray(16)
|
||||
reuuid[4] = uuid[0]
|
||||
reuuid[5] = uuid[1]
|
||||
reuuid[6] = uuid[2]
|
||||
reuuid[7] = uuid[3]
|
||||
reuuid[2] = uuid[4]
|
||||
reuuid[3] = uuid[5]
|
||||
reuuid[0] = uuid[6]
|
||||
reuuid[1] = uuid[7]
|
||||
System.arraycopy(uuid, 8, reuuid, 8, 8)
|
||||
return reuuid
|
||||
}
|
||||
|
||||
fun mysqlToUuid(uuid: ByteArray): ByteArray {
|
||||
val reuuid = ByteArray(16)
|
||||
reuuid[6] = uuid[0]
|
||||
reuuid[7] = uuid[1]
|
||||
reuuid[4] = uuid[2]
|
||||
reuuid[5] = uuid[3]
|
||||
reuuid[0] = uuid[4]
|
||||
reuuid[1] = uuid[5]
|
||||
reuuid[2] = uuid[6]
|
||||
reuuid[3] = uuid[7]
|
||||
System.arraycopy(uuid, 8, reuuid, 8, 8)
|
||||
return reuuid
|
||||
}
|
||||
@ -4,4 +4,4 @@ artifactId=$ARTIFACTID
|
||||
version=$VERSIONS
|
||||
buildJdkVersion=$JDKVERSIONS
|
||||
author=MingLiPro
|
||||
website=mingliqiye.com
|
||||
website=https://mingli-utils.mingliqiye.com
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user