Compare commits

...

1 Commits
master ... dev

Author SHA1 Message Date
a081744f14
refactor(mybatis):重构类型处理器实现以提升可维护性
移除 Kotlin 编写的 DateTimeTypeHandler 和 UUID 相关类型处理器,
新增 Java 编写的通用 QuickBaseTypeHandler 抽象类及辅助类,统一处理 MyBatis 类型转换逻辑。同时更新 UUID 类的 toString 方法,
增强不同版本 UUID 的信息展示。升级项目版本至 4.2.4。
2025-09-21 21:55:43 +08:00
8 changed files with 249 additions and 503 deletions

View File

@ -16,13 +16,13 @@
# ProjectName mingli-utils
# ModuleName mingli-utils
# CurrentFile gradle.properties
# LastUpdate 2025-09-21 15:38:52
# LastUpdate 2025-09-21 21:55:23
# UpdateUser MingLiPro
#
JDKVERSIONS=1.8
GROUPSID=com.mingliqiye.utils
ARTIFACTID=mingli-utils
VERSIONS=4.1.9
VERSIONS=4.2.4
signing.keyId=B22AA93B
signing.password=
signing.secretKeyRingFile=secret.gpg

View File

@ -0,0 +1,47 @@
/*
* 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 CallType.java
* LastUpdate 2025-09-21 21:06:52
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.mybatis;
/**
* CallType枚举类定义了不同的调用类型
* 用于标识数据库操作中结果集和可调用语句的访问方式
*/
public enum CallType {
/**
* 通过索引访问结果集
* 使用数字索引位置来获取结果集中的数据
*/
RESULTSET_INDEX,
/**
* 通过名称访问结果集
* 使用列名来获取结果集中的数据
*/
RESULTSET_NAME,
/**
* 通过索引访问可调用语句
* 使用数字索引位置来获取可调用语句中的数据
*/
CALLABLE_STATEMENT_INDEX
}

View File

@ -0,0 +1,126 @@
/*
* 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 QuickBaseTypeHandler.java
* LastUpdate 2025-09-21 21:10:36
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.mybatis;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 抽象类 QuickBaseTypeHandler MyBatis BaseTypeHandler 的扩展
* 提供了统一处理数据库字段与 Java 类型之间转换的抽象方法
* 子类需要实现 getValue setValue 方法来完成具体的类型转换逻辑
*
* @param <T> 要处理的 Java 类型
*/
public abstract class QuickBaseTypeHandler<T> extends BaseTypeHandler<T> {
/**
* 抽象方法用于从数据库结果中获取并转换为 Java 类型 T
*
* @param vg 值获取器封装了 ResultSet CallableStatement
* @param ct 调用类型标识当前是从 ResultSet 还是 CallableStatement 获取数据
* @param ci 列索引可为 null
* @param cn 列名可为 null
* @return 转换后的 Java 类型 T 实例
* @throws SQLException SQL 执行异常时抛出
*/
public abstract T getValue(
QuickBaseTypeHandlerValueGetter vg,
CallType ct,
Integer ci,
String cn
) throws SQLException;
/**
* 抽象方法用于将 Java 类型 T 设置到 PreparedStatement
*
* @param ps PreparedStatement 对象
* @param index 参数索引位置
* @param parameter Java 类型 T 的实例
* @param jdbcType JDBC 类型
* @throws SQLException SQL 执行异常时抛出
*/
public abstract void setValue(PreparedStatement ps, int index, T parameter, JdbcType jdbcType) throws SQLException;
/**
* 实现 BaseTypeHandler setNonNullParameter 方法
* 将非空参数设置到 PreparedStatement
*
* @param ps PreparedStatement 对象
* @param i 参数索引位置
* @param parameter Java 类型 T 的实例非空
* @param jdbcType JDBC 类型
* @throws SQLException SQL 执行异常时抛出
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
setValue(ps, i, parameter, jdbcType);
}
/**
* 实现 BaseTypeHandler getNullableResult 方法
* 通过列名从 ResultSet 中获取可能为 null 的结果
*
* @param rs ResultSet 对象
* @param columnName 数据库列名
* @return 转换后的 Java 类型 T 实例可能为 null
* @throws SQLException SQL 执行异常时抛出
*/
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
return getValue(new QuickBaseTypeHandlerValueGetter(null, rs), CallType.RESULTSET_NAME, null, columnName);
}
/**
* 实现 BaseTypeHandler getNullableResult 方法
* 通过列索引从 ResultSet 中获取可能为 null 的结果
*
* @param rs ResultSet 对象
* @param columnIndex 数据库列索引
* @return 转换后的 Java 类型 T 实例可能为 null
* @throws SQLException SQL 执行异常时抛出
*/
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return getValue(new QuickBaseTypeHandlerValueGetter(null, rs), CallType.RESULTSET_NAME, columnIndex, null);
}
/**
* 实现 BaseTypeHandler getNullableResult 方法
* 通过列索引从 CallableStatement 中获取可能为 null 的结果
*
* @param cs CallableStatement 对象
* @param columnIndex 数据库列索引
* @return 转换后的 Java 类型 T 实例可能为 null
* @throws SQLException SQL 执行异常时抛出
*/
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return getValue(new QuickBaseTypeHandlerValueGetter(cs, null), CallType.CALLABLE_STATEMENT_INDEX, columnIndex, null);
}
}

