spring+mybatis中typehandler怎么配置
来源:互联网 发布:steam汽车模拟软件 编辑:程序博客网 时间:2024/06/14 06:47
我们在不使用spring来管理的时候通常把typehandler的配置放到mybatis-config.xml中,如下:
<configuration> <typeHandlers> <!-- 当配置package的时候,mybatis会去配置的package扫描TypeHandler <package name="com.dy.demo"/> --> <!-- handler属性直接配置我们要指定的TypeHandler --> <typeHandler handler=""/> <!-- javaType 配置java类型,例如String, 如果配上javaType, 那么指定的typeHandler就只作用于指定的类型 --> <typeHandler javaType="" handler=""/> <!-- jdbcType 配置数据库基本数据类型,例如varchar, 如果配上jdbcType, 那么指定的typeHandler就只作用于指定的类型 --> <typeHandler jdbcType="" handler=""/> <!-- 也可两者都配置 --> <typeHandler javaType="" jdbcType="" handler=""/> </typeHandlers> ......</configuration>
但是对于我们现在的开发环境来说,spring太流行了,所以这里就成了一块问题。
闲话不多说,直接上spring的配置:
<!--声明TypeHandler bean--> <bean id="myStringTypeHandler" class="util.MyStringTypeHandler"/> <!-- 创建spring工厂 --> <bean id="ssf" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--data source的配置不变--> <property name="dataSource" ref="ds"/> <!--实体类别名--> <property name="typeAliasesPackage" value="model"/> <!--mapper文件注入--> <property name="mapperLocations" value="classpath:/mybatis-mapper/*/*DaoImpl.xml"/> <!--typeHandler注入--> <property name="typeHandlers" ref="myStringTypeHandler"/> </bean>
下面简单的介绍下typehandler的配置吧。
首先是官方对于这个属性的介绍:
以下是mybatis中转化string的源码:
package org.apache.ibatis.type;import java.sql.CallableStatement;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;public class StringTypeHandler extends BaseTypeHandler<String> { public StringTypeHandler() { } public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter); } public String getNullableResult(ResultSet rs, String columnName) throws SQLException { return rs.getString(columnName); } public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return rs.getString(columnIndex); } public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return cs.getString(columnIndex); }}
BaseTypeHandler源码:
package org.apache.ibatis.type;import java.sql.CallableStatement;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import org.apache.ibatis.session.Configuration;public abstract class BaseTypeHandler<T> extends TypeReference<T> implements TypeHandler<T> { protected Configuration configuration; public BaseTypeHandler() { } 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 var6) { 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: " + var6, var6); } } else { this.setNonNullParameter(ps, i, parameter, jdbcType); } } public T getResult(ResultSet rs, String columnName) throws SQLException { T result = this.getNullableResult(rs, columnName); return rs.wasNull()?null:result; } public T getResult(ResultSet rs, int columnIndex) throws SQLException { T result = this.getNullableResult(rs, columnIndex); return rs.wasNull()?null:result; } public T getResult(CallableStatement cs, int columnIndex) throws SQLException { T result = this.getNullableResult(cs, columnIndex); return cs.wasNull()?null:result; } public abstract void setNonNullParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException; public abstract T getNullableResult(ResultSet var1, String var2) throws SQLException; public abstract T getNullableResult(ResultSet var1, int var2) throws SQLException; public abstract T getNullableResult(CallableStatement var1, int var2) throws SQLException;}
经过查看我们发现只需要实现BaseTypeHandler这个抽象类即可,记得泛型一定是String。
以下是我自己的代码,其中oracle数据库编码为ISO-8859-1,项目编码为GBK:
package util;import org.apache.ibatis.type.BaseTypeHandler;import org.apache.ibatis.type.JdbcType;import org.apache.log4j.Logger;import java.io.UnsupportedEncodingException;import java.sql.CallableStatement;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;/** * 转化String的result与parameter * 注意:实现BaseTypeHandler时,泛型必须为String */public class MyStringTypeHandler extends BaseTypeHandler<String> { private static final Logger log = Logger.getLogger(MyStringTypeHandler.class); /** * 转化字符串编码 * @param str * @param oldCharset * @param newCharset * @return */ private static String convertEncoding(String str,String oldCharset,String newCharset){ String resultStr = null; try{ if (str == null) { return resultStr; } resultStr = new String(str.getBytes(oldCharset),newCharset); }catch(UnsupportedEncodingException e){ log.error(e.getMessage(),e); } return resultStr; } public MyStringTypeHandler() { } @Override public void setNonNullParameter(PreparedStatement ps, int index, String parameter, JdbcType jdbcType) throws SQLException { parameter = convertEncoding(parameter, "GBK","ISO-8859-1"); ps.setString(index,parameter); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { return convertEncoding(rs.getString(columnName),"ISO-8859-1","GBK"); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return convertEncoding(rs.getString(columnIndex),"ISO-8859-1","GBK"); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return convertEncoding(cs.getString(columnIndex),"ISO-8859-1","GBK"); }}
补充:以上可以解决正常的需求,但是大多码农都是不正常的,最近又遇到一个问题,也在这里加上。
当我们插入数据的时候,有些数据是可以为空的,MyBatis支持我们这样写:
<!--一个简单的插入语句--><insert id="insertUser"> insert into user (id,username,password,address) values (#{id}, #{username} #{password}, #{address,jdbcType=VARCHAR}) </insert>
这就会产生问题了,在我们加上了jdbcType=xxx这个配置后,MyBatis不再访问我们的TypeHandler,之后经过百度,发现可以使用如下几种方式解决:
<!--配置resultMap--><resultMap id="userResultMap" type="User"> <result typeHandler="StringTypeHandler" column="address" javaType="java.lang.String" jdbcType="VARCHAR" property="address"/> </resultMap><!--调用--><select id="getUser" resultMap="userResultMap"> select * from user</select><!--这个方法的缺点在于配置比较繁琐,返回时配置resultMap,插入时配置parameterMap,还要设置每个对象的每一个属性-->
<!--这个方法简洁了很多,但是你想想我们有一个20多个字段的表,好吧,画面太美不敢想--><insert id="insertUser" parameterType="User"> INSERT INTO user(username,password,address) VALUES (#{username},#{password},#{address,javaType=String,jdbcType=VARCHAR,typeHandler=StringTypeHandler(这里注意要写类全名的)}) </insert>
我推荐下面这个方法,经过注解配置,数据库类型为xxx的,java类型为xxx的,都会经过这个转换类,果然注解才是好东西哇~
另外,你注意到注解中的值被用大括号括起来了么,这说明注解值可以是一个数组,就像我们这个字符转码类,
还能这样:@MapperJdbcTypes({JdbcType.VARCHAR,JdbcType.CHAR})
和这样:@MappedTypes({String.class,Character.class})
当然,我只是举个栗子,还是要看需求的
import org.apache.ibatis.type.MappedJdbcTypes;import org.apache.ibatis.type.MappedTypes;//这个注解定义的是JdbcType类型,这里的类型不可自己随意定义,必须要是枚举类org.apache.ibatis.type.JdbcType所枚举的数据类型@MappedJdbcTypes({JdbcType.VARCHAR})//这里定义的是JavaType的数据类型,描述了哪些Java类型可被拦截@MappedTypes({String.class})public class StringTypeHandler extends BaseTypeHandler<String> {...}
学习知识要晓出处,以上的配置jdbcType方法学习自http://blog.csdn.net/u012702547/article/details/54572679
如果有不对的地方,还请大神在下面评论区指导。当然,如果这些代码有什么疑问,也可以在下方留言。
- spring+mybatis中typehandler怎么配置
- Mybatis中typeHandler的使用
- mybatis的配置元素--typeHandler类型处理器
- mybatis typeHandler
- Mybatis TypeHandler
- mybatis typeHandler
- MyBatis TypeHandler
- 关于mybatis中typeHandler的两个案例
- 关于mybatis中typeHandler的两个案例
- 关于mybatis的typehandler类的创建以及配置
- Mybatis源码学习笔记(五)配置简介之TypeHandler
- spring boot中mybatis配置
- Mybatis 示例之 TypeHandler
- Mybatis自定义typehandler
- MyBatis-自定义typeHandler
- MyBatis之typeHandler
- Mybatis 自定义 TypeHandler
- Mybatis自定义TypeHandler
- 二进制位串排列
- python 常见错误
- C++作业5—数组选择、字符串
- 类的生命周期
- Mybatis指定日志输出实现
- spring+mybatis中typehandler怎么配置
- SploitFun Linux x86 Exploit 开发系列教程
- Deep learning on Android
- Oracle—自定义function语法(转载)
- 一、wh32开发板应用>>led程序
- r-cnn+caffe-0.999 编译过程中部分问题解决
- 设计模式之单例模式
- qt 之 qsettings
- 复选框的全选和全不选 以及 复选框动态拼接 提交 复选框结果