分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
最近两天项目需求研究了一下mybatis拦截器。对于Mybatis拦截器发现其功能强大,虽很灵活但是其内部对象转换太麻烦很多接口没有完全暴露出来。甚至不得不通过反射的方式去取其内部关联对象。可能Mybatis也不希望用户直接对其内部Statement,以及ResultSetHandler等进行操作。那这样与直接JDBC又有何区别呢?
通用查询其实也并非完全通用。只能是稍微的简化一下代码,减少程序员一些重复的工作罢了。本项目采用springMVC + Mybatis + EasyUi 进行构建。设想一种应用场景。我一个统计查询:统计四张表里不同数据,或者多表关联查询:从A表当中查询三个字段,从B表当中查询二个字段,从C表当中查询一个字段,从D表当中查询两个字段。这种场景对于Mybaits来说。几张表的关联查询比较头痛。两种方式,一种是建立实体对象(VO)多表关联查询然后建立映射。返回其VO实体类。另一种方式通过对象关联的方式,Mapper.xml里进行配置。两种方式在此不作讨论。(PS:如有高手有更好的方式解决这种场景请不吝赐教)
本文主要讨论通过Mybatis拦截器实现直接取其 ResultSet 通过约定的SQL语句格式解析后生成数据格式。或者直接JSON化传给前台以作展示。
拦截器:
由于我们不关心对象与字段的映射关联。所以我们只需要在 ResultSetHandler 当中进行拦截就行了,拦截其handleResultSets方法。
直接上代码:
通用查询其实也并非完全通用。只能是稍微的简化一下代码,减少程序员一些重复的工作罢了。本项目采用springMVC + Mybatis + EasyUi 进行构建。设想一种应用场景。我一个统计查询:统计四张表里不同数据,或者多表关联查询:从A表当中查询三个字段,从B表当中查询二个字段,从C表当中查询一个字段,从D表当中查询两个字段。这种场景对于Mybaits来说。几张表的关联查询比较头痛。两种方式,一种是建立实体对象(VO)多表关联查询然后建立映射。返回其VO实体类。另一种方式通过对象关联的方式,Mapper.xml里进行配置。两种方式在此不作讨论。(PS:如有高手有更好的方式解决这种场景请不吝赐教)
本文主要讨论通过Mybatis拦截器实现直接取其 ResultSet 通过约定的SQL语句格式解析后生成数据格式。或者直接JSON化传给前台以作展示。
拦截器:
由于我们不关心对象与字段的映射关联。所以我们只需要在 ResultSetHandler 当中进行拦截就行了,拦截其handleResultSets方法。
直接上代码:
- /*
- * E2ESQM-W 业务端故障诊断系统
- * FileName:MybatisPageInterceptor.java
- * Company: ZZNode Technology Co., Ltd.
- */
- package com.zznode.e2esqm.core.commons;
- import java.lang.reflect.Field;
- import java.sql.ResultSet;
- import java.sql.Statement;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- import org.apache.ibatis.executor.resultset.ResultSetHandler;
- import org.apache.ibatis.mapping.BoundSql;
- 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;
- /**
- * Mybatis直接返回JSON格式拦截组件
- * @author wangkaiping
- * @version V1.0, 2013-5-17 下午11:43:16
- */
- @Intercepts( {@Signature(method = "handleResultSets", type = ResultSetHandler.class, args = {Statement.class}) })
- public class MybatisJsonInterceptor implements Interceptor{
- @Override
- public Object intercept(Invocation invocation) throws Throwable {
- ResultSetHandler resultSetHandler = (ResultSetHandler) invocation.getTarget();
- BoundSql boundsql = (BoundSql) ReflectUtil.getFieldValue(resultSetHandler, "boundSql");
- String sql = boundsql.getSql();
- if(sql.indexOf("t_sys_privilege ch") != -1){ //测试代码写死的 这里应该根据SQL特殊标识进行解析
- String subSql = sql.substring(6, sql.indexOf("from"));
- System.out.println(subSql); // 解析字段格式为: t.id as ID,t.name as 名称,t.age as 年龄
- String [] colmns = subSql.split(",");
- List<String> colmnsArr = new ArrayList<String>(); //字段别名集合。
- for(String i : colmns){
- String [] asName = i.split("as");
- colmnsArr.add(asName[1]);
- }
- Statement statement = (Statement) invocation.getArgs()[0]; //取得方法的参数Statement
- ResultSet rs = statement.getResultSet(); // 取得结果集
- List<Map> list = new ArrayList<Map>(); // 方法要求返回一个List list里装的是K,V的键值对。 K字段别名V值 以便后续JSON化前台直接展示
- while(rs.next()){
- if(colmnsArr.size() >0) {
- Map<String,Object> map = new HashMap<String,Object>();
- for(int i=0 ;i<colmnsArr.size();i++){
- Object obj = rs.getObject(colmnsArr.get(i).trim());
- map.put(colmnsArr.get(i).trim(), obj); //取得结果集后K、V关联后放到MAP当中
- }
- list.add(map);
- }
- }
- return list;//这里直接返回,不要再去invocation.proceed();
- }
- return invocation.proceed();
- }
- @Override
- public Object plugin(Object target) {
- return Plugin.wrap(target, this);
- }
- @Override
- public void setProperties(Properties properties) {
- System.out.println(properties.getProperty("databaseType"));
- }
- /**
- * 反射工具类
- * @author wangkaiping
- * @version V1.0, 2013-5-17 下午11:58:50
- */
- private static class ReflectUtil {
- /**
- * 利用反射获取指定对象的指定属性
- * @param obj 目标对象
- * @param fieldName 目标属性
- * @return 目标属性的值
- */
- public static Object getFieldValue(Object obj, String fieldName) {
- Object result = null;
- Field field = ReflectUtil.getField(obj, fieldName);
- if (field != null) {
- field.setAccessible(true);
- try {
- result = field.get(obj);
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- return result;
- }
- /**
- * 利用反射获取指定对象里面的指定属性
- * @param obj 目标对象
- * @param fieldName 目标属性
- * @return 目标字段
- */
- private static Field getField(Object obj, String fieldName) {
- Field field = null;
- for (Class<?> clazz = obj.getClass(); clazz != Object.class; clazz = clazz
- &nb
给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow