generated from mingliqiye/lib-tem
feat(utils): 添加 AES 加密解密工具类
All checks were successful
Gitea Actions Build / Build (push) Successful in 51s
All checks were successful
Gitea Actions Build / Build (push) Successful in 51s
- 新增 AesUtils 类,提供 AES/GCM 模式的加密解密方法- 更新 .prettierrc配置,将 useTabs 设置为 true - 重构 Base64Utils 和 Collection 类的代码结构- 简化 ComponentBean 注解定义
This commit is contained in:
parent
ceef51506d
commit
34dccd1895
@ -4,5 +4,5 @@
|
|||||||
"prettier-plugin-java"
|
"prettier-plugin-java"
|
||||||
],
|
],
|
||||||
"tabWidth": 4,
|
"tabWidth": 4,
|
||||||
"useTabs": false
|
"useTabs": true
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
JDKVERSIONS=1.8
|
JDKVERSIONS=1.8
|
||||||
GROUPSID=com.mingliqiye.utils
|
GROUPSID=com.mingliqiye.utils
|
||||||
ARTIFACTID=mingli-utils
|
ARTIFACTID=mingli-utils
|
||||||
VERSIONS=1.0.5
|
VERSIONS=1.0.7
|
||||||
|
@ -4,7 +4,6 @@ import com.mingliqiye.utils.collection.Lists;
|
|||||||
import com.mingliqiye.utils.string.StringUtil;
|
import com.mingliqiye.utils.string.StringUtil;
|
||||||
import com.mingliqiye.utils.time.DateTime;
|
import com.mingliqiye.utils.time.DateTime;
|
||||||
import com.mingliqiye.utils.time.Formatter;
|
import com.mingliqiye.utils.time.Formatter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
@ -12,7 +11,13 @@ public class Main {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// 字符串工具使用示例
|
// 字符串工具使用示例
|
||||||
System.out.println("=== 字符串工具使用示例 ===");
|
System.out.println("=== 字符串工具使用示例 ===");
|
||||||
String formatted = StringUtil.format("你好 {},今天是{}年{}月{}日", "张三", 2025, 7, 25);
|
String formatted = StringUtil.format(
|
||||||
|
"你好 {},今天是{}年{}月{}日",
|
||||||
|
"张三",
|
||||||
|
2025,
|
||||||
|
7,
|
||||||
|
25
|
||||||
|
);
|
||||||
System.out.println(formatted);
|
System.out.println(formatted);
|
||||||
|
|
||||||
List<String> fruits = Lists.newArrayList("苹果", "香蕉", "橙子");
|
List<String> fruits = Lists.newArrayList("苹果", "香蕉", "橙子");
|
||||||
@ -23,17 +28,25 @@ public class Main {
|
|||||||
System.out.println("\n=== 时间工具使用示例 ===");
|
System.out.println("\n=== 时间工具使用示例 ===");
|
||||||
DateTime now = DateTime.now();
|
DateTime now = DateTime.now();
|
||||||
System.out.println("当前时间: " + now);
|
System.out.println("当前时间: " + now);
|
||||||
System.out.println("标准格式: " + now.format(Formatter.STANDARD_DATETIME));
|
System.out.println(
|
||||||
|
"标准格式: " + now.format(Formatter.STANDARD_DATETIME)
|
||||||
|
);
|
||||||
|
|
||||||
DateTime specificDate = DateTime.of(2025, 1, 1, 12, 0, 0);
|
DateTime specificDate = DateTime.of(2025, 1, 1, 12, 0, 0);
|
||||||
System.out.println("指定时间: " + specificDate.format(Formatter.STANDARD_DATETIME));
|
System.out.println(
|
||||||
|
"指定时间: " + specificDate.format(Formatter.STANDARD_DATETIME)
|
||||||
|
);
|
||||||
|
|
||||||
// 集合工具使用示例
|
// 集合工具使用示例
|
||||||
System.out.println("\n=== 集合工具使用示例 ===");
|
System.out.println("\n=== 集合工具使用示例 ===");
|
||||||
List<Integer> numbers = Lists.newArrayList(10, 20, 30);
|
List<Integer> numbers = Lists.newArrayList(10, 20, 30);
|
||||||
System.out.println("数字列表: " + numbers);
|
System.out.println("数字列表: " + numbers);
|
||||||
|
|
||||||
List<String> linkedList = Lists.newLinkedList("第一个", "第二个", "第三个");
|
List<String> linkedList = Lists.newLinkedList(
|
||||||
|
"第一个",
|
||||||
|
"第二个",
|
||||||
|
"第三个"
|
||||||
|
);
|
||||||
System.out.println("链表内容: " + linkedList);
|
System.out.println("链表内容: " + linkedList);
|
||||||
}
|
}
|
||||||
}
|
}
|
112
src/com/mingliqiye/utils/aes/AesUtils.java
Normal file
112
src/com/mingliqiye/utils/aes/AesUtils.java
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package com.mingliqiye.utils.aes;
|
||||||
|
|
||||||
|
import com.mingliqiye.utils.base64.Base64Utils;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.spec.GCMParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,6 @@ package com.mingliqiye.utils.bean;
|
|||||||
|
|
||||||
import com.mingliqiye.utils.bean.annotation.ComponentBean;
|
import com.mingliqiye.utils.bean.annotation.ComponentBean;
|
||||||
import com.mingliqiye.utils.bean.annotation.InjectBean;
|
import com.mingliqiye.utils.bean.annotation.InjectBean;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -70,9 +70,6 @@ public class SpringBeanUtil implements ApplicationContextAware {
|
|||||||
public void setApplicationContext(
|
public void setApplicationContext(
|
||||||
@NotNull ApplicationContext applicationContext
|
@NotNull ApplicationContext applicationContext
|
||||||
) throws BeansException {
|
) throws BeansException {
|
||||||
// 避免重复赋值,确保只设置一次ApplicationContext
|
|
||||||
if (SpringBeanUtil.applicationContext == null) {
|
|
||||||
SpringBeanUtil.applicationContext = applicationContext;
|
SpringBeanUtil.applicationContext = applicationContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package com.mingliqiye.utils.collection;
|
package com.mingliqiye.utils.collection;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 集合工具类,提供对列表和数组的常用操作方法。
|
* 集合工具类,提供对列表和数组的常用操作方法。
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
package com.mingliqiye.utils.collection;
|
package com.mingliqiye.utils.collection;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists工具类提供了一系列创建List实现的便捷方法。
|
* Lists工具类提供了一系列创建List实现的便捷方法。
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package com.mingliqiye.utils.file;
|
package com.mingliqiye.utils.file;
|
||||||
|
|
||||||
import com.mingliqiye.utils.string.StringUtil;
|
import com.mingliqiye.utils.string.StringUtil;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
@ -15,6 +12,8 @@ import java.nio.file.Paths;
|
|||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件工具类,提供常用的文件操作方法
|
* 文件工具类,提供常用的文件操作方法
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
package com.mingliqiye.utils.hash;
|
package com.mingliqiye.utils.hash;
|
||||||
|
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
||||||
import org.mindrot.jbcrypt.BCrypt;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.mindrot.jbcrypt.BCrypt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提供常用的哈希计算工具方法,包括文件哈希值计算、BCrypt 加密等。
|
* 提供常用的哈希计算工具方法,包括文件哈希值计算、BCrypt 加密等。
|
||||||
|
@ -2,7 +2,6 @@ package com.mingliqiye.utils.minecraft.slp;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.mingliqiye.utils.network.NetworkEndpoint;
|
import com.mingliqiye.utils.network.NetworkEndpoint;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
package com.mingliqiye.utils.network;
|
package com.mingliqiye.utils.network;
|
||||||
|
|
||||||
import com.mingliqiye.utils.string.StringUtil;
|
import com.mingliqiye.utils.string.StringUtil;
|
||||||
import lombok.Getter;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网络地址类,用于表示一个网络地址(IP或域名),并提供相关操作。
|
* 网络地址类,用于表示一个网络地址(IP或域名),并提供相关操作。
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package com.mingliqiye.utils.network;
|
package com.mingliqiye.utils.network;
|
||||||
|
|
||||||
import com.mingliqiye.utils.string.StringUtil;
|
import com.mingliqiye.utils.string.StringUtil;
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IP和端口聚集类,用于封装网络地址与端口信息。
|
* IP和端口聚集类,用于封装网络地址与端口信息。
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
package com.mingliqiye.utils.network;
|
package com.mingliqiye.utils.network;
|
||||||
|
|
||||||
import com.mingliqiye.utils.string.StringUtil;
|
import com.mingliqiye.utils.string.StringUtil;
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网络端口类
|
* 网络端口类
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.mingliqiye.utils.string;
|
package com.mingliqiye.utils.string;
|
||||||
|
|
||||||
import com.mingliqiye.utils.collection.Lists;
|
import com.mingliqiye.utils.collection.Lists;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.mingliqiye.utils.system;
|
package com.mingliqiye.utils.system;
|
||||||
|
|
||||||
import com.mingliqiye.utils.collection.Lists;
|
import com.mingliqiye.utils.collection.Lists;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
package com.mingliqiye.utils.time;
|
package com.mingliqiye.utils.time;
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.var;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.var;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 时间工具类,用于处理日期时间的转换、格式化等操作。
|
* 时间工具类,用于处理日期时间的转换、格式化等操作。
|
||||||
|
@ -11,7 +11,6 @@ import com.fasterxml.jackson.databind.SerializerProvider;
|
|||||||
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
||||||
import com.mingliqiye.utils.time.DateTime;
|
import com.mingliqiye.utils.time.DateTime;
|
||||||
import com.mingliqiye.utils.time.Formatter;
|
import com.mingliqiye.utils.time.Formatter;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,13 +2,12 @@ package com.mingliqiye.utils.time.typehandlers;
|
|||||||
|
|
||||||
import com.mingliqiye.utils.time.DateTime;
|
import com.mingliqiye.utils.time.DateTime;
|
||||||
import com.mingliqiye.utils.time.Formatter;
|
import com.mingliqiye.utils.time.Formatter;
|
||||||
|
import java.sql.*;
|
||||||
import org.apache.ibatis.type.BaseTypeHandler;
|
import org.apache.ibatis.type.BaseTypeHandler;
|
||||||
import org.apache.ibatis.type.JdbcType;
|
import org.apache.ibatis.type.JdbcType;
|
||||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||||
import org.apache.ibatis.type.MappedTypes;
|
import org.apache.ibatis.type.MappedTypes;
|
||||||
|
|
||||||
import java.sql.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DateTime类型处理器类
|
* DateTime类型处理器类
|
||||||
* 用于在MyBatis中处理DateTime类型与数据库VARCHAR类型之间的转换
|
* 用于在MyBatis中处理DateTime类型与数据库VARCHAR类型之间的转换
|
||||||
|
66
src/com/mingliqiye/utils/uuid/MysqlUUIDv1.java
Normal file
66
src/com/mingliqiye/utils/uuid/MysqlUUIDv1.java
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package com.mingliqiye.utils.uuid;
|
||||||
|
|
||||||
|
import lombok.var;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MySQL UUID格式与标准UUID格式相互转换工具类
|
||||||
|
* <p>
|
||||||
|
* MySQL使用不同的字节顺序存储UUID,此类提供了在MySQL格式和标准UUID格式之间转换的方法
|
||||||
|
* @author MingLiPro
|
||||||
|
*/
|
||||||
|
public class MysqlUUIDv1 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将MySQL格式的UUID转换为标准UUID格式
|
||||||
|
*
|
||||||
|
* @param uuid MySQL格式的UUID字节数组,长度必须为16字节
|
||||||
|
* @return 标准UUID格式的字节数组,长度为16字节
|
||||||
|
*/
|
||||||
|
public static byte[] mysqlToUuid(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将标准UUID格式转换为MySQL格式的UUID
|
||||||
|
*
|
||||||
|
* @param uuid 标准UUID格式的字节数组,长度必须为16字节
|
||||||
|
* @return MySQL格式的UUID字节数组,长度为16字节
|
||||||
|
*/
|
||||||
|
public static byte[] uuidToMysql(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;
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,7 @@ import com.github.f4b6a3.uuid.UuidCreator;
|
|||||||
import com.mingliqiye.utils.string.StringUtil;
|
import com.mingliqiye.utils.string.StringUtil;
|
||||||
import com.mingliqiye.utils.time.DateTime;
|
import com.mingliqiye.utils.time.DateTime;
|
||||||
import com.mingliqiye.utils.time.DateTimeOffset;
|
import com.mingliqiye.utils.time.DateTimeOffset;
|
||||||
import com.mingliqiye.utils.time.Formatter;
|
import lombok.Data;
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -19,7 +18,7 @@ import java.util.Objects;
|
|||||||
*
|
*
|
||||||
* @author MingLiPro
|
* @author MingLiPro
|
||||||
*/
|
*/
|
||||||
@Setter
|
@Data
|
||||||
public class UUID implements Serializable {
|
public class UUID implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,6 +68,9 @@ public class UUID implements Serializable {
|
|||||||
* @return 新建的 UUID 实例
|
* @return 新建的 UUID 实例
|
||||||
*/
|
*/
|
||||||
public static UUID of(byte[] bytes) {
|
public static UUID of(byte[] bytes) {
|
||||||
|
if (bytes == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
ByteBuffer bb = ByteBuffer.wrap(bytes);
|
ByteBuffer bb = ByteBuffer.wrap(bytes);
|
||||||
long msb = bb.getLong();
|
long msb = bb.getLong();
|
||||||
long lsb = bb.getLong();
|
long lsb = bb.getLong();
|
||||||
@ -82,7 +84,10 @@ public class UUID implements Serializable {
|
|||||||
* @return 解析后的 UUID 实例
|
* @return 解析后的 UUID 实例
|
||||||
* @throws UUIDException 如果解析失败
|
* @throws UUIDException 如果解析失败
|
||||||
*/
|
*/
|
||||||
public static UUID ofString(String data) {
|
public static UUID of(String data) {
|
||||||
|
if (data == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
java.util.UUID uuid1 = java.util.UUID.fromString(data);
|
java.util.UUID uuid1 = java.util.UUID.fromString(data);
|
||||||
UUID uuid = new UUID();
|
UUID uuid = new UUID();
|
||||||
@ -99,6 +104,9 @@ public class UUID implements Serializable {
|
|||||||
* @return 表示该 UUID 的字节数组
|
* @return 表示该 UUID 的字节数组
|
||||||
*/
|
*/
|
||||||
public byte[] toBytes() {
|
public byte[] toBytes() {
|
||||||
|
if (this.uuid == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
|
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
|
||||||
bb.putLong(uuid.getMostSignificantBits());
|
bb.putLong(uuid.getMostSignificantBits());
|
||||||
bb.putLong(uuid.getLeastSignificantBits());
|
bb.putLong(uuid.getLeastSignificantBits());
|
||||||
@ -178,15 +186,6 @@ public class UUID implements Serializable {
|
|||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
return "UUID(null)";
|
return "UUID(null)";
|
||||||
}
|
}
|
||||||
if (uuid.version() == 1) {
|
|
||||||
return StringUtil.format(
|
|
||||||
"UUID(uuid={},time={},mac={},version={})",
|
|
||||||
toUUIDString(true),
|
|
||||||
getDateTime().format(Formatter.STANDARD_DATETIME),
|
|
||||||
extractMACFromUUID(),
|
|
||||||
uuid.version()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return StringUtil.format(
|
return StringUtil.format(
|
||||||
"UUID(uuid={},version={})",
|
"UUID(uuid={},version={})",
|
||||||
toUUIDString(true),
|
toUUIDString(true),
|
||||||
@ -203,6 +202,9 @@ public class UUID implements Serializable {
|
|||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (uuid.version() != 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return DateTime.of(uuid.timestamp() / 10_000).add(
|
return DateTime.of(uuid.timestamp() / 10_000).add(
|
||||||
DateTimeOffset.of(-141427L, ChronoUnit.DAYS)
|
DateTimeOffset.of(-141427L, ChronoUnit.DAYS)
|
||||||
);
|
);
|
||||||
|
@ -11,7 +11,6 @@ import com.fasterxml.jackson.databind.SerializerProvider;
|
|||||||
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
|
||||||
import com.mingliqiye.utils.uuid.UUID;
|
import com.mingliqiye.utils.uuid.UUID;
|
||||||
import com.mingliqiye.utils.uuid.UUIDException;
|
import com.mingliqiye.utils.uuid.UUIDException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,7 +6,6 @@ import org.apache.ibatis.type.JdbcType;
|
|||||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||||
import org.apache.ibatis.type.MappedTypes;
|
import org.apache.ibatis.type.MappedTypes;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.sql.CallableStatement;
|
import java.sql.CallableStatement;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@ -22,32 +21,6 @@ import java.sql.SQLException;
|
|||||||
@MappedJdbcTypes(JdbcType.BINARY)
|
@MappedJdbcTypes(JdbcType.BINARY)
|
||||||
public class UUIDBinaryTypeHandler extends BaseTypeHandler<UUID> {
|
public class UUIDBinaryTypeHandler extends BaseTypeHandler<UUID> {
|
||||||
|
|
||||||
/**
|
|
||||||
* 将 UUID 对象转换为二进制字节数组
|
|
||||||
*
|
|
||||||
* @param uuid 要转换的 UUID 对象
|
|
||||||
* @return 包含 UUID 数据的 16 字节二进制数组
|
|
||||||
*/
|
|
||||||
public static byte[] UUID_TO_BIN(UUID uuid) {
|
|
||||||
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
|
|
||||||
bb.putLong(uuid.GetUUID().getMostSignificantBits());
|
|
||||||
bb.putLong(uuid.GetUUID().getLeastSignificantBits());
|
|
||||||
return bb.array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将二进制字节数组转换为 UUID 对象
|
|
||||||
*
|
|
||||||
* @param bytes 包含 UUID 数据的二进制字节数组
|
|
||||||
* @return 转换后的 UUID 对象,如果输入为 null 则返回 null
|
|
||||||
*/
|
|
||||||
public static UUID BIN_TO_UUID(byte[] bytes) {
|
|
||||||
if (bytes == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return UUID.of(bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置非空参数到 PreparedStatement 中
|
* 设置非空参数到 PreparedStatement 中
|
||||||
*
|
*
|
||||||
@ -64,7 +37,7 @@ public class UUIDBinaryTypeHandler extends BaseTypeHandler<UUID> {
|
|||||||
UUID parameter,
|
UUID parameter,
|
||||||
JdbcType jdbcType
|
JdbcType jdbcType
|
||||||
) throws SQLException {
|
) throws SQLException {
|
||||||
ps.setBytes(i, UUID_TO_BIN(parameter));
|
ps.setBytes(i, UUIDConverter.UUID_TO_BIN(parameter));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,7 +51,7 @@ public class UUIDBinaryTypeHandler extends BaseTypeHandler<UUID> {
|
|||||||
@Override
|
@Override
|
||||||
public UUID getNullableResult(ResultSet rs, String columnName)
|
public UUID getNullableResult(ResultSet rs, String columnName)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
return BIN_TO_UUID(rs.getBytes(columnName));
|
return UUIDConverter.BIN_TO_UUID(rs.getBytes(columnName));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -92,7 +65,7 @@ public class UUIDBinaryTypeHandler extends BaseTypeHandler<UUID> {
|
|||||||
@Override
|
@Override
|
||||||
public UUID getNullableResult(ResultSet rs, int columnIndex)
|
public UUID getNullableResult(ResultSet rs, int columnIndex)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
return BIN_TO_UUID(rs.getBytes(columnIndex));
|
return UUIDConverter.BIN_TO_UUID(rs.getBytes(columnIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,6 +79,6 @@ public class UUIDBinaryTypeHandler extends BaseTypeHandler<UUID> {
|
|||||||
@Override
|
@Override
|
||||||
public UUID getNullableResult(CallableStatement cs, int columnIndex)
|
public UUID getNullableResult(CallableStatement cs, int columnIndex)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
return BIN_TO_UUID(cs.getBytes(columnIndex));
|
return UUIDConverter.BIN_TO_UUID(cs.getBytes(columnIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package com.mingliqiye.utils.uuid.typehandlers;
|
||||||
|
|
||||||
|
import com.mingliqiye.utils.uuid.UUID;
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user