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}