spring+mybatis框架中转化驼峰的两种解决方案

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/coder_zyz/article/details/79965826

  项目中因为要用到驼峰,需要将所有的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>

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页