Ibatis的类型处理器TypeHandler解析

合集下载

mybatis 类型 映射原理

mybatis 类型 映射原理

mybatis 类型映射原理
MyBatis类型映射原理:
MyBatis是一种流行的持久化框架,它提供了一种简单的方法将数据库中的数据映射到Java对象上。

类型映射是MyBatis中的一个重要概念,它允许我们在数据库和Java之间建立一种对应关系,使数据的读写操作更加方便。

在MyBatis中,类型映射是通过TypeHandler完成的。

TypeHandler负责将数据库中的数据类型转换为Java对象,并将Java对象转换为数据库中的数据类型。

TypeHandler是一个接口,我们可以通过实现该接口来定义自己的类型映射规则。

MyBatis内置了许多常用的TypeHandler,例如IntegerTypeHandler、StringTypeHandler等。

当我们在映射文件或注解中指定某个字段的类型时,MyBatis会自动选择合适的TypeHandler进行类型转换。

此外,MyBatis还提供了注解来简化类型映射的配置。

我们可以通过
@MappedTypes和@MappedJdbcTypes注解来指定Java类型和数据库类型之间的映射关系。

对于复杂的类型映射,MyBatis还支持自定义TypeHandler。

我们可以实现TypeHandler接口,重写其中的方法来完成自定义的类型转换逻辑。

总结起来,MyBatis的类型映射原理就是通过TypeHandler来处理数据库和Java类型之间的转换。

它提供了内置的TypeHandler,并支持自定义TypeHandler 来满足更复杂的类型转换需求。

通过合理配置类型映射,我们可以更方便地操作数据库中的数据。

mybatis自定义类型处理器TypehHandler示例详解

mybatis自定义类型处理器TypehHandler示例详解

mybatis⾃定义类型处理器TypehHandler⽰例详解前⾔当⼤家使⽤mybatis作为持久层框架时,在存储和查询数据时,只需要在mapper.xml⽂件中配置好对应字段的JdbcType和JavaType,mybatis就可以帮我们转化对应的类型。

这背后是有mybatis内置的类型转换器做转换(可见源码TypeHandlerRegistry)。

但是有时候,我们会对某些字段做特殊处理,⽐如加密和解密、状态转换、类型转换等。

这个时候我们需要⾃定义类型转换器。

类架构从上⾯的图中可以看出MyBatis中整个类型处理器实现架构,TypeHandler接⼝定义了类型处理器,⽽TypeReference抽象类则定义了⼀个类型引⽤,⽤于引⽤⼀个泛型类型(此处很抽象,不好理解,详见后续解析),BaseTypeHandler则是类型处理器的基础,是所有类型处理器的公共模块,⼏乎所有的类型处理器都是通过直接继承BaseTypeHandler来实现的。

⼀、原理使⽤场景:mybatis在预处理语句(PreparedStatement)中设置⼀个参数时,或者从结果集(ResultSet)中取出⼀个值时,都会⽤到TypeHandler。

它的作⽤就是将java类型(javaType)转化为jdbc类型(jdbcType),或者将jdbc类型(jdbcType)转化为java类型(javaType)。

⼆、⾃定义类型处理器实现TypeHandler接⼝或者继承BaseTypehandlerTypeHandler是⼀个接⼝,它定义了如下四个⽅法,实现类必须去实现,⽅法如下:void setParameter(PreparedStatement var1, int var2, T var3,JdbcType var4) throws SQLException;T getResult(ResultSet var1, String var2) throws SQLException;T getResult(ResultSet var1, int var2) throws SQLException;T getResult(CallableStatement var1, int var2) throws SQLException;}setParameter:通过preparedStatement对象设置参数,将T类型的数据存⼊数据库。

mybatis typehandler运行原理 -回复

mybatis typehandler运行原理 -回复

mybatis typehandler运行原理-回复MyBatis是一个流行的Java持久层框架,它提供了方便的数据库访问方式。

在MyBatis中,通过使用TypeHandler来处理Java对象与数据库字段之间的映射关系。

本篇文章将介绍MyBatis TypeHandler的运行原理,并一步一步回答中括号中的问题。

1. TypeHandler概述TypeHandler是MyBatis中一个重要的组件,它负责Java对象和数据库字段之间的类型转换操作。

