阿图什网站,有道网站收录提交入口,wordpress 插件 发布文章,微信小程序店铺怎么弄建立TypeHandler 我们知道java有java的数据类型#xff0c;数据库有数据库的数据类型#xff0c;那么我们在往数据库中插入数据的时候是如何把java类型当做数据库类型插入数据库#xff0c;在从数据库读取数据的时候又是如何把数据库类型当做java类型来处理呢#xff1f;这…建立TypeHandler 我们知道java有java的数据类型数据库有数据库的数据类型那么我们在往数据库中插入数据的时候是如何把java类型当做数据库类型插入数据库在从数据库读取数据的时候又是如何把数据库类型当做java类型来处理呢这中间必然要经过一个类型转换。在Mybatis中我们可以定义一个叫做TypeHandler类型处理器的东西通过它可以实现Java类型跟数据库类型的相互转换。下面将就如何建立自己的TypeHandler做一个简要介绍。 TypeHandler接口 在Mybatis中要实现自己的TypeHandler就需要实现Mybatis为我们提供的TypeHandler接口。在TypeHandler中定义了四个方法 public interface TypeHandlerT { /** * 用于定义在Mybatis设置参数时该如何把Java类型的参数转换为对应的数据库类型 * param ps 当前的PreparedStatement对象 * param i 当前参数的位置 * param parameter 当前参数的Java对象 * param jdbcType 当前参数的数据库类型 * throws SQLException */ void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException; /** * 用于在Mybatis获取数据结果集时如何把数据库类型转换为对应的Java类型 * param rs 当前的结果集 * param columnName 当前的字段名称 * return 转换后的Java对象 * throws SQLException */ T getResult(ResultSet rs, String columnName) throws SQLException; /** * 用于在Mybatis通过字段位置获取字段数据时把数据库类型转换为对应的Java类型 * param rs 当前的结果集 * param columnIndex 当前字段的位置 * return 转换后的Java对象 * throws SQLException */ T getResult(ResultSet rs, int columnIndex) throws SQLException; /** * 用于Mybatis在调用存储过程后把数据库类型的数据转换为对应的Java类型 * param cs 当前的CallableStatement执行后的CallableStatement * param columnIndex 当前输出参数的位置 * return * throws SQLException */ T getResult(CallableStatement cs, int columnIndex) throws SQLException; } 现在假设我们有一个实体对象User其中有一个属性interests是String数组类型如下所示 public class User { private int id; private String name; private int age; private String[] interests; public int getId() { return id; } public void setId(int id) { this.id id; } public String getName() { return name; } public void setName(String name) { this.name name; } public int getAge() { return age; } public void setAge(int age) { this.age age; } public String[] getInterests() { return interests; } public void setInterests(String[] interests) { this.interests interests; } Override public String toString() { return User [age age , id id , interests Arrays.toString(interests) , name name ]; } } 我们需要把它以拼接字符串的形式存到数据库中然后在取出来的时候又把它还原为一个String数组。这个时候我们就可以给它定义一个TypeHandler专门来处理String数组类型和数据库VARCHAR类型的相互转换。在这里我们建立一个名叫StringArrayTypeHandler的TypeHandler代码如下所示 package com.tiantian.mybatis.handler; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeHandler; public class StringArrayTypeHandler implements TypeHandlerString[] { public String[] getResult(ResultSet rs, String columnName) throws SQLException { String columnValue rs.getString(columnName); return this.getStringArray(columnValue); } public String[] getResult(ResultSet rs, int columnIndex) throws SQLException { String columnValue rs.getString(columnIndex); return this.getStringArray(columnValue); } public String[] getResult(CallableStatement cs, int columnIndex) throws SQLException { // TODO Auto-generated method stub
String columnValue cs.getString(columnIndex); return this.getStringArray(columnValue); } public void setParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType) throws SQLException { if (parameter null) ps.setNull(i, Types.VARCHAR); else { StringBuffer result new StringBuffer(); for (String value : parameter) result.append(value).append(,); result.deleteCharAt(result.length()-1); ps.setString(i, result.toString()); } } private String[] getStringArray(String columnValue) { if (columnValue null) return null; return columnValue.split(,); } } BaseTypeHandler抽象类 在实现自己的TypeHandler时除了上面提到的实现最原始的接口之外Mybatis还为我们提供了一个实现了TypeHandler接口的抽象类BaseTypeHandler。所以我们也可以通过继承BaseTypeHandler来实现自己的TypeHandler。 我们先来看一下BaseTypeHandler类的定义 public abstract class BaseTypeHandlerT extends TypeReferenceT implements TypeHandlerT { protected Configuration configuration; public void setConfiguration(Configuration c) { this.configuration c; } public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException { if (parameter null) { if (jdbcType null) { throw new TypeException(JDBC requires that the JdbcType must be specified for all nullable parameters.); } try { ps.setNull(i, jdbcType.TYPE_CODE); } catch (SQLException e) { throw new TypeException(Error setting null for parameter # i with JdbcType jdbcType . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: e, e); } } else { setNonNullParameter(ps, i, parameter, jdbcType); } } public T getResult(ResultSet rs, String columnName) throws SQLException { T result getNullableResult(rs, columnName); if (rs.wasNull()) { return null; } else { return result; } } public T getResult(ResultSet rs, int columnIndex) throws SQLException { T result getNullableResult(rs, columnIndex); if (rs.wasNull()) { return null; } else { return result; } } public T getResult(CallableStatement cs, int columnIndex) throws SQLException { T result getNullableResult(cs, columnIndex); if (cs.wasNull()) { return null; } else { return result; } } public abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException; public abstract T getNullableResult(ResultSet rs, String columnName) throws SQLException; public abstract T getNullableResult(ResultSet rs, int columnIndex) throws SQLException; public abstract T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException; } 我们可以看到BaseTypeHandler对TypeHandler接口的四个方法做了一个简单的选择把null值的情况都做了一个过滤核心的取值和设值的方法还是抽象出来了供子类来实现。使用BaseTypeHandler还有一个好处是它继承了另外一个叫做TypeReference的抽象类通过TypeReference的getRawType()方法可以获取到当前TypeHandler所使用泛型的原始类型。这对Mybatis在注册TypeHandler的时候是非常有好处的。在没有指定javaType的情况下Mybatis在注册TypeHandler时可以通过它来获取当前TypeHandler所使用泛型的原始类型作为要注册的TypeHandler的javaType类型这个在讲到Mybatis注册TypeHandler的方式时将讲到。 当通过继承BaseTypeHandler来实现自己的TypeHandler时我们的StringArrayTypeHandler应该这样写 public class StringArrayTypeHandler extends BaseTypeHandlerString[] { Override public String[] getNullableResult(ResultSet rs, String columnName) throws SQLException { return getStringArray(rs.getString(columnName)); } Override public String[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return this.getStringArray(rs.getString(columnIndex)); } Override public String[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return this.getStringArray(cs.getString(columnIndex)); } Override public void setNonNullParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType) throws SQLException { //由于BaseTypeHandler中已经把parameter为null的情况做了处理所以这里我们就不用再判断parameter是否为空了直接用就可以了
StringBuffer result new StringBuffer(); for (String value : parameter) result.append(value).append(,); result.deleteCharAt(result.length()-1); ps.setString(i, result.toString()); } private String[] getStringArray(String columnValue) { if (columnValue null) return null; return columnValue.split(,); } } 注册TypeHandler 建立了自己的TypeHandler之后就需要把它注册到Mybatis的配置文件中让Mybatis能够识别并使用它。注册TypeHandler主要有两种方式一种是通过在Mybatis配置文件中定义typeHandlers元素的子元素typeHandler来注册另一种是通过在Mybatis配置文件中定义typeHandlers元素的子元素package来注册。使用typeHandler子元素注册时一次只能注册一个TypeHandler而使用package子元素注册时Mybatis会把指定包里面的所有TypeHandler都注册为TypeHandler。使用typeHandler子元素注册时我们需要通过它的handler属性来指明当前要注册的TypeHandler的全名称这个属性是必须要的。另外还有两个附加属性可以指定一个是javaType用以指定对应的java类型另一个是jdbcType用以指定对应的jdbc类型。使用package子元素注册时需要我们通过它的name属性来指定要扫描的包如果这个时候我们也需要指定对应TypeHandler的javaType和jdbcType的话就需要我们在TypeHandler类上使用注解来定义了。Mybatis注册TypeHandler最基本的方式就是建立一个javaType、jdbcType和TypeHandler的对应关系。在使用typeHandler子元素进行注册的时候有三种类型的注册方式 1.如果我们指定了javaType和jdbcType那么Mybatis会注册一个对应javaType和jdbcType的TypeHandler。 2.如果我们只指定了javaType属性那么这个时候又分两种情况 1如果我们通过注解的形式在TypeHandler类上用MappedJdbcTypes指定了对应的jdbcType那么Mybatis会一一注册指定的javaType、jdbcType和TypeHandler的组合也包括使用这种形式指定了jdbcType为null的情况。现假设我们有如下这样一个StringArrayTypeHandler MappedJdbcTypes({JdbcType.VARCHAR}) public class StringArrayTypeHandler implements TypeHandlerString[] { //..中间的实现代码省略了 //.. } 然后我们在Mybatis的配置文件中这样注册它 typeHandlers typeHandler handlercom.tiantian.mybatis.handler.StringArrayTypeHandler javaType[Ljava.lang.String;/ /typeHandlers 则Mybatis在实际注册的时候是以javaType为String数组jdbcType为VARCHAR来注册StringArrayTypeHandler的。 转载于:https://www.cnblogs.com/Dhouse/p/5977039.html