本文共 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
这里定义了一些方法,其中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(); Listvalues = 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!