Mybatis之插件开发之下划线转驼峰形式插件
程序员文章站
2022-05-31 23:08:28
...
背景:有些人在使用Mybatis时,为了方便扩展而使用Map类型的返回值。使用Map作为返回值时,Map中的键值就是查询结果中的列名,而列名一般都是大小写字母或者下划线形式,因此和Java使用的驼峰形式不一致,而且由于不同数据库查询出来的大小写也不一致,因此为了保证在使用Map是属性一致,可以对Map类型结果进行特殊处理,即不同格式的列名转换为Java的驼峰形式命名。这种情况下我们可以使用拦截器,通过拦截ResultSetHander接口中的handleResultSets方法去处理Map类型的结果,拦截器代码如下:
1,拦截器类CameHumpInterceptor.class
package person.david.ssm.interceptor;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import java.sql.Statement;
import java.util.*;
/**
* @author David
* @className CameHumpInterceptor
* Mybatis Map 类型下划线key转小写驼峰形式
* @date 2020/2/13 20:40
*/
@Intercepts(
@Signature(
type = ResultSetHandler.class,
method = "handleResultSets",
args = {Statement.class})
)
@SuppressWarnings({"unchecked","rawtypes"})
public class CameHumpInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("==================>开始进行拦截...");
List<Object> list = (List<Object>)invocation.proceed();
for (Object object : list) {
//如果结果是Map类型,就对Map的key进行转换
if (object instanceof Map){
processMap((Map) object);
}else {
break;
}
}
return list;
}
/**
* 处理map类型
*
* @param map
*/
private void processMap(Map<String,Object> map){
System.out.println("==================>开始处理map类型...");
Set<String> keySet = new HashSet<>(map.keySet());
for (String key : keySet) {
//以大写开头的字母为小写,如果包含下划线也会处理为驼峰
//此处只通过简单的两个标识来判断
if ((key.charAt(0) >= 'A' && key.charAt(0) <= 'Z') || key.indexOf("_") >= 0 ){
Object value = map.get(key);
map.remove(key);
map.put(underlineToCamehunp(key),value);
}
}
}
/**
* 将下划线风格转换为驼峰风格
* @param inputString
* @return
*/
public static String underlineToCamehunp(String inputString){
System.out.println("==================>开始进行转换...");
StringBuilder sb = new StringBuilder();
boolean nextUppercase = false;
for (int i = 0; i < inputString.length(); i++) {
char c = inputString.charAt(i);
if (c == '_') {
if (sb.length()>0) {
nextUppercase = true;
}
}else {
if (nextUppercase) {
sb.append(Character.toUpperCase(c));
nextUppercase = false;
}else {
sb.append(Character.toLowerCase(c));
}
}
}
return sb.toString();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target,this);
}
@Override
public void setProperties(Properties properties) {
}
}
2,接口TestMapper.class
@CacheNamespace(eviction = FifoCache.class,flushInterval = 60000,size = 512,readWrite = true)
public interface TestMapper {
Map<Object,Object> selectStuById(int id);
}
3,TestMapper.xml文件
<select id="selectStuById" parameterType="int" resultType="map">
select stu_name, stu_age, stu_gender, stu_hobby
from t_test
where id = #{id}
</select>
4,配置文件里配置写好的拦截器插件
<!--配置下划线风格转换驼峰风格的拦截器插件-->
<plugins>
<plugin interceptor="person.david.ssm.interceptor.CameHumpInterceptor"/>
</plugins>
5,测试类测试下划线转驼峰
@Test
public void test7(){
SqlSession sqlSession = sqlSessionFactory.openSession();
TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
Map<Object ,Object> map = testMapper.selectStuById(4);
for (Map.Entry<Object, Object> entry : map.entrySet()) {
System.out.println(entry.getKey()+"=========>"+entry.getValue());
}
}