项目中因为要用到驼峰,需要将所有的bean对象和Map转化为驼峰标识,项目里用到一下方式
1.是resultType="java.util.Map"返回值为Map类型的这里采用拦截器,拦截相应的Map返回值,在mybatis-config.xml里添加如下内容:
<plugin interceptor="org.loushang.framework.mybatis.RestlutMapInterceptor">
<!-- 返回类型为Map时,key统一为大写(upper)、小写(lower) -->
<property name="upperOrLower" value="camel" />
</plugin>
其中拦截器RestlutMapInterceptor是这样写的
package org.loushang.framework.mybatis;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.ibatis.executor.resultset.DefaultResultSetHandler;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.executor.statement.BaseStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.inspur.tax.utils.StringUtils;
/**
*
* @ClassName: RestlutMapInterceptor
* @Description: 覆盖loushang-framework中的ResultMap拦截器,目的是添加对驼峰命名法转换的支持
* @author wbw
* @date 2016年8月29日 下午2:32:30
*
*/
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }),
@Signature(method = "handleResultSets", type = ResultSetHandler.class, args = { Statement.class }) })
public class RestlutMapInterceptor implements Interceptor {
private static Logger log = LoggerFactory.getLogger(RestlutMapInterceptor.class);
@SuppressWarnings("unchecked")
public Object intercept(Invocation ivk) throws Throwable {
Object target = ivk.getTarget();
/**
* 获取返回值类型
*/
if (ResultMapUtil.getUpperOrLower() != null && target instanceof RoutingStatementHandler) {
RoutingStatementHandler statementHandler = (RoutingStatementHandler) target;
BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler,
"delegate");
MappedStatement mappedStatement = (MappedStatement) ReflectHelper.getValueByFieldName(delegate,
"mappedStatement");
List<ResultMap> rms = mappedStatement.getResultMaps();
ResultMap rm = rms != null && rms.size() > 0 ? rms.get(0) : null;
String type = rm != null && rm.getType() != null ? rm.getType().getName() : "";
if ("java.util.HashMap".equals(type) || "java.util.Map".equals(type)) {
ResultMapUtil.threadInfo.set(true);
}
}
/**
* 统一Map类型返回值大小写
*/
if (ResultMapUtil.getUpperOrLower() != null && target instanceof DefaultResultSetHandler) {
if (ResultMapUtil.threadInfo.get() != null && (Boolean) ResultMapUtil.threadInfo.get()) {
// 获取到当前的Statement
Statement stmt = (Statement) ivk.getArgs()[0];
// 通过Statement获取到当前的结果集,对其进行处理,并返回对应的处理结果
ResultMapUtil.threadInfo.remove();
return handleResultSet(stmt.getResultSet());
}
}
ResultMapUtil.threadInfo.remove();
return ivk.proceed();
}
/**
* 处理结果集
*
* @param resultSet
* @param mapParam
* @return
*/
private Object handleResultSet(ResultSet resultSet) {
if (resultSet != null) {
List<Object> resultList = new ArrayList<Object>();
try {
ResultSetMetaData rsmd = resultSet.getMetaData();
int columnCount = rsmd.getColumnCount();
// 把每一行对应的Key和Value存放到Map中
while (resultSet.next()) {
// 定义用于存放Key-Value的Map
Map<Object, Object> map = new HashMap<Object, Object>();
// 根据配置属性,将Map的key统一为大写或小写
for (int i = 1; i <= columnCount; i++) {
Object value = resultSet.getObject(rsmd.getColumnName(i));
//lcz 20171013 mybatis 读取number类型,java以BigDecimal类型接收,前台精度丢失,统一转换为String类型
if(value instanceof BigDecimal){
value = ((BigDecimal)value).toPlainString();
}
//lcz 20171023 mybatis 读取oracle.sql.TIMESTAMP类型,转换json时报错,统一转换为String类型
if(value instanceof oracle.sql.TIMESTAMP){
if(value != null){
String formatStr = ResultMapUtil.getFormatStr4OracleSqlTimestamp();
Timestamp timestamp = ((oracle.sql.TIMESTAMP) value).timestampValue();
Date date = new Date(timestamp.getTime());
SimpleDateFormat sd = new SimpleDateFormat(formatStr);
value = sd.format(date);
}
}
if (value != null) {
// 驼峰命名法
if ("camel".equals(ResultMapUtil.getUpperOrLower())) {
map.put(StringUtils.toCamelCase(rsmd.getColumnName(i)), value);
} else if ("upper".equals(ResultMapUtil.getUpperOrLower())) {
map.put(rsmd.getColumnName(i).toUpperCase(), value);
} else {
map.put(rsmd.getColumnName(i).toLowerCase(), value);
}
}
// lcz 20170222 map返回参数值为null时,继续在map中添加该值
else{
map.put(StringUtils.toCamelCase(rsmd.getColumnName(i)), value);
}
}
// 把封装好的Map存放到List中并进行返回
resultList.add(map);
}
} catch (SQLException e) {
log.error("Mybatis返回值Map统一大小处理出错!", e);
e.printStackTrace();
} finally {
closeResultSet(resultSet);
}
return resultList;
}
return null;
}
/**
* 关闭ResultSet
*
* @param resultSet
* 需要关闭的ResultSet
*/
private void closeResultSet(ResultSet resultSet) {
try {
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException e) {
}
}
public Object plugin(Object obj) {
return Plugin.wrap(obj, this);
}
public void setProperties(Properties properties) {
// 是否返回记录总数
ResultMapUtil.setUpperOrLower(null);
if (properties.get("upperOrLower") != null) {
String upperOrLower = (String) properties.get("upperOrLower");
if ("camel".equals(upperOrLower.toLowerCase())) {
ResultMapUtil.setUpperOrLower("camel");
} else if ("upper".equals(upperOrLower.toLowerCase())) {
ResultMapUtil.setUpperOrLower("upper");
} else if ("lower".equals(upperOrLower.toLowerCase())) {
ResultMapUtil.setUpperOrLower("lower");
} else {
log.warn("Mybatis返回值Map统一大小写配置属性{" + upperOrLower + "}为无效值,属性为 upper、lower 或 camel!");
}
}
if (properties.get("oracle.sql.TIMESTAMP.formatStr") != null) {
String formatStr4OracleSqlTimestamp = (String) properties.get("oracle.sql.TIMESTAMP.formatStr");
ResultMapUtil.setFormatStr4OracleSqlTimestamp(formatStr4OracleSqlTimestamp);
}
}
}
通过这种拦截器就能将resultType="java.util.Map"返回值为Map类型的的转化为驼峰标识
2.但是上面一种在resultType返回对象为bean时是不能转化的,例如resultType="org.sjzcgl.util.object.data.TaxZcmlb"
但是我们在mybatis-config.xml使用mapUnderscoreToCamelCase可以使对象转换驼峰,如下。
<settings>
<setting name="jdbcTypeForNull" value="NULL" />
<setting name="callSettersOnNulls" value="true" />
<setting name="logImpl" value="STDOUT_LOGGING" />
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>