View File

@ -0,0 +1,64 @@
/*
* 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 QuickBaseTypeHandlerValueGetter.java
* LastUpdate 2025-09-21 21:07:10
* UpdateUser MingLiPro
*/
package com.mingliqiye.utils.mybatis;
import java.sql.CallableStatement;
import java.sql.ResultSet;
/**
* QuickBaseTypeHandlerValueGetter类用于封装CallableStatement和ResultSet对象的获取操作
* 该类提供了对存储过程调用结果和查询结果集的统一访问接口
*/
public class QuickBaseTypeHandlerValueGetter {
private final CallableStatement callableStatement;
private final ResultSet resultSet;
/**
* 构造函数初始化QuickBaseTypeHandlerValueGetter实例
*
* @param callableStatement 存储过程调用语句对象用于执行存储过程
* @param resultSet 查询结果集对象用于获取查询结果
*/
public QuickBaseTypeHandlerValueGetter(CallableStatement callableStatement, ResultSet resultSet) {
this.callableStatement = callableStatement;
this.resultSet = resultSet;
}
/**
* 获取结果集对象
*
* @return ResultSet 查询结果集对象
*/
public ResultSet getResultSet() {
return resultSet;
}
/**
* 获取存储过程调用语句对象
*
* @return CallableStatement 存储过程调用语句对象
*/
public CallableStatement getCallableStatement() {
return callableStatement;
}
}

View File

@ -1,102 +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 DateTimeTypeHandler.kt
* LastUpdate 2025-09-15 13:53:53
* 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,
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}")
}
}
}

View File

@ -1,279 +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 UUIDTypeHandler.kt
* LastUpdate 2025-09-15 13:54:18
* 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)
}
}

View File

@ -1,119 +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 MysqlUUIDBinaryTypeHandler.kt
* LastUpdate 2025-09-15 13:54: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))
}
}

View File

@ -16,7 +16,7 @@
* ProjectName mingli-utils
* ModuleName mingli-utils.main
* CurrentFile UUID.kt
* LastUpdate 2025-09-19 20:22:27
* LastUpdate 2025-09-21 21:53:40
* UpdateUser MingLiPro
*/
@ -588,6 +588,15 @@ class UUID : Serializable {
* @return 包含 UUID 和版本号的字符串
*/
override fun toString(): String {
when (version) {
1 -> {
return "UUID(uuid=${getString()},version=${version},datetime=${getDateTime()},mac=${getMac()})"
}
6, 7 -> {
return "UUID(uuid=${getString()},version=${version},datetime=${getDateTime()})"
}
}
return "UUID(uuid=${getString()},version=${version})"
}