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

原创 2018年04月16日 20:29:10

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

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

OpenGL实现RGB到YUV的转化

采用OpenGLES2.0规范,在GPU硬件上实现高效率的RGB数据到YUV数据的转化
  • 2017年02月09日 22:27

Mybatis开启数据库字段自动映射为驼峰命名

​ 遇到查询数据库表中的数据,其它字段都有内容,只有其中一个字段内容为null。mysql中该字段的命名为head_url,后来查明原因是需要在Mybatis开启数据库字段自动映射为驼峰命名。在m...
  • napoay
  • napoay
  • 2017-11-07 15:24:07
  • 831

java 驼峰转换

将"_"转换成驼峰,将驼峰转换成"_"。 import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 驼峰转换 ...
  • hzw2312
  • hzw2312
  • 2017-01-19 16:53:22
  • 1764

Spring+MyBatis框架中sql语句的书写,数据集的传递以及多表关联查询

在很多Java EE项目中,Spring+MyBatis框架经常被用到,项目搭建在这里不再赘述,现在要将的是如何在项目中书写,增删改查的语句,如何操作数据库,以及后台如何获取数据,如何进行关联查询,以...
  • li398349797
  • li398349797
  • 2016-10-30 22:41:57
  • 263

中划线命名转化驼峰命名

var rmsPrefix=/^-/, rdasAlpha=/-([\da-z])/gi; function camelCase(string){ return ...
  • cheng198938
  • cheng198938
  • 2016-03-21 13:32:41
  • 240

驼峰和下划线命令转换

import java.util.regex.Matcher; import java.util.regex.Pattern; public class Camel_UnderlineConver...
  • nwsuafer
  • nwsuafer
  • 2014-01-17 15:21:23
  • 998

驼峰命名法(CamelCase)和下划线命名法(UnderScoreCase)之间的转换

前言:         在我们项目中前端传来的参数多是首字母小写,如果是两个词,第二个此首字母大写,如userName。类似于我们后端的驼峰命名。 但是如果我们用的原生sql,我们需要把驼...
  • wabiaozia
  • wabiaozia
  • 2017-10-26 15:53:44
  • 572

Spring+Mybatis框架 ModelAndView

  • 2013年11月11日 09:24
  • 22.96MB
  • 下载

java,下划线与驼峰命名转换

public static class Tool{ private static Pattern linePattern = Pattern.compile("_(\\w)"); ...
  • fly_down
  • fly_down
  • 2015-06-12 15:10:26
  • 11001

JS字符串转成驼峰的三种方法

问题描述:写一个字符串转成驼峰的方法,例:border-bottom-color->borderBottomColor方法一:操作字符串数组function tranformStr1(str){ ...
  • SuperluminalSnails
  • SuperluminalSnails
  • 2016-10-02 13:46:01
  • 4641
收藏助手
不良信息举报
您举报文章:spring+mybatis框架中转化驼峰的两种解决方案
举报原因:
原因补充:

(最多只允许输入30个字)