Mybatis(拦截器实现)通用mapper及全ORM实现(二)
发布日期:2022-02-22 18:04:24 浏览次数:13 分类:技术文章

本文共 27819 字,大约阅读时间需要 92 分钟。

上一篇简单介绍了一下mybatisext的基本使用情况,接下来我们开始陆续介绍一下实现

先看一下mapper基类:

package cw.frame.mybatisext.base;import cw.frame.mybatisext.SqlStatement;import cw.frame.mybatisext.base.entity.BaseExtEntity;import org.apache.ibatis.annotations.*;import java.util.List;public interface BaseExtMapper
{ @Insert(BaseSqlStatement.OPERATE_TYPE_ADD_ONE) public int addOne(@Param(BaseSqlStatement.OPERATE_PARAM_ENTITY) Entity entity); @Insert(BaseSqlStatement.OPERATE_TYPE_ADD_MANY) public int addMany(@Param(BaseSqlStatement.OPERATE_PARAM_ENTITIES) List
entities); @Delete(BaseSqlStatement.OPERATE_TYPE_REMOVE_BY_ID) public int removeById(@Param(BaseSqlStatement.OPERATE_PARAM_PRIMARY_KEY) Object id); @Delete(BaseSqlStatement.OPERATE_TYPE_REMOVE_BY_IDS) public int removeByIds(@Param(BaseSqlStatement.OPERATE_PARAM_PRIMARY_KEYS) List
ids); @Delete(BaseSqlStatement.OPERATE_TYPE_REMOVE) public int remove(@Param(BaseSqlStatement.OPERATE_PARAM_SQLSTATEMANT) SqlStatement sqlStatement); @Update(BaseSqlStatement.OPERATE_TYPE_UPDAT_BY_ID) public int updateById(@Param(BaseSqlStatement.OPERATE_PARAM_ENTITY) Entity entity); @Update(BaseSqlStatement.OPERATE_TYPE_UPDATE) public int update(@Param(BaseSqlStatement.OPERATE_PARAM_SQLSTATEMANT) SqlStatement sqlStatement); @Select(BaseSqlStatement.OPERATE_TYPE_GET_BY_ID) public Entity getById(@Param(BaseSqlStatement.OPERATE_PARAM_PRIMARY_KEY) Object id); @Select(BaseSqlStatement.OPERATE_TYPE_GET_BY_IDS) public List
getByIds(@Param(BaseSqlStatement.OPERATE_PARAM_PRIMARY_KEYS) List
ids); @Select(BaseSqlStatement.OPERATE_TYPE_GET_ONE) public Entity getOne(@Param(BaseSqlStatement.OPERATE_PARAM_SQLSTATEMANT) SqlStatement sqlStatement); @Select(BaseSqlStatement.OPERATE_TYPE_GET_MANY) public List
getMany(@Param(BaseSqlStatement.OPERATE_PARAM_SQLSTATEMANT) SqlStatement sqlStatement); @Select(BaseSqlStatement.OPERATE_TYPE_GET_PAGE) public List
getPage(@Param(BaseSqlStatement.OPERATE_PARAM_SQLSTATEMANT) SqlStatement sqlStatement, @Param(BaseSqlStatement.OPERATE_PARAM_PAGER) Pager pager);}

这里定义了一些方法,其中SQL语句都是固定的常量,也就是后续需要通过mybatis拦截器根据范型实体类来做修改

SqlStatement是一个查询对象,后面再介绍

接下来我们看下拦截器的实现,首先看下拦截器代码:

