mybatis 中 ObjectWrapperFactory的使用

本文介绍了MyBatis中ObjectWrapperFactory的使用,包括其接口方法,如何根据XML配置注入自定义工厂,以及如何自定义ObjectWrapperFactory以处理Map中key的下划线问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mybatis 中 ObjectWrapperFactory的使用

ObjectWrapperFactory用于对对象进行包装后处理,在mybatis中用于对结果对象的处理。我们看一下这个接口提供的方法。hasWrapperFor 判断是否满足条件,getWrapperFor 获取ObjectWrapper对象。

public interface ObjectWrapperFactory {

  boolean hasWrapperFor(Object object);

  ObjectWrapper getWrapperFor(MetaObject metaObject, Object object);

}

其实关键的就是使用的ObjectWrapper对对象进行处理,我们看一下mybatis源码是如何匹配上具体的 ObjectWrapperFactory。下面就是获取到具体的ObjectWrapperFactory源码,其实也很简单根据我们在xml中节点配置就可以读取到注入进来了。

  private void objectWrapperFactoryElement(XNode context) throws Exception {
    if (context != null) {
      String type = context.getStringAttribute("type");
      ObjectWrapperFactory factory = (ObjectWrapperFactory) resolveClass(type).newInstance();
      configuration.setObjectWrapperFactory(factory);
    }
  }

在xml中的配置,只需要在mybatis-config.xml中加入标签objectWrapperFactory,下面是我配置的自定义map,key去除下划线的处理。

<objectWrapperFactory type="org.apache.ibatis.dao.mapper.factory.MapWrapperFactory"/>

接下看看如何自定义ObjectWrapperFactory,我们需要实现ObjectWrapperFactory接口,以去除map中key的下划线为例

public class MapWrapperFactory implements ObjectWrapperFactory {
  @Override
  public boolean hasWrapperFor(Object object) {
    return object instanceof Map;
  }

  @Override
  public ObjectWrapper getWrapperFor(MetaObject metaObject, Object object) {
    return new MyMapWrapper(metaObject, (Map<String, Object>)object);
  }
}

在创建MyMapWrapper对象实现ObjectWrapper

package org.apache.ibatis.dao.mapper.wrapper;

import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.wrapper.MapWrapper;

import java.util.Map;

public class MyMapWrapper extends MapWrapper {



  public MyMapWrapper(MetaObject metaObject, Map<String, Object> map) {
    super(metaObject, map);
  }


  @Override
  public String findProperty(String name, boolean useCamelCaseMapping) {
    if (useCamelCaseMapping && ((name.charAt(0) >= 'A' && name.charAt(0) <= 'Z') || name.contains("_"))) {
     return underlineToCamelCase(name);
    }
    return name;
  }
//user_name_log_abc_dd
  private static String underlineToCamelCase(String name) {
    StringBuilder sb = new StringBuilder();
    boolean flag = false;
    for (int i = 0; i < name.length(); i++) {
      if (name.charAt(i) == '_') {
        flag = true;
        continue;
      }else {
        if (flag) {
          sb.append(Character.toUpperCase(name.charAt(i)));
          flag = false;
        }else {
          sb.append(name.charAt(i));
        }
      }
    }
    return sb.toString();
  }

}

接下来我们可以测试一下看看效果,我们先将objectWrapperFactory在xml中去除看看效果,以下是测试代码

    public static void main(String[] args) throws IOException {
        //读取 mybatis-config.xml 文件转成输入流
        Reader resourceAsReader = Resources.getResourceAsReader("org/apache/ibatis/dao/mapper/mybatis-config.xml");

        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsReader);
        SqlSession sqlSession = build.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        Map<String, Object> map = mapper.selectById("1723ad77a1ca06b29a011471036a2dd6");
        System.out.println(map);
    }

没有配置objectWrapperFactory的效果,输出的结果可以看到key是带下划线的

{gender=1, last_login_time=2021-03-23 09:55:33.0, create_time=2020-03-22 23:23:12.0, user_name=test1, pass_word=$2a$10$eus6faJ6/X2hNo5Cm.7bK.Z0oP9UQADthoqRaGTwHEdwehnaMj4Lu, role_uid=d105da79260f4d6a8a03571e4a2b17bc, avatar=,70f5b89fe70a28d95e10c19c96bf2e85, uid=1723ad77a1ca06b29a011471036a2dd6, login_count=47, update_time=2021-03-23 09:55:33.0, last_login_ip=0:0:0:0:0:0:0:1, nick_name=test1, email=1595833114@qq.com, status=false}

配置了以后得结果,下划线已经消失了,可以看出objectWrapperFactory配置已经生效了。

{passWord=$2a$10$eus6faJ6/X2hNo5Cm.7bK.Z0oP9UQADthoqRaGTwHEdwehnaMj4Lu, gender=1, nickName=test1, updateTime=2021-03-23 09:55:33.0, avatar=,70f5b89fe70a28d95e10c19c96bf2e85, roleUid=d105da79260f4d6a8a03571e4a2b17bc, userName=test1, loginCount=47, lastLoginIp=0:0:0:0:0:0:0:1, uid=1723ad77a1ca06b29a011471036a2dd6, lastLoginTime=2021-03-23 09:55:33.0, createTime=2020-03-22 23:23:12.0, email=1595833114@qq.com, status=false}
如果在 MyBatis 中遇到了中文乱码问题,可以尝试以下解决方案: 1. 在 jdbc 链接中添加编码参数 ```xml <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> ``` 2. 在配置文件中添加编码过滤器 ```xml <configuration> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <typeAliases> <package name="com.example.model"/> </typeAliases> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> <plugins> <plugin interceptor="com.example.plugin.MyInterceptor"/> </plugins> <objectFactory type="com.example.factory.MyObjectFactory"/> <objectWrapperFactory type="com.example.factory.MyObjectWrapperFactory"/> <reflectorFactory type="com.example.factory.MyReflectorFactory"/> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="root"/> <property name="filters" value="stat,wall,config"/> <property name="connectionProperties" value="druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000"/> </dataSource> </environment> </environments> <databaseIdProvider type="DB_VENDOR"> <property name="Oracle" value="oracle"/> <property name="MySQL" value="mysql"/> <property name="DB2" value="db2"/> </databaseIdProvider> <typeHandlers> <typeHandler javaType="java.util.Date" jdbcType="DATE" handler="com.example.handler.MyDateTypeHandler"/> </typeHandlers> <objectWrapperFactory type="com.example.factory.MyObjectWrapperFactory"/> <reflectorFactory type="com.example.factory.MyReflectorFactory"/> </configuration> ``` 3. 在 mapper 文件中添加字符集设置 ```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.UserMapper"> <resultMap id="userMap" type="com.example.model.User"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> <result property="gender" column="gender"/> </resultMap> <select id="selectById" resultMap="userMap"> select * from user where id=#{id} </select> <insert id="insert" parameterType="com.example.model.User"> insert into user(id,name,age,gender) values(#{id},#{name},#{age},#{gender}) </insert> </mapper> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

久★伴i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值