当我要插入一条数据,某个数据是数组类型,数据库中却是VARCHAR类型,这个时候可能会傻乎乎的先把这个数据自己手动转换成String类型再插入到数据库中,同时取出来的时候也要做相反的转换,其实大可不必。MyBatis为我们提供了更好的方法即是TypeHandler来应对Java和jdbc字段类型不匹配的情况。MyBatis中内置了不少的TypeHandler,如果我们想要自己自定义一个TypeHandler可以实现TypeHandler接口,也可以继承BaseTypeHandler类。
下面我们定义一个将逗号分隔的字符串和数组对象之间的进行类型转换的抽象类,并实现了Integer,Long,Double,Float,Charater,Boolean几个常用的数组直接的转换。
package org.jstudioframework.mybatis.type;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.lang.reflect.Array;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 将逗号分隔的字符串和数组对象之间的进行类型转换的抽象类
*/
public abstract class StringTokenizerTypeHandler<T> extends BaseTypeHandler<T[]> {
private Class<T> clazz;
public StringTokenizerTypeHandler(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T[] ts, JdbcType jdbcType) throws SQLException {
StringBuffer result = new StringBuffer();
for (T value : ts) {
result.append(value).append(",");
}
result.deleteCharAt(result.length() - 1);
ps.setString(i, result.toString());
}
@Override
public T[] getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
return toArray(resultSet.getString(columnName));
}
@Override
public T[] getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
return toArray(resultSet.getString(columnIndex));
}
@Override
public T[] getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
return toArray(callableStatement.getString(columnIndex));
}
T[] toArray(String columnValue) {
if (columnValue == null) {
return createArray(0);
}
String[] values = columnValue.split(",");
T[] array = createArray(values.length);
for (int i = 0; i < values.length; i++) {
array[i] = parseString(values[i]);
}
return array;
}
T[] createArray(int size) {
return (T[]) Array.newInstance(clazz, size);
}
abstract T parseString(String value);
}
//------------------------一些常用实现类-------------------------//
public class INTEGER extends StringTokenizerTypeHandler<Integer> {
public INTEGER() {
super(Integer.class);
}
@Override
Integer parseString(String value) {
return Integer.parseInt(value);
}
}
public class LONG extends StringTokenizerTypeHandler<Long> {
public LONG() {
super(Long.class);
}
@Override
Long parseString(String value) {
return Long.parseLong(value);
}
}
public class DOUBLE extends StringTokenizerTypeHandler<Double> {
public DOUBLE() {
super(Double.class);
}
@Override
Double parseString(String value) {
return Double.parseDouble(value);
}
}
public class FLOAT extends StringTokenizerTypeHandler<Float> {
public FLOAT() {
super(Float.class);
}
@Override
Float parseString(String value) {
return Float.parseFloat(value);
}
}
public class STRING extends StringTokenizerTypeHandler<String> {
public STRING() {
super(String.class);
}
@Override
String parseString(String value) {
return value;
}
}
public class CHAR extends StringTokenizerTypeHandler<Character> {
public CHAR() {
super(Character.class);
}
@Override
Character parseString(String value) {
return value.charAt(0);
}
}
public class BOOLEAN extends StringTokenizerTypeHandler<Boolean> {
public BOOLEAN() {
super(Boolean.class);
}
@Override
Boolean parseString(String value) {
return Boolean.parseBoolean(value);
}
}