MyBatis提供了许多预定义的TypeHandler,用于处理各种常见的Java和数据库类型之间的映射关系。

如果需要处理自定义的Java类型或数据库类型,可以编写自己的TypeHandler实现。

2. TypeHandler接口TypeHandler接口是所有TypeHandler实现类的父接口,其中定义了一系列处理Java对象与数据库字段之间映射的方法。

其中最重要的方法是setParameter和getResult,分别用于设置参数值和获取结果值。

3. 数据库类型到Java类型的映射在使用TypeHandler时,MyBatis首先根据数据库字段的类型确定具体使用哪个TypeHandler处理。

MyBatis提供了一系列内置的TypeHandler,每个TypeHandler负责处理一种数据库类型。

内置TypeHandler根据数据库类型的不同,使用不同的Java数据类型进行映射,如Integer、String、BigDecimal等。

4. Java类型到数据库类型的映射当将Java对象保存到数据库中时,MyBatis会根据Java对象的类型使用对应的TypeHandler。

TypeHandler会将Java对象转换为数据库能够接受的类型,然后通过JDBC将数据存储到数据库中。

5. TypeHandler的注册所有的TypeHandler都需要进行注册才能被MyBatis框架识别和使用。

MyBatisPlus自动类型转换之TypeHandler

MyBatisPlus自动类型转换之TypeHandler

MyBatisPlus⾃动类型转换之TypeHandlerMyBatis Plus ⾃动类型转换之TypeHandler数据库表⾥有ids字段,存放的都是主键id,逗号分隔。

model⾥⾯是Set集合装Integer类型的 ids⽤MyBatis的TypeHandler做⾃动类型转换分三步:1.实体类需要加个注解@TableName(autoResultMap = true)2.对应对象的属性也需要加注解@TableField(typeHandler = SetTypeHandler.class)3.继承BaseTypeHandler实现其⽅法@MappedTypes(Set.class)@MappedJdbcTypes(JdbcType.VARCHAR)public class SetTypeHandler extends BaseTypeHandler<Set> {@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, Set parameter, JdbcType jdbcType)throws SQLException {String param = parameter.toString().replaceAll("\\[|\\]| ", "");ps.setString(i, param);}@Overridepublic Set<Integer> getNullableResult(ResultSet rs, String columnName)throws SQLException {String sqlSet = rs.getString(columnName);return getSet(sqlSet);}@Overridepublic Set<Integer> getNullableResult(ResultSet rs, int columnIndex)throws SQLException {String sqlSet = rs.getString(columnIndex);return getSet(sqlSet);}@Overridepublic Set<Integer> getNullableResult(CallableStatement cs, int columnIndex)throws SQLException {String sqlSet = cs.getString(columnIndex);return getSet(sqlSet);}private Set<Integer> getSet(String sqlSet) {if (StringUtils.isNotBlank(sqlSet)) {return Arrays.asList(sqlSet.split(",")).stream().map(Integer::parseInt).collect(Collectors.toSet());}return new HashSet();}}解释以上代码:实体类要转换的类型:Set@MappedTypes(Set.class)对应数据库表的字段类型:varchar@MappedJdbcTypes(JdbcType.VARCHAR)参数set,⽤来给参数PreparedStatement对象对应的列设置参数,预编译SQL语句,在SQL语句执⾏之前改变语句。

mybatis-plus如何配置自定义数据类型TypeHandle

mybatis-plus如何配置自定义数据类型TypeHandle

mybatis-plus如何配置⾃定义数据类型TypeHandle⽬录如何配置⾃定义数据类型TypeHandle1.背景2.举例3.TypeHandle配置⾃定义TypeHandler的使⽤笔记类型转换器还可以通过注解配置java类型和jdbc类型如何配置⾃定义数据类型TypeHandle1.背景mybatis-plus在mybatis的基础的上,做了全⾯增强功能,极⼤的提⾼了我们的开发效率。

有时候我们使⽤的实体字段类型,与数据库创建的字段类型⽆法对应上,这时候就需要配之⾃定义的类型处理类,来处理代码和数据库之间的数据流转。