package cw.frame.mybatisext.provider.mysql;import cw.frame.mybatisext.provider.mysql.interceptorhandler.ResultSetHandlerInterceptor;import cw.frame.mybatisext.provider.mysql.interceptorhandler.StatementHandlerInterceptor;import org.apache.ibatis.executor.resultset.ResultSetHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.plugin.*;import java.sql.Connection;import java.sql.Statement;import java.util.*;@Intercepts({        @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),        @Signature(type = StatementHandler.class, method = "update", args = Statement.class),        @Signature(type = ResultSetHandler.class, method="handleResultSets", args={Statement.class})})public class MySqlInterceptor implements Interceptor {    private StatementHandlerInterceptor statementHandlerInterceptor;    private ResultSetHandlerInterceptor resultSetHandlerInterceptor;    @Override    public Object intercept(Invocation invocation) throws Throwable{        // query/update -> prepare -> setParameters -> handleResultSets        Object target = invocation.getTarget();        String methodName = invocation.getMethod().getName();        if (target instanceof StatementHandler && methodName == "prepare"){            return this.getStatementHandlerInterceptor().prepare(invocation);        } else if (target instanceof StatementHandler && methodName == "update"){            return this.getStatementHandlerInterceptor().update(invocation);        } else if (target instanceof ResultSetHandler && methodName == "handleResultSets"){            return this.getResultSetHandlerInterceptor().handleResultSets(invocation);        }        return invocation.proceed();    }    @Override    public Object plugin(Object target) {        return Plugin.wrap(target, this);    }    @Override    public void setProperties(Properties properties) {    }    private StatementHandlerInterceptor getStatementHandlerInterceptor() {        if (this.statementHandlerInterceptor == null){            this.statementHandlerInterceptor = new StatementHandlerInterceptor();        }        return this.statementHandlerInterceptor;    }    private ResultSetHandlerInterceptor getResultSetHandlerInterceptor() {        if (this.resultSetHandlerInterceptor == null){            this.resultSetHandlerInterceptor = new ResultSetHandlerInterceptor();        }        return this.resultSetHandlerInterceptor;    }}

因为目前我只实现了mysql数据库操作,所以这个拦截器是在cw.frame.mybatisext.provider.mysql包下,相应的查询对象等都是在这个包下

mybatis的拦截器可以拦截的几个方法也是整个数据操作的一个流程:query/update -> prepare -> setParameters -> handleResultSets,根据我们的需求,我们相应要做的就是:

1、修改sql语句
2、设置参数
3、封装返回结果
所以我这里针对了prepare、update、handleResultSets这三个方法进行拦截,设置参数我放在了prepare里

我们先看下prepare、updat的拦截实现,他们在StatementHandlerInterceptor中,代码稍有点长了,没耐心的可以先略过

package cw.frame.mybatisext.provider.mysql.interceptorhandler;import cw.frame.mybatisext.SqlStatement;import cw.frame.mybatisext.base.BaseSqlStatement;import cw.frame.mybatisext.base.FormatSqlWrapper;import cw.frame.mybatisext.base.Pager;import cw.frame.mybatisext.base.entity.BaseExtEntity;import cw.frame.mybatisext.base.entity.BaseExtEnum;import cw.frame.mybatisext.base.entity.ColumnInfo;import cw.frame.mybatisext.base.entity.TableInfo;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.SqlCommandType;import org.apache.ibatis.plugin.Invocation;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.Statement;import java.util.ArrayList;import java.util.List;public class StatementHandlerInterceptor extends BaseInterceptorHandler {    private Logger logger= LoggerFactory.getLogger(getClass());    public Object prepare(Invocation invocation) throws Throwable{        Object target = invocation.getTarget();        StatementHandler statementHandler = (StatementHandler)target;        BoundSql boundSql = statementHandler.getBoundSql();        if (!this.needInterceptor(boundSql.getSql())){            return invocation.proceed();        }        MetaObjectHelper metaObjectHelper = new MetaObjectHelper(statementHandler);        SqlCommandType sqlCommandType = metaObjectHelper.getSqlCommandType();        Object result = null;        if (sqlCommandType == SqlCommandType.INSERT){            result = executeInsertOnPrepareMethod(metaObjectHelper, (Connection)invocation.getArgs()[0], boundSql.getSql());        } else if (sqlCommandType == SqlCommandType.DELETE){            result = executeDeleteOnPrepareMethod(metaObjectHelper, (Connection)invocation.getArgs()[0], boundSql.getSql());        } else if (sqlCommandType == SqlCommandType.UPDATE){            result = executeUpdateOnPrepareMethod(metaObjectHelper, (Connection)invocation.getArgs()[0], boundSql.getSql());        } else if (sqlCommandType == SqlCommandType.SELECT){            result = executeSelectOnPrepareMethod(metaObjectHelper, (Connection)invocation.getArgs()[0], boundSql.getSql());        }        if (result == null){            return invocation.proceed();        } else {            return result;        }    }    public Object update(Invocation invocation) throws Throwable{        Object target = invocation.getTarget();        Object[] args = invocation.getArgs();        StatementHandler statementHandler = (StatementHandler)target;        BoundSql boundSql = statementHandler.getBoundSql();        if (!this.needInterceptor(boundSql.getSql())){            return invocation.proceed();        }        MetaObjectHelper metaObjectHelper = new MetaObjectHelper(statementHandler);        Object result = null;        if (metaObjectHelper.getSqlCommandType() == SqlCommandType.INSERT){            String operateSql = boundSql.getSql();            Object parameterObject = null;            if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_ADD_ONE)){                parameterObject = metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_ENTITY);            } else if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_ADD_MANY)){                parameterObject = metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_ENTITIES);            }            result = executeInsertOnUpdateMethod(parameterObject, (PreparedStatement)args[0], operateSql);        }        if (result == null){            return invocation.proceed();        } else {            return result;        }    }    private PreparedStatement executeSelectOnPrepareMethod(MetaObjectHelper metaObjectHelper, Connection connection, String operateSql) throws Throwable{        if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_GET_BY_ID)){            Object parameterObject = metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_PRIMARY_KEY);            TableInfo tableInfo = TableInfo.getTableInfo(metaObjectHelper.getEntityClassType());            ColumnInfo primaryKeyColumn = tableInfo.getPrimaryKeyColumn();            StringBuilder sb = new StringBuilder();            sb.append("select * from ").append(tableInfo.getTableName()).append(" where `");            sb.append(primaryKeyColumn.getColumnName()).append("`=?");            PreparedStatement preparedStatement = this.getPreparedStatementBySql(sb.toString(), connection);            this.setPreparedStatementValue(preparedStatement,1, parameterObject);            return preparedStatement;        } else if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_GET_BY_IDS)){            Object parameterObject = metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_PRIMARY_KEYS);            TableInfo tableInfo = TableInfo.getTableInfo(metaObjectHelper.getEntityClassType());            ColumnInfo primaryKeyColumn = tableInfo.getPrimaryKeyColumn();            List keys = (List)parameterObject;            StringBuilder sb = new StringBuilder();            sb.append("select * from ").append(tableInfo.getTableName()).append(" where find_in_set(`");            sb.append(primaryKeyColumn.getColumnName()).append("`,?)");            PreparedStatement preparedStatement = this.getPreparedStatementBySql(sb.toString(), connection);            this.setPreparedStatementValue(preparedStatement, 1, this.joinKeys(keys));            return preparedStatement;        } else if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_GET_ONE)){            SqlStatement sqlStatement = (SqlStatement) metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_SQLSTATEMANT);            FormatSqlWrapper formatSqlWrapper = sqlStatement.getFormatSqlWrapper();            String sql = formatSqlWrapper.getSql();            int indexOfLimit = sql.indexOf("limit");            if (indexOfLimit > 0){                sql = "select * from (" + sql + ") a limit 1";            } else {                sql += " limit 1";            }            return getPreparedStatementBySqlStatement(sql, formatSqlWrapper.getParameters(), connection);        } else if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_GET_MANY)){            return getPreparedStatementBySqlStatement(metaObjectHelper, connection);        } else if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_GET_PAGE)){            SqlStatement sqlStatement = (SqlStatement) metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_SQLSTATEMANT);            Pager pager = (Pager) metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_PAGER);            FormatSqlWrapper formatSqlWrapper = sqlStatement.getFormatSqlWrapper();            String pageSql = formatSqlWrapper.getSql();            String sql = "select count(*) from (" + pageSql + ") a";            PreparedStatement countStatement = getPreparedStatementBySqlStatement(sql, formatSqlWrapper.getParameters(), connection);            ResultSet resultSet = countStatement.executeQuery();            if (resultSet.next()){                Object count = resultSet.getObject(1);                pager.setRowCount(Integer.valueOf(count.toString()));                int currentPage = pager.getCurrentPage();                int pageSize = pager.getPageSize();                int skip = pageSize * (currentPage - 1);                StringBuilder sb = new StringBuilder();                int indexOfLimit = pageSql.indexOf("limit");                if (indexOfLimit > 0){                    sb.append("select * from (").append(pageSql).append(") a");                } else {                    sb.append(pageSql);                }                sb.append(" limit ");                if (skip > 0){                    sb.append(skip).append(",");                }                sb.append(pageSize);                return getPreparedStatementBySqlStatement(sb.toString(), formatSqlWrapper.getParameters(), connection);            }            return getPreparedStatementBySqlStatement(metaObjectHelper, connection);        }        return null;    }    private PreparedStatement executeUpdateOnPrepareMethod(MetaObjectHelper metaObjectHelper, Connection connection, String operateSql) throws Throwable{        if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_UPDAT_BY_ID)){            Object parameterObject = metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_ENTITY);            TableInfo tableInfo = TableInfo.getTableInfo(parameterObject.getClass().getName());            StringBuilder sbSetPart = new StringBuilder();            ColumnInfo primaryKeyColumn = tableInfo.getPrimaryKeyColumn();            List values = new ArrayList();            for (ColumnInfo columnInfo : tableInfo.getColumnns()){                if (!columnInfo.isDbColumn()){                    continue;                }                if (!columnInfo.getIsPrimaryKey()){                    if (sbSetPart.length() > 0){                        sbSetPart.append(",");                    }                    sbSetPart.append("`").append(columnInfo.getColumnName()).append("`").append("=?");                    values.add(TableInfo.getFieldValue(parameterObject, columnInfo.getField()));                }            }            StringBuilder sb = new StringBuilder();            sb.append("update ").append(tableInfo.getTableName()).append(" set ");            sb.append(sbSetPart.toString());            sb.append(" where `").append(primaryKeyColumn.getColumnName()).append("`=?");            PreparedStatement preparedStatement = this.getPreparedStatementBySql(sb.toString(), connection);            int i = 1;            for (Object value : values){                this.setPreparedStatementValue(preparedStatement, i, value);                i++;            }            this.setPreparedStatementValue(preparedStatement, i, TableInfo.getFieldValue(parameterObject, primaryKeyColumn.getField()));            return preparedStatement;        } else if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_UPDATE)){            return getPreparedStatementBySqlStatement(metaObjectHelper, connection);        }        return null;    }    private PreparedStatement executeDeleteOnPrepareMethod(MetaObjectHelper metaObjectHelper, Connection connection, String operateSql) throws Throwable{        if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_REMOVE_BY_ID)){            Object parameterObject = metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_PRIMARY_KEY);            TableInfo tableInfo = TableInfo.getTableInfo(metaObjectHelper.getEntityClassType());            ColumnInfo primaryKeyColumn = tableInfo.getPrimaryKeyColumn();            StringBuilder sb = new StringBuilder();            sb.append("delete from ").append(tableInfo.getTableName()).append(" where ");            sb.append(primaryKeyColumn.getColumnName()).append("=?");            PreparedStatement preparedStatement = this.getPreparedStatementBySql(sb.toString(), connection);            this.setPreparedStatementValue(preparedStatement,1, parameterObject);            return preparedStatement;        } else if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_REMOVE_BY_IDS)){            Object parameterObject = metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_PRIMARY_KEYS);            TableInfo tableInfo = TableInfo.getTableInfo(metaObjectHelper.getEntityClassType());            ColumnInfo primaryKeyColumn = tableInfo.getPrimaryKeyColumn();            List keys = (List)parameterObject;            StringBuilder sb = new StringBuilder();            sb.append("delete from ").append(tableInfo.getTableName()).append(" where find_in_set(`");            sb.append(primaryKeyColumn.getColumnName()).append("`,?)");            PreparedStatement preparedStatement = this.getPreparedStatementBySql(sb.toString(), connection);            this.setPreparedStatementValue(preparedStatement,1, this.joinKeys(keys).toString());            return preparedStatement;        } else if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_REMOVE)){            return getPreparedStatementBySqlStatement(metaObjectHelper, connection);        }        return null;    }    private PreparedStatement executeInsertOnPrepareMethod(MetaObjectHelper metaObjectHelper, Connection connection, String operateSql) throws Throwable{        TableInfo tableInfo;        List entities = null;        Object parameterObject;        if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_ADD_ONE)){            parameterObject = metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_ENTITY);            tableInfo = TableInfo.getTableInfo(parameterObject.getClass().getName());            entities = new ArrayList();            entities.add(parameterObject);        } else if (operateSql.equals(BaseSqlStatement.OPERATE_TYPE_ADD_MANY)){            parameterObject = metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_ENTITIES);            entities = (List)parameterObject;            if (entities.size() == 0){                throw new IllegalArgumentException();            }            tableInfo = TableInfo.getTableInfo(entities.get(0).getClass().getName());        } else {            return null;        }        List
> allValues = new ArrayList
>(); String sql = getInsertSql(tableInfo, entities, allValues); ColumnInfo primaryKeyColumn = tableInfo.getPrimaryKeyColumn(); PreparedStatement preparedStatement; if (primaryKeyColumn.getIsPrimaryKey() && primaryKeyColumn.isGeneratedKey() && allValues.size() == 1){ preparedStatement = this.getPreparedStatementBySql(sql, connection, Statement.RETURN_GENERATED_KEYS); } else { preparedStatement = this.getPreparedStatementBySql(sql, connection); } for (List values : allValues){ for (int i=0; i
1){ preparedStatement.addBatch(); } } return preparedStatement; } private String getInsertSql(TableInfo tableInfo, List
entities, List
> allValues) throws Throwable{ StringBuilder sb = new StringBuilder(); sb.append("insert into "); sb.append(tableInfo.getTableName()); sb.append("("); StringBuilder sbColumn = new StringBuilder(); StringBuilder sbValue = new StringBuilder(); for (int i=0; i
values = new ArrayList
(); for (ColumnInfo columnInfo : tableInfo.getColumnns()){ if (!columnInfo.isDbColumn()){ continue; } if (columnInfo.getIsPrimaryKey() && columnInfo.isGeneratedKey()){ continue; } if (i == 0){ if (sbColumn.length() > 0){ sbColumn.append(","); sbValue.append(","); } sbColumn.append("`").append(columnInfo.getColumnName()).append("`"); sbValue.append("?"); } Object val = TableInfo.getFieldValue(entities.get(i), columnInfo.getField()); values.add(val); } allValues.add(values); } sb.append(sbColumn.toString()).append(")"); sb.append(" values(").append(sbValue.toString()).append(")"); return sb.toString(); } private Integer executeInsertOnUpdateMethod(Object parameterObject, PreparedStatement preparedStatement, String operateSql) throws Throwable{ Object entity = null; if (parameterObject instanceof BaseExtEntity){ entity = parameterObject; } else if (parameterObject instanceof List){ List entities = (List)parameterObject; if (entities.size() == 1){ entity = entities.get(0); } } if (entity != null){ TableInfo tableInfo = TableInfo.getTableInfo(entity.getClass().getName()); ColumnInfo keyColumnInfo = tableInfo.getPrimaryKeyColumn(); int result = preparedStatement.executeUpdate(); if (keyColumnInfo.isGeneratedKey()){ ResultSet rs = preparedStatement.getGeneratedKeys(); if (rs.next()){ Object primaryKeyValue = rs.getObject(1); TableInfo.setFieldValue(parameterObject, keyColumnInfo.getField(), primaryKeyValue); } } return result; } else { int[] results = preparedStatement.executeBatch(); int resultNum = 0; for (int v : results){ resultNum += v; } return resultNum; } } private PreparedStatement getPreparedStatementBySqlStatement(MetaObjectHelper metaObjectHelper, Connection connection) throws Throwable{ SqlStatement sqlStatement = (SqlStatement) metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_SQLSTATEMANT); FormatSqlWrapper formatSqlWrapper = sqlStatement.getFormatSqlWrapper(); return this.getPreparedStatementBySqlStatement(formatSqlWrapper.getSql(), formatSqlWrapper.getParameters(), connection); } private PreparedStatement getPreparedStatementBySqlStatement(String sql, List parameters, Connection connection) throws Throwable{ PreparedStatement preparedStatement = this.getPreparedStatementBySql(sql, connection); for (int i=0; i

这里我们先说prepare的处理,首先判断本次请求是不是需要拦截,这里的判断是根据sql语句是不是mapper基类里那些常量(SQL),当然这些sql不是真正的sql语句,包括参数名称他们都定义在了查询对象基础类里

public static final String OPERATE_TYPE_NAME_PRE = "mybatisext.";    public static final String OPERATE_TYPE_ADD_ONE = OPERATE_TYPE_NAME_PRE + "addOne";    public static final String OPERATE_TYPE_ADD_MANY = OPERATE_TYPE_NAME_PRE + "addMany";    public static final String OPERATE_TYPE_REMOVE_BY_ID = OPERATE_TYPE_NAME_PRE + "removeById";    public static final String OPERATE_TYPE_REMOVE_BY_IDS = OPERATE_TYPE_NAME_PRE + "removeByIds";    public static final String OPERATE_TYPE_REMOVE = OPERATE_TYPE_NAME_PRE + "remove";    public static final String OPERATE_TYPE_UPDAT_BY_ID = OPERATE_TYPE_NAME_PRE + "updateById";    public static final String OPERATE_TYPE_UPDATE = OPERATE_TYPE_NAME_PRE + "update";    public static final String OPERATE_TYPE_GET_BY_ID = OPERATE_TYPE_NAME_PRE + "findById";    public static final String OPERATE_TYPE_GET_BY_IDS = OPERATE_TYPE_NAME_PRE + "findByIds";    public static final String OPERATE_TYPE_GET_ONE = OPERATE_TYPE_NAME_PRE + "getOne";    public static final String OPERATE_TYPE_GET_MANY = OPERATE_TYPE_NAME_PRE + "getMany";    public static final String OPERATE_TYPE_GET_PAGE = OPERATE_TYPE_NAME_PRE + "getPage";    public static final String OPERATE_PARAM_ENTITY = "entity";    public static final String OPERATE_PARAM_ENTITIES = "entities";    public static final String OPERATE_PARAM_PRIMARY_KEY = "id";    public static final String OPERATE_PARAM_PRIMARY_KEYS = "ids";    public static final String OPERATE_PARAM_SQLSTATEMANT = "sqlStatement";    public static final String OPERATE_PARAM_PAGER = "pager";

如不需要拦截,则直接返回原操作结果,确定需要拦截之后就开始进行sql语句的修改和参数的传入工作。首先为了获取一些当前操作信息,用到了mybatis提供的MetaObject对象并进行了一个封装方便提取一些需要的属性在MetaObjectHelper类中

package cw.frame.mybatisext.base;import cw.frame.mybatisext.SqlStatement;import cw.frame.mybatisext.base.entity.BaseExtEntity;import org.apache.ibatis.binding.MapperMethod;import org.apache.ibatis.executor.parameter.ParameterHandler;import org.apache.ibatis.executor.resultset.ResultSetHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.mapping.SqlCommandType;import org.apache.ibatis.reflection.DefaultReflectorFactory;import org.apache.ibatis.reflection.MetaObject;import org.apache.ibatis.reflection.SystemMetaObject;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;public class MetaObjectHelper {    private MetaObject metaObject;    private String keyPre = "";    public MetaObjectHelper(StatementHandler statementHandler){        this.metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());        this.keyPre = "delegate.";    }    public MetaObjectHelper(ResultSetHandler resultSetHandler){        this.metaObject = MetaObject.forObject(resultSetHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());        this.keyPre = "";    }    public ParameterHandler getParameterHandler(){        return (ParameterHandler)this.metaObject.getValue(this.keyPre + "parameterHandler");    }    public SqlCommandType getSqlCommandType(){        return this.getMappedStatement().getSqlCommandType();    }    public Object getParameterObject(){        return this.getParameterHandler().getParameterObject();    }    public Object getParameterObject(String paramName){        Object object = this.getParameterObject();        if (object instanceof MapperMethod.ParamMap){            MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap)object;            if (paramMap.keySet().contains(paramName)){                return paramMap.get(paramName);            }        }        return null;    }    public MappedStatement getMappedStatement(){        return (MappedStatement)this.metaObject.getValue(this.keyPre + "mappedStatement");    }    public String getMapperId(){        return this.getMappedStatement().getId();    }    public SqlStatement getSqlStatement(){        Object parameterObject = this.getParameterObject();        if (parameterObject instanceof MapperMethod.ParamMap){            MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap)parameterObject;            if (paramMap.keySet().contains("sqlStatement")){                return  (SqlStatement) paramMap.get("sqlStatement");            }        }        return null;    }    public Class
getEntityClassType() throws Throwable{ Class
entityClass = null; String mapperId = this.getMapperId(); String className = mapperId.substring(0, mapperId.lastIndexOf(".")); Class
clazz = Class.forName(className); for (Type type : clazz.getGenericInterfaces()){ ParameterizedType parameterizedType = (ParameterizedType)type; for (Type argumentsType : parameterizedType.getActualTypeArguments()){ Class argumentClass = Class.forName(argumentsType.getTypeName()); if (BaseExtEntity.class.isAssignableFrom(argumentClass)){ entityClass = argumentClass; break; } } if (entityClass != null){ break; } } return entityClass; } public void setSql(String sql){ this.metaObject.setValue(this.keyPre + "boundSql.sql", sql); }}

