使用@TypeDefs自定义数据类型

使用@TypeDefs自定义数据类型

  • 使用场景:自定义Long数组,使数据库数据类型为bigint[],而不是bytea

实现

  1. 定义公共的ArraySqlTypeDescriptor
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.sql.BasicBinder;
import org.hibernate.type.descriptor.sql.BasicExtractor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;

import java.sql.*;

public class ArraySqlTypeDescriptor implements SqlTypeDescriptor {
   

    public static final ArraySqlTypeDescriptor INSTANCE = new ArraySqlTypeDescriptor();

    @Override
    public int getSqlType() {
   
        return Types.ARRAY;
    }

    @Override
    public boolean canBeRemapped() {
   
        return true;
    }

    @Override
    public <X> ValueBinder<X> getBinder(JavaTypeDescriptor<X> javaTypeDescriptor) {
   
        return new BasicBinder<X>(javaTypeDescriptor, this) {
   
            @Override
            protected void doBind(
                    PreparedStatement st,
                    X value,
                    int index,
                    WrapperOptions options
            ) throws SQLException {
   
                AbstractArrayTypeDescriptor<Object> abstractArrayTypeDescriptor
                        = (AbstractArrayTypeDescriptor<Object>) javaTypeDescriptor;
                st.setArray(
                        index,
                        st.getConnection().createArrayOf(
                                abstractArrayTypeDescriptor.getSqlArrayType(),
                                abstractArrayTypeDescriptor.unwrap(
                                        value,
                                        Object[].class,
                                        options
                                )
                        )
                );
            }

            @Override
            protected void doBind(
                    CallableStatement st,
                    X value,
                    String name,
                    WrapperOptions options
            ) throws SQLException {
   
                throw new UnsupportedOperationException(
                        "Binding by name is not supported!"
                );
            }
        };
    }

    @Override
    public <X> ValueExtractor<X> getExtractor(
            final JavaTypeDescriptor<X> javaTypeDescriptor) {
   
        return new BasicExtractor<X>(javaTypeDescriptor, this) {
   
            @Override
            protected X doExtract(
                    ResultSet rs,
                    String name,
                    WrapperOptions options
            ) throws SQLException {
   
                return javaTypeDescriptor.wrap(
                        rs.getArray(name),
                        options
                );
            }

            @Override
            protected X doExtract(
                    CallableStatement statement,
                    int index,
                    WrapperOptions options
            ) throws SQLException {
   
                return javaTypeDescriptor.wrap(
                        statement.getArray(index),
                        options
                );
            }

            @Override
            protected X doExtract(
                    CallableStatement statement,
                    String name,
                    WrapperOptions options
            ) throws SQLException {
   
                return javaTypeDescriptor.wrap(
                        statement.getArray(name),
                        options
                );
            }
        };
    }
}
    1. 定义抽象类AbstractArrayTypeDescriptor,实现解析、复制和封装数据
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.java.MutableMutabilityPlan;
import org.hibernate.usertype.DynamicParameterizedType;

import java.sql.Array;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Properties;

public abstract class AbstractArrayTypeDescriptor<T> extends AbstractTypeDescriptor<T> implements DynamicParameterizedType {
   

    private Class<T> arrayObjectClass;

    @Override
    public void setParameterValues(Properties parameters) {
   
        arrayObjectClass = ((ParameterType) parameters
                .get(PARAMETER_TYPE))
                .getReturnedClass();

    }

    public AbstractArrayTypeDescriptor(Class<T> arrayObjectClass) {
   
        super(
                arrayObjectClass,
                (MutabilityPlan<T>) new MutableMutabilityPlan<Object>() {
   
                    @Override
                    protected T deepCopyNotNull(Object value) {
   
                        return ArrayUtil.deepCopy(value);
                    }
                }
        );
        this.arrayObjectClass = arrayObjectClass;
    }