2.举例我们有个实体类TestEntity,使⽤注解@TableName表⽰对应数据库表名为test@Data@TableName(value = "test")public class TestEntity{private static final long serialVersionUID = 8565214506859404278L;private String id;private String type;private Document content;}DAO层对象@Mapperpublic interface TestDao extends BaseMapper<TestEntity> {}XML⽂件<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.aisino.dao.TestDao"><resultMap type="com.aisino.entity.TestEntity" id="testMap"><result property="id" column="id"/><result property="type" column="name"/><result property="content" column="content"/></resultMap></mapper>其中Document使⽤的是org.w3c.dom.Document对象,数据库存储的字段类型为bytea,我这⾥使⽤的是postgresql,显然数据类型⽆法匹配,这⾥需要编写类型处理类进⾏数据类型转换。

basetypehandler使用

basetypehandler使用

basetypehandler使用关于basetypehandler的使用方法和功能的文章。

basetypehandler是MyBatis中的一个重要组件,它扮演着类型处理器(TypeHandler)的基础角色,用于处理Java对象与数据库字段类型之间的转换。

本篇文章将以basetypehandler的使用为主题,详细解答如何使用basetypehandler来实现Java对象与数据库字段类型之间的转换,并介绍其特点和优势。

一、什么是basetypehandler?basetypehandler是MyBatis中用于处理Java对象与数据库字段类型之间转换的基本类型处理器。

它属于MyBatis框架自带的类型处理器之一,我们可以直接调用它的API来实现数据类型转换。

basetypehandler支持多种常见数据类型的转换,如字符串、整数、日期等。

二、basetypehandler的使用方法1. 导入项目依赖在使用basetypehandler之前,首先需要在项目的配置文件(如pom.xml)中添加对MyBatis的依赖。

可以在Maven中央仓库搜索并添加MyBatis 相关的依赖,再使用Maven或Gradle进行项目构建。

2. 创建Java对象在代码中定义需要进行类型转换的Java对象。

假设我们有一个User类,其中包含一个age字段:javapublic class User {private int age;省略getter和setter方法}3. 创建TypeHandler接下来我们需要创建一个继承自basetypehandler的自定义类型处理器,用于处理User类中的age字段。

在创建TypeHandler时,需要指定Java 类型和数据库字段类型:javapublic class AgeTypeHandler extends BaseTypeHandler<Integer> { Overridepublic void setNonNullParameter(PreparedStatement preparedStatement, int i, Integer integer, JdbcType jdbcType) throws SQLException {preparedStatement.setInt(i, integer);}Overridepublic Integer getNullableResult(ResultSet resultSet, String s) throws SQLException {return resultSet.getInt(s);}Overridepublic Integer getNullableResult(ResultSet resultSet, int i) throws SQLException {return resultSet.getInt(i);}Overridepublic Integer getNullableResult(CallableStatement callableStatement, int i) throws SQLException {return callableStatement.getInt(i);}}在这个例子中,我们创建了一个AgeTypeHandler类,用于处理Integer 类型的age字段。

java mybatis booleantypehandler 用法

java mybatis booleantypehandler 用法

java mybatis booleantypehandler 用法全文共四篇示例,供读者参考第一篇示例:Java是一种广泛应用的编程语言,在开发过程中常常会涉及到数据库操作。

MyBatis是一款优秀的持久层框架,可以帮助开发者在Java应用中轻松地进行数据库操作。

在MyBatis中,BooleanTypeHandler是一种非常常用的类型处理器,用于处理boolean类型的数据。

BooleanTypeHandler的作用是将数据库中的boolean类型数据与Java中的boolean类型数据进行转换。

在数据库中,通常使用1或0来表示true或false。

而在Java中,boolean类型的变量只能取true 或false这两个值。

BooleanTypeHandler在这两者之间起到了桥梁的作用,方便开发者对数据的处理。

使用BooleanTypeHandler的方式很简单,只需要在MyBatis的配置文件中进行相应的配置即可。

在数据库表对应的实体类中,需要将boolean类型的字段定义为Boolean类型,而不是基本数据类型boolean。