随后再根据操作类型和参数进行sql语句的创建、和参数设定,最后返回新的PreparedStatement,这个过程我们就拿添加单个实体一种情况做下说明,其它的都大同小异了,可以自行看代码

添加单个实体,对应mapper方法:

@Insert(BaseSqlStatement.OPERATE_TYPE_ADD_ONE)    public int addOne(@Param(BaseSqlStatement.OPERATE_PARAM_ENTITY) Entity entity);

首先我们获取参数,通过前面提到的MetaObjectHelper类:

parameterObject = metaObjectHelper.getParameterObject(BaseSqlStatement.OPERATE_PARAM_ENTITY);

然后获取实体的类型和对应的数据相应信息,这里用到了TableInfo类在下一篇我们介绍

对于添加一条记录和多条记录的sql语句是一样的,只是设置参数的变化

获取默认的PreparedStatement:connection.prepareStatement(sql, autoGeneratedKeys);

根据TableInfo类给到的实体映射信息构建sql并设置参数,最后返回初始化好的PreparedStatement

接下来就是交给mybatis自己去执行sql了,然后对于新增方法我们在update拦截中对返回结果数和自增id进行赋值。mybatis对insert和update都会走StatementHandler.update方法,并不会走ResultSetHandler.handleResultSets方法

本篇先介绍到这,源代码

转载地址:https://blog.csdn.net/erct/article/details/82698504 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Mybatis(拦截器实现)通用mapper及全ORM实现(一)
下一篇:Mybatis(拦截器实现)通用mapper及全ORM实现(三)

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月11日 05时20分40秒