    @Override
    public boolean areEqual(Object one, Object another) {
   
        if (one == another) {
   
            return true;
        }
        if (one == null || another == null) {
   
            return false;
        }
        return ArrayUtil.isEquals(one, another);
    }

    @Override
    public String toString(Object value) {
   
        return Arrays.deepToString((Object[]) value);
    }

    @Override
    public T fromString(String string) {
   
        return ArrayUtil.fromString(
                string,
                arrayObjectClass
        );
    }

    @SuppressWarnings({
   "unchecked"}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ModuleNotFoundError是一个Python异常,表明没有找到所需的模块。在这里,它指出找不到名为'sklearn.utils._typedefs'的模块。 'sklearn.utils._typedefs'是Scikit-learn库的一部分,这是一个流行的用于机器学习的Python库。该模块通常包含数据类型定义,用于通过Scikit-learn库进行机器学习任务。 如果遇到此错误,通常是因为在您的Python环境中缺少Scikit-learn库或其依赖项之一。您可以尝试在命令行中运行以下命令,以确保Scikit-learn库被正确安装: pip list 如果Scikit-learn库已经被安装,您可以尝试升级它: pip install --upgrade scikit-learn 您也可以尝试卸载并重新安装Scikit-learn库: pip uninstall scikit-learn pip install scikit-learn 如果以上方法均无法解决问题,则可能需要更新Python环境或其它的依赖项。 ### 回答2: ModuleNotFoundError: No module named 'sklearn.utils._typedefs' 这个错误通常是由于sklearn包里缺少了所需模块造成的。具体来说,是因为缺少了scikit-learn的utils._typedefs模块。 sklearn.utils._typedefs模块是一个定义了一些类型别名和类型变量的辅助模块,用于简化代码实现和提高可读性。然而,有时候这个模块可能会出现找不到的情况,导致程序报错。 解决这个问题的方法有很多种,其中比较常见和有效的方法包括: 1.升级scikit-learn版本,更新utils._typedefs模块,解决对其的依赖问题。 2.安装缺少的模块,可以使用pip命令安装scikit-learn的utils._typedefs模块或直接使用Anaconda进行安装。 3.将所需的utils._typedefs模块手动添加到Python的路径中,这个方法需要具备一定的编程技能,对一些较为复杂的程序,效果可能并不理想。 总之,ModuleNotFoundError: No module named 'sklearn.utils._typedefs' 错误通常出现在引用标准库中的部分,可以使用升级/安装/手动添加库等方式解决这个问题。同时,在编程过程中,我们也应该注意检查程序引用的库是否存在,以避免出现类似的问题。 ### 回答3: 这个错误是因为sklearn.utils._typedefs模块在当前的Python环境中不存在。有几种可能的原因: - 使用的Python环境中没有安装sklearn库或安装的版本过低,导致相关模块不被识别。 - 在导入模块时输出了错误的名称,因为该模块的名称拼写错误或被更改了。 - 使用了不同版本的sklearn库,导致所需的模块在该版本中不可用。 要解决这个问题,可以尝试以下几种方法: - 确保已正确安装和载入scikit-learn库。可以使用pip命令或者conda(如果你使用了anaconda环境)来安装最新版本。 - 检查扩展名是否正确。确保正确调用_sklearn.utils._typedefs,而不是_sklearn.util._typedefs或_sklearn.utils_typedefs。 - 检查是否有多个版本的sklearn库(或子模块)安装在不同的目录中,而你尝试在导入模块时却未指定正确的位置。可以使用sys.path来查看Python系统路径,以确保正在从正确位置导入模块。 - 尝试在命令行中显式地导入所需的模块,以查看是否存在其他错误或依赖关系。例如,导入sklearn库中的其他模块,以确定是否有任何依赖项缺失或读取权限问题。 总之,这个错误通常是由于安装或导入库的问题导致的,所以只需要确保正确安装和导入即可。如果以上方法仍不能解决问题,可以查看更具体的错误信息,或者在开发者社区中寻求帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值