然后,在MyBatis的配置文件中,添加如下的配置:```xml<typeHandlers><typeHandlerhandler="org.apache.ibatis.type.BooleanTypeHandler" javaType="ng.Boolean"/></typeHandlers>```@Overrideprotected String convertToJdbcType(Boolean aBoolean) {return aBoolean ? "Y" : "N";}}```然后在MyBatis的配置文件中使用这个自定义的类型处理器:通过这种方式,开发者可以自定义类型处理器来处理不同类型的数据转换,使得数据在数据库与Java代码之间的交互更加灵活。

handler的运行机制

handler的运行机制

handler的运行机制Handler的运行机制Handler是Android开发中非常重要的一个概念,它在Android 中起到了非常重要的作用,它可以帮助我们实现异步操作,以及主线程和子线程之间的通信。

Handler的运行机制分为三个部分:消息队列、消息处理器和消息。

我们来看看消息队列,消息队列是Handler的核心之一,它是用来保存消息的队列。

当我们向Handler发送消息时,它会将消息存放到队列中,然后由Handler按照一定的规则进行处理。

消息队列中的消息是按照优先级排序的,先进先出,后进后出。

接下来,我们来看看消息处理器,消息处理器是用来处理消息的。

当消息队列中有消息时,Handler会调用它的处理函数来处理消息。

消息处理器会根据消息的类型,执行相应的操作。

比如,当我们使用Handler.post()方法发送一个Runnable对象时,消息处理器会将它存储在消息队列中,并在处理时调用它的run()方法。

我们来看看消息,消息是Handler中的最小单位,它是用来传递信息的。

当我们向Handler发送消息时,我们需要创建一个Message对象,并将它传递给Handler。

Message对象中包含了消息的类型以及一些附加信息。

在Handler的处理函数中,我们可以根据消息的类型来执行相应的操作。

在整个Handler的运行过程中,主线程和子线程之间的通信是非常重要的。

当我们在子线程中执行一些操作时,如果需要更新UI,我们就需要使用Handler来实现。

在主线程中创建Handler对象,并将它传递给子线程,子线程就可以通过Handler来向主线程发送消息,从而更新UI。

总的来说,Handler的运行机制是非常复杂的,但是它的作用是非常重要的。

它可以帮助我们实现异步操作,以及主线程和子线程之间的通信。

在实际的开发中,我们需要熟练掌握Handler的使用,以便更好地开发出高质量的Android应用程序。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Ibatis的类型处理器TypeHandler解析Ibatis允许用户像在hibernate中一样定义自己的类型,但是,用户自定义类型需要与数据库中的字段类型进行对应。

它的处理方法是允许我们扩展TypeHandler。

Ibatis框架在处理该数据类型时就会自动调用TypeHandler进行类型转换,非常方便,ibatis中所有的类型都有它自己的TypeHandler,只是一些常用的数据类类型它已经给我们实现了而已。

在配置文件中,我们有两个地方可以配置这种处理器。

第一个地方是sqlMap文件中标签ResultMap或者ParameterMap中的TypeHandler属性,这里配置的handler是局部属性,只会在该ResultMap中才会进行转换。

<resultMap id="UserOrder" class="UserOrderDO" groupBy="id">......<result property="tripType" column="trip_Type"typeHandler="mon.EnumTypeHandlerCallBack"/> ......</resultMap>第二个地方是sqlMapConfig文件中的标签typeHandlers中配置typeHandle子标签,这里配置的标签是全局属性,任何只要匹配该子标签的地方都会自动使用该Handler.<typeHandlers><typeHandlerjdbcType="CLOB" javaType="ng.String"callback="org.springframework.orm.ibatis.support.ClobStringTypeHandle r"/></typeHandlers>例如这里的全局配置,如果此时某个数据库字段的jdbcType是CLOB类型,并且映射的JavaType 类型是字符串类型,那么就会自动调用这里的callback来实行类型转换。

那么Ibatis是如何确定使用哪一个TypeHandler的呢?!它会在自己的局部区域寻找是否在配置文件中配置了Handler,找到了就使用这个handler,如果没有找到,就会查找是否有全局handler,也就是第二种方式配置的handler,这里要注意,可能我们也没有在全局配置文件中配置handler,此时,Ibatis就会根据实际类型配置默认的handler。

我们来看一些关键代码,按照查找步骤,这里我去掉了异常,只看关键的部分。

第一步:从局部Reultmap中取出配置属性。

String propertyName =childAttributes.getProperty("property");String nullValue = childAttributes.getProperty("nullValue"); String jdbcType = childAttributes.getProperty("jdbcType");String javaType = childAttributes.getProperty("javaType");String columnName = childAttributes.getProperty("column");String columnIndex =childAttributes.getProperty("columnIndex");String statementName = childAttributes.getProperty("select"); String resultMapName =childAttributes.getProperty("resultMap");String callback = childAttributes.getProperty("typeHandler"); callback = vars.typeHandlerFactory.resolveAlias(callback);javaType = vars.typeHandlerFactory.resolveAlias(javaType); TypeHandler handler = null;if (callback != null) { // 注意这里,如果配置了就使用这个配置的handler Object impl =Resources.classForName(callback).newInstance();if (implinstanceofTypeHandlerCallback) {handler = new CustomTypeHandler((TypeHandlerCallback) impl);} else if (implinstanceofTypeHandler) {handler = (TypeHandler) impl;} else {throw new NestedRuntimeException ("The class '' is not a valid implementation of TypeHandler or TypeHandlerCallback");}} else {//如果没有配置,就到这里来找handler =resolveTypeHandler(vars.client.getDelegate().getTypeHandlerFactory(), vars.currentResultMap.getResultClass(), propertyName, javaType, jdbcType, true);}第二步,如果局部配置中没有找到,就到下面去找。

publicTypeHandlerresolveTypeHandler(TypeHandlerFactorytypeHandlerFact ory, Class clazz, String propertyName, String javaType, String jdbcType, booleanuseSetterToResolve) {TypeHandler handler = null;if (clazz == null) {// Unknownhandler = typeHandlerFactory.getUnkownTypeHandler();} else if (DomTypeMarker.class.isAssignableFrom(clazz)) {// DOMhandler = typeHandlerFactory.getTypeHandler(String.class, jdbcType); } else if (java.util.Map.class.isAssignableFrom(clazz)) {// Mapif (javaType == null) {handler = typeHandlerFactory.getUnkownTypeHandler(); //BUG 1012591 - typeHandlerFactory.getTypeHandler(ng.Object.class, jdbcType); } else {try {Class javaClass = Resources.classForName(javaType);handler = typeHandlerFactory.getTypeHandler(javaClass, jdbcType);} catch (Exception e) {throw new NestedRuntimeException("Error. Could not set TypeHandler. Cause: " + e, e);}}} else if (typeHandlerFactory.getTypeHandler(clazz, jdbcType) != null) {// Primitivehandler = typeHandlerFactory.getTypeHandler(clazz, jdbcType);} else {// JavaBeanif (javaType == null) {if (useSetterToResolve) {Class type = PROBE.getPropertyTypeForSetter(clazz, propertyName);handler = typeHandlerFactory.getTypeHandler(type, jdbcType);} else {Class type = PROBE.getPropertyTypeForGetter(clazz, propertyName);handler = typeHandlerFactory.getTypeHandler(type, jdbcType);}} else {try {Class javaClass = Resources.classForName(javaType);handler = typeHandlerFactory.getTypeHandler(javaClass, jdbcType);} catch (Exception e) {throw new NestedRuntimeException("Error. Could not set TypeHandler. Cause: " + e, e);}}}return handler;}1.相信大家已经很明白了,其实要找一个Handler,主要就是需要javaType和jdbcType,而这两个参数要么通过反射得到,要么通过配置文件中得到。

因此,为了明确我们一般都在配置文件中进行申明。

2.最后来看一点typeHandlerFactory.getTypeHandler(clazz, jdbcType)是怎么实现的。

publicTypeHandlergetTypeHandler(Class type, String jdbcType) {Map jdbcHandlerMap = (Map) typeHandlerMap.get(type);//首先根据JAVA 类型TypeHandler handler = null;if (jdbcHandlerMap != null) {handler = (TypeHandler) jdbcHandlerMap.get(jdbcType);//每个JDBC 类型if (handler == null) {handler = (TypeHandler) jdbcHandlerMap.get(null);}}return handler;}其实一个Handler=javaType+jdbcType。

相关文档
最新文档