MyBatis typeHandler接口的定义和使用

 更新时间:2023年05月17日 10:23:01   作者:shenzhenNBA  
TypeHandler被称作类型处理器,MyBatis在设置预处理语句中的参数或从结果集中取出一个值时,都会用类型处理器将Java对象转化为数据库支持的类型或者将获取到数据库值以合适的方式转换成Java类型,感兴趣的同学可以参考下文

在Java项目中一般我们都需要处理数据库表到Java的Bean对象的映射关系,常用的ORM框架有mybatis,在大多数据情况下,数据库的数据类型到Java的数据类型满足我们的需要,例如varchar到String,int到int等,但是有些时候项目需要完成数据库数据类型到Java的某个数据类型的映射,mybatis现有的typeHandler不满足要求,所以需要用户自己开发用户自定义的typeHandler类型,以满足要求;

例如,数据库需要保存用户喜欢的产品,表字段以varchar类型保存,同时是一个符合JSON格式的列表,每个产品信息按 "产品名称(产品代码)",所以最终结果:["产品名称1(产品代码1)","产品名称2(产品代码2)"],即符合列表格式的JSON字符串,其对应的Java的Bean变量为一个字符型的List变量,即List<String>,所以需要完成数据库表字段的Varchar数据类型到Java的List<String>的映射处理关系,现有的typeHandler类型不足以满足要求,所以我们需要开发一个用户自定义的mybatis的typeHandler来处理这个问题,然后应用到mapper的XML文件中,大致框架代码(具体自行丰富补充)和步骤如下:

1,引入相关依赖Jar包,版本看自行根据需要定义

<!-- mybatis依赖 -->
<dependency>  
    <groupId>org.mybatis.spring.boot</groupId>  
    <artifactId>mybatis-spring-boot-starter</artifactId>  
    <version>2.0.0</version>  
</dependency>
<!-- 数据库连接池 -->
<dependency>  
    <groupId>com.alibaba</groupId>  
    <artifactId>druid</artifactId>  
    <version>1.1.10</version>  
</dependency>
<!-- mysql数据库连接 -->
<dependency>  
    <groupId>mysql</groupId>  
    <artifactId>mysql-connector-java</artifactId>  
    <version>5.1.48</version>
	<!--此仅参考,版本根据需要而定-->
</dependency>

2,用户相关的JavaBean对象

package com.xx.yy.zz.model; 
import java.util.List;
public class UserProduct {
	private String userName;
	private String userCode
	//DB字段以JSON格式保存:["产品名1(产品代码1)","产品名2(产品代码2)",...]
	private List<String> likeProducts = new ArraryList<String>();
	//...other... 
	//...setter/getter省略...
}

3,自定义DB表字段(内容为符合JSON格式的字符串列表)的varchar数据类型到Java的List的映射处理关系的typeHandler开发

package com.xx.yy.zz.orm; 
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
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 com.alibaba.fastjson.JSONObject; //需要fastjson的jar包支持
@MappedTypes(List.class) //映射的Java数据类型
@MappedJdbcTypes(JdbcType.VARCHAR)  //映射的JDBC数据类型
public class MyListTypeHandler extends BaseTypeHandler<List<String>>{
	//List列表中如果为其它对象xxJavaBean则把String换为目标对象	
	//重写mybatis设置参数的方法
	@Override
	public void setNonNullParameter(PreparedStatement ps,int i, List<String> param,
		JdbcType jdbcType) throws SQLException {
		ps.setString(i, JSONObject.toJSONString(param));
	}
	//重写mybatis获取字段字符串型内容到Bean类List变量的方法
	@Override
	public List<String> getNullableResult(ResultSet rs, String columnName)
		throws SQLException{
		String tempJson = rs.getString(columnName);
		if (null != tempJson && !tempJson.trim().isEmpty()){
			return JSONObject.parseArray(tempJson,String.class);
		}
		return null;
	}
	@Override
	public List<String> getNullableResult(ResultSet rs, int columnIndex)
		throws SQLException{
		String tempJson = rs.getString(columnIndex);
		if (null != tempJson && !tempJson.trim().isEmpty()){
			return JSONObject.parseArray(tempJson,String.class);
		}
		return null;
	}
	@Override
	public List<String> getNullableResult(CallableStatement cs, int columnIndex)
		throws SQLException{
		String tempJson = cs.getString(columnName);
		if (null != tempJson && !tempJson.trim().isEmpty()){
			return JSONObject.parseArray(tempJson,String.class);
		}
		return null;
	}
}

4, 操作数据库的DAO层定义

package com.xx.yy.zz.dao;
import com.xx.yy.zz.model.UserProduct;
public interface UserProductDao {
	int insertRecord(UserProduct record);
	int updateRecord(UserProduct record);
	//...more code...
}

5,在springboot的配置yml文件中进行mybatis相关配置

#其它配置项省略

mybatis:

