IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Mybatis中关于自定义typeHandler的详细使用以及心得体会-超级详细 -> 正文阅读

[大数据]Mybatis中关于自定义typeHandler的详细使用以及心得体会-超级详细

1. 什么是 typeHandler

typeHandler 是MyBatis框架集成的一个数据类型处理器,用于 java 数据类型 和 数据库类型 之间的互转,当然java对于数据库的操作需要jdbc,所以可以理解为 java数据类型 和 jdbc类型 之间的转换器,专业用词就是 javaTypejdbcType 之间的转换,可以见下表所示:
在这里插入图片描述

2. typeHandler的隐式声明

MyBatis 系统已经创建好所常用的 typeHandler。在大部分的情况下无须显式地声明 jdbcType 和 javaType,或者用 typeHandler 去指定对应的字段来实现数据类型转换,因为 MyBatis 系统会自己探测映射的数据类型,来自动选择 typeHandler

3. 自定义typeHandler

虽然 typeHandler 所提供的转换类型很多,但有的时候仍然不能满足我们对于某一字段的转换要求,这时就需要自定义类型处理器。
参考了网上很多资料,大部分都讲的不太明白,以下是自己通过一天的不断测试,总结的心得体会,如有什么错误,欢迎指正。

3.1 需求:将数据库里的 datetime 类型 转换到Java类型是 String,且格式为 “2022/3/12 11:19:34”

如果不自定义类型处理器,Mybatis转换的格式为
数据库数据库 java字符串在这里插入图片描述

虽然默认处理器可以实现自动转换,但是 java 的时间转换格式不能自定义,所以用自定义处理器来实现

  1. 实现泛型接口TypeHandler<String>的四个方法
/*
* 自定义 数据库dataTime 与 java String 转换
* */
public class StringTypeHandle implements TypeHandler<String> {

//  将java类型 转换成 数据库需要的类型
    public void setParameter(PreparedStatement preparedStatement, int i, String str, JdbcType jdbcType) throws SQLException {
       /*
        * 调用mabatis所集成的处理器转换过去
        * 框架所提供的转换方法更加强大
        * 即在插入和更新数据时在字段处不引用该处理器
        * */
    }

    //  将数据库中类型 转换成java类型
    public String getResult(ResultSet resultSet, String s) throws SQLException {
        Date date = resultSet.getDate(s);
        Time time = resultSet.getTime(s);
        java.util.Date dateTime = new java.util.Date(date.getTime()+time.getTime()+8*60*60*1000);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        return sdf.format(dateTime);
    }
    //  将数据库中类型 转换成java类型
    public String getResult(ResultSet resultSet, int i) throws SQLException {
        Date date = resultSet.getDate(i);
        Time time = resultSet.getTime(i);
        java.util.Date dateTime = new java.util.Date(date.getTime()+time.getTime()+8*60*60*1000);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        return sdf.format(dateTime);
    }
    //  将数据库中类型 转换成java类型
    public String getResult(CallableStatement callableStatement, int i) throws SQLException {
        Date date = callableStatement.getDate(i);
        Time time = callableStatement.getTime(i);
        java.util.Date dateTime = new java.util.Date(date.getTime()+time.getTime()+8*60*60*1000);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        return sdf.format(dateTime);
    }
}
  1. setParameter(PreparedStatement preparedStatement, int i, String str, JdbcType jdbcType) 是将 java数据类型 转换成 数据库需要的类型PreparedStatement preparedStatement是在执行更新或者添加表数据时给占位符 ?设置值,int i表示第几个占位符,即位置,String str是需要处理的字符串,JdbcType jdbcType是数据库的数据类型(目前没发现作用)
  2. String getResult()有三个重载方法,目的都是将 数据库中的类型 转换成 java类型,只是有不同的方式提取数据库的值,可以是根据字段位置,字段名称,存储过程调用等
  1. mybatis-config.xml (mybatis配置文件) 配置文件中进行注册
<typeHandlers>
	<typeHandler handler="com.cyx.entity.StringTypeHandle"></typeHandler>
</typeHandlers>

注意在 <configuration> </configuration> 中的位置顺序

  1. 所需要转换的字段处引用 typeHandler = “com.cyx.entity.StringTypeHandle”(自己的类名)
