为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

Mybatis拦截器解决达梦数据库sql返回类型Mapkey大写问题

2023-06-22 5页 doc 101KB 74阅读

用户头像 个人认证

is_856463

暂无简介

举报
Mybatis拦截器解决达梦数据库sql返回类型Mapkey大写问题     Mybatis拦截器,解决达梦数据库sql返回类型Mapkey大写问题          Mybatis拦截器,解决达梦数据库sql返回类型Mapkey大写问题拦截器功能点代码介绍拦截器入口接收Mybatis处理的结果自己处理查询结果拦截器功能点代码介绍在代码中有一句invocation.proceed();方法,如果执行了这个方法,就是mybatis自己处理查询结果返给我们用。如果不执行该方法,则我们自己可以拿到结果自己映射到返回类型中去拦截器入口importorg.apache.ibatis.executor.r...
Mybatis拦截器解决达梦数据库sql返回类型Mapkey大写问题
     Mybatis拦截器,解决达梦数据库sql返回类型Mapkey大写问          Mybatis拦截器,解决达梦数据库sql返回类型Mapkey大写问题拦截器功能点代码介绍拦截器入口接收Mybatis处理的结果自己处理查询结果拦截器功能点代码介绍在代码中有一句invocation.proceed();方法,如果执行了这个方法,就是mybatis自己处理查询结果返给我们用。如果不执行该方法,则我们自己可以拿到结果自己映射到返回类型中去拦截器入口importorg.apache.ibatis.executor.resultset.DefaultResultSetHandler;importorg.apache.ibatis.executor.resultset.ResultSetHandler;importorg.apache.ibatis.mapping.MappedStatement;importorg.apache.ibatis.mapping.ResultMap;importorg.apache.ibatis.plugin.*;importorg.apache.ibatis.reflection.MetaObject;importorg.apache.ibatis.reflection.SystemMetaObject;importorg.springframework.stereotype.Component;importjava.sql.Statement;importjava.util.List;importjava.util.Map;importjava.util.Properties;/***拦截特定接口的返回值,转成Map*/@Component//拦截Executor类的query方法@Intercepts({@Signature(type=ResultSetHandler.class,method="handleResultSets",args={Statement.class})})publicclassMybatisResultInterceptimplementsInterceptor{publicObjectintercept(Invocationinvocation)throwsThrowable{DefaultResultSetHandlerdefaultResultSetHandler=(DefaultResultSetHandler)invocation.getTarget();MetaObjectmetaStatementHandler=SystemMetaObject.forObject(defaultResultSetHandler);MappedStatementmappedStatement=(MappedStatement)metaStatementHandler.getValue("mappedStatement");//获取节点属性的集合ListresultMaps=mappedStatement.getResultMaps();//上面一堆代码主要是为了获取sql的映射类型ClassresultType=resultMaps.get(0).getType();//InterceptorFlagInterface这个是我自己定义的一个标记接口,这句代码意思是,如果sql的结果映射类型为map或者实体实现了InterceptorFlagInterface接口的都会走这个if语句if(Map.class.isAssignableFrom(resultType)||InterceptorFlagInterface.class.isAssignableFrom(resultType)){//处理sql返回值是Map类型的returnMapIntercept.interceptMap(invocation);}else{returnEntityIntercept.intercept(invocation);}}publicObjectplugin(Objecttarget){returnPlugin.wrap(target,this);}publicvoidsetProperties(Propertiesarg0){}}接收Mybatis处理的结果这种是接收框架拼接的结果,处理达梦数据库Mapkey大写问题这个类是拦截器类,里面有2中业务处理方法,是我自己的业务importcom.alibaba.druid.pool.DruidPooledResultSet;importcom.alibaba.druid.pool.DruidPooledStatement;importcom.alibaba.druid.proxy.jdbc.NClobProxyImpl;importcom.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl;importcom.alibaba.fastjson.JSONObject;importdm.jdbc.desc.Column;importdm.jdbc.driver.DmdbNClob;importdm.jdbc.driver.DmdbPreparedStatement;importorg.apache.ibatis.plugin.Invocation;importjava.sql.PreparedStatement;importjava.sql.SQLException;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;/***拦截特定接口的返回值,转成Map*/publicclassMapIntercept{/***处理拦截map**@paraminvocation*@return*@throwsThrowable*/publicstaticObjectinterceptMap(Invocationinvocation)throwsThrowable{//执行请求方法,框架所得结果保存到result中Objectresult=invocation.proceed();if(result!=null&&resultinstanceofArrayList){ArrayListresultList=(ArrayList)result;//当前返回值的实体类是实现了InterceptorFlagInterface的才会做转换if(resultList.size()!=0&&resultList.get(0)instanceofInterceptorFlagInterface){//这个方法不用看,是处理Mapkey大写的备用Listres=newArrayList<>();for(inti=0;icolumnsToMap=columnsToMap(columns);Listres=newArrayList<>();for(inti=0;ioldMap=(Map)resultList.get(i);MapnewMap=newHashMap<>(oldMap.size());for(Map.Entryentry:oldMap.entrySet()){Objectvalue=entry.getValue();//如果数据库类型为clob或blob,sql映射类型为map,需要单独处理if(valueinstanceofNClobProxyImpl){NClobProxyImplnClobProxy=(NClobProxyImpl)value;DmdbNClobrawClob=(DmdbNClob)nClobProxy.getRawClob();value=rawClob.data;}/*elseif(valueinstanceofDmdbBlob){//处理blob,当前代码实验未成功DmdbBlobdmdbBlob=(DmdbBlob)value;try{byte[]data=dmdbBlob.data;byte[]bytes="blob".getBytes();value=newString(dmdbBlob.data,"UTF-8");value=bytes2HexString(data);}catch(UnsupportedEncodingExceptione){e.printStackTrace();}}*/if(columnsToMap.get(entry.getKey())==null){newMap.put(entry.getKey(),value);}else{//将大写key变为我们正确的列名newMap.put(columnsToMap.get(entry.getKey()),value);}}res.add(newMap);}returnres;}/***当sql的返回值是Map类型时,需要将大写的key转成小写的key**@paramcolumns*@return*/publicstaticMapcolumnsToMap(Column[]columns){if(columns==null||columns.length==0){thrownewRuntimeException("Mybatis拦截器未获取到原SQL中的列名");}//这个map:当sql的返回值是Map类型时,需要将大写的key转成小写的keyMapcolumnsToMap1=newHashMap<>(8);for(Columncolumn:columns){Stringname=column.name;//LABEL是个特殊字,会默认大写,就算在sql中用的是小写if("LABEL".equals(name)){columnsToMap1.put(name.toUpperCase(),"label");}else{columnsToMap1.put(name.toUpperCase(),column.name);}}returncolumnsToMap1;}/***获取sql中查询结果中的列名**@paraminvocation*@return*/publicstaticColumn[]getColumns(Invocationinvocation)throwsSQLException{PreparedStatementstatement=(PreparedStatement)invocation.getArgs()[0];DruidPooledResultSetgeneratedKeys=(DruidPooledResultSet)statement.getGeneratedKeys();DruidPooledStatementpoolableStatement=generatedKeys.getPoolableStatement();PreparedStatementProxyImplstatement1=(PreparedStatementProxyImpl)poolableStatement.getStatement();DmdbPreparedStatementrawObject=(DmdbPreparedStatement)statement1.getRawObject();returnrawObject.columns;}}自己处理查询结果这种是自己处理结果,不让框架去处理了importcom.alibaba.fastjson.JSON;importorg.apache.ibatis.executor.resultset.DefaultResultSetHandler;importorg.apache.ibatis.mapping.MappedStatement;importorg.apache.ibatis.mapping.ResultMap;importorg.apache.ibatis.mapping.ResultMapping;importorg.apache.ibatis.plugin.Invocation;importorg.apache.ibatis.reflection.MetaObject;importorg.apache.ibatis.reflection.SystemMetaObject;importorg.springframework.stereotype.Component;importjava.sql.ResultSet;importjava.sql.ResultSetMetaData;importjava.sql.Statement;importjava.time.LocalDate;importjava.time.LocalDateTime;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;publicclassEntityIntercept{publicstaticObjectintercept(Invocationinvocation)throwsThrowable{ListresList=newArrayList();DefaultResultSetHandlerdefaultResultSetHandler=(DefaultResultSetHandler)invocation.getTarget();MetaObjectmetaStatementHandler=SystemMetaObject.forObject(defaultResultSetHandler);MappedStatementmappedStatement=(MappedStatement)metaStatementHandler.getValue("mappedStatement");//获取节点属性的集合ListresultMaps=mappedStatement.getResultMaps();ClassresultType=resultMaps.get(0).getType();if(resultType==String.class||resultType==int.class){//如果走这里,就会执行框架的invocation.proceed();方法处理返回结果}else{//之前遇到Mybatis框架无法映射类型LocalDateTime,所以才有这个拦截器的存在,LocalDateTime具体解决方法看另外一篇//判断当前实体是否需要做LocalDateTime的转换if(!isLocalDate(resultMaps)){returninvocation.proceed();}//处理返回的实体中有LocalDateTime的MapcolumnsAndFieldMap=columnsAndFieldMap(resultMaps);//获取mybatis返回的实体类类型名intresultMapCount=resultMaps.size();if(resultMapCount>0){Statementstatement=(Statement)invocation.getArgs()[0];ResultSetresultSet=statement.getResultSet();if(resultSet!=null){//获得对应列名ResultSetMetaDatarsmd=resultSet.getMetaData();ListcolumnList=newArrayList<>();for(inti=1;i<=rsmd.getColumnCount();i++){//这里是拿到所有的列名,在达梦中应该都是大写的//通过这些列名再去拿当前列的查询结果columnList.add(rsmd.getColumnName(i));}while(resultSet.next()){MapresultMap=newHashMap<>();for(StringcolName:columnList){//通过这些列名再去拿当前列的查询结果,resultSet.getString(colName)resultMap.put(columnsAndFieldMap.get(colName),resultSet.getString(colName));}//最后将我们的结果转成一个实体类resultTyperesList.add(JSON.parseObject(JSON.toJSONString(resultMap),resultType));}returnresList;}}}returninvocation.proceed();}/***当sql返回值类型是实体类时,判断字段中是否有LocalDateTime**@paramresultMaps*@return*/publicstaticBooleanisLocalDate(ListresultMaps){//ResultMap中sql列和实体类字段的映射MapcolumnsToMap1=newHashMap<>(8);ResultMapresultMap1=resultMaps.get(0);ListresultMappings=resultMap1.getResultMappings();for(ResultMappingresultMapping:resultMappings){ClassjavaType=resultMapping.getJavaType();if(javaType==LocalDateTime.class||javaType==LocalDate.class){returntrue;}}returnfalse;}/***当sql返回值类型是实体类时,获取到自定的ResultMap中sql列和实体类字段的映射**@paramresultMaps*@return*/publicstaticMapcolumnsAndFieldMap(ListresultMaps){//ResultMap中sql列和实体类字段的映射MapcolumnsToMap1=newHashMap<>(8);ResultMapresultMap1=resultMaps.get(0);ListresultMappings=resultMap1.getResultMappings();for(ResultMappingresultMapping:resultMappings){if(resultMapping.getJavaType()!=List.class){columnsToMap1.put(resultMapping.getColumn().toUpperCase(),resultMapping.getProperty());}}returncolumnsToMap1;}} -全文完-
/
本文档为【Mybatis拦截器解决达梦数据库sql返回类型Mapkey大写问题】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索