mapper-locations: classpath:mapper/*Mapper.xml

type-aliases-package: com.xx.yy.zz.model

6,在Mapper的XML文件中应用自定义的typeHandler类型,部分代码如下

<mapper namespace="com.xx.yy.zz.dao.UserProductDao" >
	<resultMap id="resultMap" type="com.xx.yy.zz.model.Product">
		<id column="id" property="id" jdbcType="Decimal">
		<result column="likeProdcts" property="likeProdcts" jdbcType="varchar"
			typeHandler="com.xx.yy.zz.orm.MyListTypeHandler">
		<!-- ...other result... -->
	</resultMap>
</mapper>
<!-- 新增 -->
<insert id="insertRecord" parameterType="UserProduct">
	insert into xxTable
	<trim prefix="(" suffix=")" suffixOverride=",">
		<if test="userName != null">
		userName,
		</if>
		<!-- ...other... -->
		<if test="likeProdcts != null">
		likeProdcts,
		</if>		
	</trim>
	<trim prefix=" values (" suffix=")" suffixOverride=",">
		<if test="userName != null">
		#{userName,jdbcType=varchar},
		</if
		<!-- ...other... -->
		<if test="likeProdcts != null">
		#{likeProdcts,jdbcType=varchar,typeHandler=com.xx.yy.zz.orm.MyListTypeHandler},
		</if>
	</trim>
</insert>
<!-- 更新 -->
<update id="updateRecord" parameterType="UserProduct">
	update xxTable 
	<set>
		<if test="likeProdcts != null">
		#{likeProdcts,jdbcType=varchar,typeHandler=com.xx.yy.zz.orm.MyListTypeHandler},
		</if>
		<!-- ...other... -->
	</set>
	where id = #{id,jdbcType=decimal}
</update>

这样处理之后即可满足,数据库表字段数据类型为varchar类型,字段保存内容为符合JSON格式的字符串,到JavaBean对象为List<String>列表类型的映射和处理,从Java持久化到表字段时自动转化为符合JSON格式的内容保存,另一方面,程序从DB表字段内容读取到Java程序时内容自动转化为List<String>,非常方便,另外数组类型String[]也可以,但是Java对数组的增删等操作,不如 List 方便,所以推荐使用 List 比较好,当然,本例List中列表的项为String类型,那如果为某个JavaBean对象呢?其实完全可以,方法类似的,这里为简单举例就用String,本身String也是一个对象;

除了我们自定义的 MyListTypeHandler 类型外,其mybatis本身内部已经含有很多的typeHandler类型,例如:BooleanTypeHandler,ByteTypeHandler,ShortTypeHandler,IntegerTypeHandler,LongTypeHandler,FloatTypeHandler,DoubleTypeHandler,StringTypeHandler,ClobTypeHandler,DateTypeHandler等等这些其实就是默认已经在为我们处理完成映射关系了,只不过内部已经有,且直接内部自动完成映射,我们不需要显示指定typeHandler而已,这就是mybatis框架的功能,已经帮我们完成了绝大部分功能,我们仅需处理一下特别的或特定需要即可;

到此这篇关于MyBatis typeHandler接口的定义和使用的文章就介绍到这了,更多相关MyBatis typeHandler内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Spring Security 捕获 filter 层面异常返回我们自定义的内容

    详解Spring Security 捕获 filter 层面异常返回我们自定义的内容

    Spring 的异常会转发到 BasicErrorController 中进行异常写入,然后才会返回客户端。所以,我们可以在 BasicErrorController 对 filter异常进行捕获并处理,下面通过本文给大家介绍Spring Security 捕获 filter 层面异常,返回我们自定义的内容,感兴趣的朋友一起看看吧
    2022-05-05
  • 并发编程之Java内存模型volatile的内存语义

    并发编程之Java内存模型volatile的内存语义

    这篇文章主要介绍了并发编程之Java内存模型volatile的内存语义,理解volatile特性的一个好办法是把对volatile变量的单个读/写,看成是使用同一个锁对单个读/写操作做了同步。下面我们一起进入文章看看具体例子吧,需要的小伙伴可以参考下
    2021-11-11
  • jackson 实现null转0 以及0转null的示例代码

    jackson 实现null转0 以及0转null的示例代码

    这篇文章主要介绍了jackson 实现null转0 以及0转null的示例代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Java基础泛型详情

    Java基础泛型详情

    这篇文章主要介绍了Java基础泛型详情,泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,下面文章的详细介绍,需要的朋友可以参考一下
    2022-04-04
  • 彻底搞懂Java多线程(一)

    彻底搞懂Java多线程(一)

    这篇文章主要给大家介绍了关于Java面试题之多线程和高并发的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2021-07-07
  • 详解Spring Boot 异步执行方法

    详解Spring Boot 异步执行方法

    这篇文章主要介绍了Spring Boot 异步执行方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • JAVA基础--如何通过异常处理错误

    JAVA基础--如何通过异常处理错误

    这篇文章主要介绍了JAVA中如何通过异常处理错误,文中讲解非常细致,代码帮助大家更好的理解,感兴趣的朋友可以了解下
    2020-06-06
  • Java中Jedis基本使用

    Java中Jedis基本使用

    Redis的Java实现的客户端,本文主要介绍了Java中Jedis基本使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • 详解springboot的三种启动方式

    详解springboot的三种启动方式

    这篇文章主要介绍了详解springboot的三种启动方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • java字符串遍历的几种常用方法总结

    java字符串遍历的几种常用方法总结

    Java字符串是一系列的Unicode字符序列,但是它却常常被误认为是char序列,这篇文章主要给大家介绍了关于java字符串遍历的几种常用方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-04-04

最新评论