<mapper namespace="com.cyx.mapper.TestMapper">

    <resultMap id="TestResult" type="testData">
        <result column="createTime" property="createTime" typeHandler="com.cyx.entity.StringTypeHandle"/>
    </resultMap>
    <select id="findAll" resultMap="TestResult">
        select * from test
    </select>

</mapper>
3.2 需求:将 数据库中varchar类型 “-1.201,-1.214,-0.254,…” 转换成java类型 Double[] {-1.201,-1.214,-0.254,…}

知识点:TypeHandler<?>泛型中是引用类型,不能填基本数据类型,基本数据类型要转换成引用类型-包装类,因为实质上都是 Object 的转换,而Object是一个类
具体基本数据类型和引用类型的互相转换,可以看 23.Java之包装类(包装类的分类,装箱,拆箱)

  1. 实现泛型接口TypeHandler<Double[]>的四个方法
/*
 * 自定义 数据库 varchar 转换成 double[]数组
 * */
public class DoubleTypeHandle implements TypeHandler<Double[]> {
    //  将java类型 转换成 数据库需要的类型
    public void setParameter(PreparedStatement preparedStatement, int i, Double[] doubles, JdbcType jdbcType) throws SQLException {
        String s1 = "";
        for (int j = 0; j < doubles.length; j++) {
            if (j != 0)
            {
                s1 += ",";
            }
            s1 += String.valueOf(doubles[j]);
        }
        preparedStatement.setString(i,s1);
    }
    //  将数据库中类型 转换成java类型
    public Double[] getResult(ResultSet resultSet, String s) throws SQLException {
        String s1 = resultSet.getString(s);
        Double points[] = null;
        if (s1 != null) {
            String str[] = s1.split(",");
            points = new Double[str.length];
            for (int j = 0; j < str.length; j++) {
                points[j] = Double.parseDouble(str[j]);
            }
        }
        return points;
    }

    public Double[] getResult(ResultSet resultSet, int i) throws SQLException {
        String s1 = resultSet.getString(i);
        Double points[] = null;
        if (s1 != null) {
            String str[] = s1.split(",");
            points = new Double[str.length];
            for (int j = 0; j < str.length; j++) {
                points[j] = Double.parseDouble(str[j]);
            }
        }
        return points;
    }

    public Double[] getResult(CallableStatement callableStatement, int i) throws SQLException {
        String s1 = callableStatement.getString(i);
        Double points[] = null;
        if (s1 != null) {
            String str[] = s1.split(",");
            points = new Double[str.length];
            for (int j = 0; j < str.length; j++) {
                points[j] = Double.parseDouble(str[j]);
            }
        }
        return points;
    }
}
  1. mybatis-config.xml (mybatis配置文件) 配置文件中进行注册
<!--    注册类型处理器 -->
    <typeHandlers>
        <typeHandler handler="com.cyx.entity.DoubleTypeHandle"></typeHandler>
    </typeHandlers>
  1. 所需要转换的字段处引用 typeHandler = “com.cyx.entity.DoubleTypeHandle” (自己的类名)
<mapper namespace="com.cyx.mapper.TestMapper">

    <insert id="addObj" parameterType="testData">
        insert into test(name,createTime,isOnline,points) values (#{name},#{createTime},#{isOnline},#{points,typeHandler=com.cyx.entity.ArrayTypeHandle})
    </insert>

    <resultMap id="TestResult" type="testData">
        <result column="points" property="points" typeHandler="com.cyx.entity.DoubleTypeHandle"/>
    </resultMap>
    <select id="findAll" resultMap="TestResult">
        select * from test
    </select>

</mapper>

4. 扩充

如果从数据库里取的值想转换成几个不同类型的,但是写几个重复的类型处理器确实会有些繁琐,这时候可以直接实现接口TypeHandler,对 Object o 进行类的判断,再做不同的处理

public class ArrayTypeHandle implements TypeHandler {
//  将java类型 转换成 数据库需要的类型
    public void setParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {
    
    }

    //  将数据库中类型 转换成java类型
    public Object getResult(ResultSet resultSet, String s) throws SQLException {
        return null;
    }

    public Object getResult(ResultSet resultSet, int i) throws SQLException {
        return null;
    }

    public Object getResult(CallableStatement callableStatement, int i) throws SQLException {
        return null;
    }
}
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 21:52:47  更:2022-03-13 21:55:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:52:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码