mybatis TypeHandler注入spring的依赖方式
TypeHandler注入spring的依赖
解决方法
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- .... --> <property name="typeHandlers"> <array> <bean class="com.example.YurCustomTypeHandler"> <property name="property" ref="bean"/> </bean> </array> </property> </bean>
在mybatis想通过写一个自定义的handler实现业务功能,该handler默认创建的时候,是不在spring的管理范围里的,所以你在handler用@Autowired注入,是会报npe。
需要通过上面的方式,就可以解决了。
mybatis扩展:自定义TypeHandler
在Mybatis中定义了很多默认的类型处理器,将sql语句中的值转化成JDBC的类型,以及将结果集中的值转化为字段类型的值,详情可见官网默认的TypeHandler,但是有的时候我们并不想用官网的TypeHandler的时候,自定义的TypeHandler就派上用场了
1、编写自定义TypeHandler
在自定义的类上加上@MappedJdbcTypes(JdbcType.VARCHAR)注解,括号里的JdbcType.Varchar是需要替代的
默认的JDBC类型,然后让这个类继承BaseHandler<String>,泛型类型String说明替代String类型,然后再重写的方法中
对只进行处理就行了,每个方法都必须返回值,如果没有返回的话,默认是不返回任何东西的,导致的结果就是,插入的值为null,获得的值也全部为null
package javaDIYFree.typeHandler; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedJdbcTypes; import sun.security.provider.MD5; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * @author Hearts * @date 2019/4/17 * @desc */ @MappedJdbcTypes(JdbcType.VARCHAR)//需要替代的默认的JDBC类型,泛型类型String说明替代String类型 public class VarcharTypeHandler extends BaseTypeHandler<String> { /** * 对设置的值进行处理 * @param preparedStatement * @param i * @param s * @param jdbcType * @throws SQLException */ @Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, String s, JdbcType jdbcType) throws SQLException { //我在传进来的字符串后面加了一串字符串 preparedStatement.setString(i,s+">>>>>>>>>>>>>>>>"); } /** * 对获取值的操作进行扩展,列名方式 * @param resultSet * @param s * @return * @throws SQLException */ @Override public String getNullableResult(ResultSet resultSet, String s) throws SQLException { return resultSet.getString(s); } /** * 对获取值的操作进行扩展,索引方式 * @param resultSet * @param i * @return * @throws SQLException */ @Override public String getNullableResult(ResultSet resultSet, int i) throws SQLException { return resultSet.getString(i); } /** * 对其他获取值的操作进行扩展 * @param callableStatement * @param i * @return * @throws SQLException */ @Override public String getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return callableStatement.getString(i); } }
2、配置TypeHandler
有两种方式配置,一种就是直接,再配置SqlSessionFactoryBean的时候,将自定义的TypeHandler配置进去,但是这种方式不常用,应为这就代表所有的Varchar的操作都是用自定义的TypeHandler了,一般我们只需要在某一个表的某一个字段进行自定义,这个时候就用第二种方式配置了
第一种配置方式
@Bean public SqlSessionFactoryBean createSqlSessionFactoryBean(DruidDataSource druidDataSource){ final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); try{ //配置数据源 sqlSessionFactoryBean.setDataSource(druidDataSource); //配置mapper文件所在的位置 sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")); //配置自定义TypeHandler sqlSessionFactoryBean.setTypeHandlers(new TypeHandler[]{new VarcharTypeHandler()}); } catch (IOException e) { e.printStackTrace(); } return sqlSessionFactoryBean; }
在需要使用的操作和字段中添加typeHandler
<insert id="insert" parameterType="javaDIYFree.model.User"> insert into user (id, create_date, `name`, did, `password`, username ) values (#{id,jdbcType=BIGINT}, #{createDate,jdbcType=TIMESTAMP}, #{name,jdbcType=VARCHAR}, #{did,jdbcType=BIGINT}, #{password,jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR,typeHandler=varcharTypeHandler} ) <!--在插入操作内,对username字段进行处理--> </insert>
3、测试
package javaDIYFree.dao; import javaDIYFree.config.MybatisConfig; import javaDIYFree.model.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.function.Consumer; /** * @author Hearts * @date 2019/4/17 * @desc */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = MybatisConfig.class) public class UserMapperTest { @Autowired private UserMapper userMapper; @Test /** * 测试insert方法 */ public void insertUser(){ User user = new User(); user.setUsername("zhangsan"); user.setPassword("123456"); userMapper.insert(user); } @Test /** * 测试selectAll方法 */ public void selectAllUser(){ userMapper.selectAll().forEach(new Consumer<User>() { public void accept(User i) { //打印用户名和密码 System.out.println(i.getUsername() +" ======> "+i.getPassword()); } }); } }
4、项目结构图
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
关于SpringCloud中Ribbon的7种负载均衡策略解析
这篇文章主要介绍了关于SpringCloud中Ribbon的7种负载均衡策略解析,服务端负载均衡器的问题是,它提供了更强的流量控制权,但无法满足不同的消费者希望使用不同负载均衡策略的需求,而使用不同负载均衡策略的场景确实是存在的,需要的朋友可以参考下2023-07-07Java C++ leetcode执行一次字符串交换能否使两个字符串相等
这篇文章主要为大家介绍了Java C++ leetcode1790执行一次字符串交换能否使两个字符串相等,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2022-10-10
最新评论