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

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

到目前为止,我们通过mybatis的拦截器完成了一些基础mapper的功能,接下来我们来看看如何能够实现一个对象关系映射的全ORM操作。

实体与表、列的定义已经完成了,那剩下要做的就是:

1、定义如何通过对象方式编写sql语句
2、把查询对象转译成sql去查询
3、把查询结果转化成实体对象

我们先看看mybatisext关于查询对象的一些类关系:

SqlStatement接口

所有查询对象必须实现一下几个方法:

1、getSqlWrapper() 
    返回一个sql信息对象包括sql语句和里面的相关参数map信息
2、getResultMap()
    返回这个查询sql的返回结果中每个字段对应的实体类及其中的属性
3、getFormatSqlWrapper()
    返回一个标准的sql信息对象,与getSqlWrapper不同是sql语句里面不会有需要替换的变量,以mysql为例参数会替换成?,并包括根据参数顺序的参数值数组
4、getFormatSqlReplacement()
     sql中参数替代自负,默认?

package cw.frame.mybatisext.base;import java.util.HashMap;import java.util.Map;public class SqlWrapper {    private String sql;    private Map
parameters = new HashMap
(); public SqlWrapper(){} public SqlWrapper(String sql){ this.sql = sql; } public SqlWrapper(String sql, Map
parameters){ this.sql = sql; this.parameters = parameters; } public Map
getParameters() { return parameters; } public String getSql() { return sql; } public void setParameters(Map
parameters) { this.parameters = parameters; } public void setSql(String sql) { this.sql = sql; }}
package cw.frame.mybatisext.base;import cw.frame.mybatisext.base.entity.TableInfo;import java.util.*;public class ResultMap {    private TableInfo tableInfo;    private Map
resultMap; private Map
subResultMap; public ResultMap(TableInfo tableInfo){ this.tableInfo = tableInfo; this.resultMap = new HashMap
(); this.subResultMap = null; } public void addResultMap(String resultName, String propertyName){ this.resultMap.put(resultName, propertyName); } /** * 添加子结果映射 * @param subResultMap 子结果map对象 * @param resultPropertyName 结果存储字段 */ public void addSubResultMap(ResultMap subResultMap, String resultPropertyName){ if (this.subResultMap == null){ this.subResultMap = new HashMap
(); } this.subResultMap.put(resultPropertyName, subResultMap); } public Map
getResultMap(){ return this.resultMap; } public boolean hasSubResultMap(){ if (this.subResultMap != null && this.subResultMap.size() > 0){ return true; } else { return false; } } public Map
getSubResultMap() { return subResultMap; } public TableInfo getTableInfo(){ return this.tableInfo; }}

BaseSqlStatement抽象类

SqlStatement的实现类,定义了基础mapper中需要拦截的sql语句常量、参数名称常量,和一个抽象方法prepare()

getFormatSqlWrapper() -> getSqlWrapper() -> prepare()

子类需要完善的prepare()方法要做的事情也就是创建一个SqlWrapper对象

package cw.frame.mybatisext.base;import cw.frame.mybatisext.SqlStatement;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.regex.Matcher;import java.util.regex.Pattern;public abstract class BaseSqlStatement implements SqlStatement {    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";    private SqlWrapper sqlWrapper;    private ResultMap resultMap;    private FormatSqlWrapper formatSqlWrapper = null;    @Override    public SqlWrapper getSqlWrapper(){        if (this.sqlWrapper == null){            this.prepare();        }        return this.sqlWrapper;    }    @Override    public ResultMap getResultMap(){        return this.resultMap;    }    @Override    public FormatSqlWrapper getFormatSqlWrapper(){        if (this.formatSqlWrapper == null){            this.formatSql();        }        return this.formatSqlWrapper;    }    public void setResultMap(ResultMap resultMap){        this.resultMap = resultMap;    }    public String getParameterName(String tableName, String propertyName){        StringBuilder sb = new StringBuilder();        sb.append("#{");        if(tableName != null && !tableName.isEmpty()){            sb.append(tableName).append(".");        }        sb.append(propertyName);        sb.append("}");        return sb.toString();    }    protected void setSqlWrapper(String sql) {        this.sqlWrapper = new SqlWrapper(sql);    }    protected void setSqlWrapper(String sql, Map
parameters) { this.sqlWrapper = new SqlWrapper(sql, parameters); } protected void setSqlWrapper(SqlWrapper sqlWrapper) { this.sqlWrapper = sqlWrapper; } protected void unsetSqlWrapper(){ this.sqlWrapper = null; } protected SqlWrapper combineSqlWrappers(List
sqlStatements, String joinStr){ if (sqlStatements.size() == 0){ return new SqlWrapper(); } StringBuilder sb = new StringBuilder(); Map
parameters = new HashMap
(); for(SqlStatement sqlStatement : sqlStatements){ if (sb.length() > 0){ sb.append(joinStr); } SqlWrapper sqlWrapper = sqlStatement.getSqlWrapper(); sb.append(sqlWrapper.getSql()); parameters.putAll(sqlWrapper.getParameters()); } return new SqlWrapper(sb.toString(), parameters); } protected abstract void prepare(); private void formatSql(){ StringBuffer sbSql = new StringBuffer(); List
values = new ArrayList(); SqlWrapper sqlWrapper = this.getSqlWrapper(); Pattern pattern = Pattern.compile("#\\{\\S+?\\}"); Matcher matcher = pattern.matcher(sqlWrapper.getSql()); while (matcher.find()){ matcher.appendReplacement(sbSql, this.getFormatSqlReplacement()); values.add(sqlWrapper.getParameters().get(matcher.group())); } matcher.appendTail(sbSql); this.formatSqlWrapper = new FormatSqlWrapper(sbSql.toString(), values); }}

接下来就是定义具体的查询对象了,mybatisext把一个查询拆分成几个部分并进行不同的类封装:

1、select字段部分
2、表连接部分
3、单个条件字段部分
4、单个分组group字段部分
5、单个having字段你部分
6、单个order字段排序部分
7、多个条件、排序、分组、连接的部分

我们来逐一看下代码

package cw.frame.mybatisext.provider.mysql.statement;import cw.frame.mybatisext.base.BaseSqlStatement;import cw.frame.mybatisext.base.ResultMap;import cw.frame.mybatisext.base.entity.BaseExtEntity;import cw.frame.mybatisext.base.entity.ColumnInfo;import cw.frame.mybatisext.base.entity.TableInfo;import cw.frame.mybatisext.provider.mysql.ExpressionExplain;import cw.frame.mybatisext.provider.mysql.ExpressionResult;import java.util.*;public class SelectStatement extends BaseSqlStatement {    private Class
entityClassType; private Set
selectPropertyNames = new TreeSet
(); private Map
selectPropertyNameMap = new HashMap
(); private TableInfo tableInfo; private String aliasTableName; private Map
propertyResultMap = new HashMap
(); private ResultMap resultMap; public SelectStatement(Class
entityClassType, String aliasTableName){ this.entityClassType = entityClassType; this.aliasTableName = aliasTableName; this.tableInfo = TableInfo.getTableInfo(this.entityClassType); this.resultMap = new ResultMap(this.tableInfo); this.setResultMap(this.resultMap); } /** * 设置查询列 * @param propertyNames propertyName, max(#{propertyName})等 */ public void select(String... propertyNames){ for (String propertyName : propertyNames){ if (propertyName.equals("*")){ for (ColumnInfo columnInfo : this.tableInfo.getColumnns()){ this.selectPropertyNames.add(columnInfo.getPropertyName()); } break; } else { this.selectPropertyNames.add(propertyName); } } this.unsetSqlWrapper(); } /** * 设置查询列 * @param propertyName propertyName, max(#{propertyName})等 * @param resultPropertyName 结果返回存储属性字段 */ public void selectAs(String propertyName, String resultPropertyName){ this.selectPropertyNameMap.put(propertyName, resultPropertyName); } /** * 设置查询列 * @param propertyNameMap k:propertyName propertyName, max(#{propertyName})等,v:结果返回存储属性字段 */ public void selectAs(Map
propertyNameMap){ this.selectPropertyNameMap.putAll(propertyNameMap); } public TableInfo getTableInfo(){ return this.tableInfo; } public boolean hasSelectFields(){ return this.selectPropertyNames.size() > 0; } public String getAliasTableName() { return aliasTableName; } public Map
getPropertyResultMap() { return propertyResultMap; } @Override protected void prepare(){ StringBuilder sb = new StringBuilder(); for (String propertyName : this.selectPropertyNames){ this.buildSelectItemPartSql(sb, propertyName, null); } for (String propertyName : this.selectPropertyNameMap.keySet()){ this.buildSelectItemPartSql(sb, propertyName, this.selectPropertyNameMap.get(propertyName)); } // 查询所有字段 if (sb.length() == 0){ for (String propertyName : this.tableInfo.getPropertyNames()){ this.buildSelectItemPartSql(sb, propertyName, null); } } String sql = sb.toString(); this.setSqlWrapper(sql); } private void buildSelectItemPartSql(StringBuilder sb, String selectFieldString, String resultProperty){ if (sb.length() != 0){ sb.append(","); } ExpressionResult expressionResult = ExpressionExplain.explain(selectFieldString, this); ColumnInfo columnInfo = expressionResult.getColumn(); if (expressionResult.isExpression()){ sb.append(expressionResult.getResult()); } else { sb.append(this.aliasTableName).append(".`"); sb.append(columnInfo.getColumnName()).append("`"); } String asName; String resultPropertyName; if (resultProperty == null || resultProperty.isEmpty()){ asName = this.aliasTableName + "_" + columnInfo.getColumnName(); resultPropertyName = columnInfo.getPropertyName(); } else { ColumnInfo resultColumn = this.tableInfo.getColumnByPropertyName(resultProperty); resultPropertyName = resultProperty; if (resultColumn.isDbColumn()){ asName = this.aliasTableName + "_" + resultColumn.getPropertyName(); } else { asName = this.aliasTableName + "_" + resultPropertyName; } } sb.append(" ").append(asName); this.propertyResultMap.put(resultPropertyName, asName); this.resultMap.addResultMap(asName, resultPropertyName); }}

通过SelectStatement可以设置需要查询的列,也可以指定查询列结果别名(column1 as xxx),并对自定义了一个别名:表别名_列名(或指定的别名),最终把这些别名和实体对应关系记录在一个ResultMap类里

package cw.frame.mybatisext.provider.mysql.statement;import cw.frame.mybatisext.base.BaseSqlStatement;import cw.frame.mybatisext.base.SqlWrapper;import cw.frame.mybatisext.enumeration.JoinType;import cw.frame.mybatisext.provider.mysql.MySqlStatement;import java.util.HashMap;import java.util.Map;public class SingleJoinStatement extends BaseSqlStatement {    private SelectStatement fromSelectStatement;    private Object toStatement;    private JoinType joinType;    private Map
joinRelationshipMap = new HashMap
(); public SingleJoinStatement(SelectStatement fromSelectStatement, SelectStatement toSelectStatement, JoinType joinType){ this.fromSelectStatement = fromSelectStatement; this.toStatement = toSelectStatement; this.joinType = joinType; } public SingleJoinStatement(SelectStatement fromSelectStatement, MySqlStatement toMySqlStatement, JoinType joinType){ this.fromSelectStatement = fromSelectStatement; this.toStatement = toMySqlStatement; this.joinType = joinType; } public void setRelationship(String fromPropertyName, String toPropertyName){ this.joinRelationshipMap.put(fromPropertyName, toPropertyName); } @Override protected void prepare(){ StringBuilder sb = new StringBuilder(); Map
parameters = new HashMap
(); SelectStatement toSelectStatement = null; MySqlStatement toMySqlStatement = null; for (String fromPropertyName : this.joinRelationshipMap.keySet()){ String toPropertyName = this.joinRelationshipMap.get(fromPropertyName); if (sb.length() == 0){ sb.append(this.getJoinTypeSqlString(this.joinType)).append(" "); if (this.toStatement instanceof SelectStatement){ toSelectStatement = (SelectStatement)this.toStatement; String toTableAsName = toSelectStatement.getAliasTableName(); sb.append("`").append(toSelectStatement.getTableInfo().getTableName()).append("`"); sb.append(" ").append(toTableAsName); } else { // 连接子查询 toMySqlStatement = (MySqlStatement)this.toStatement; String toTableAsName = toMySqlStatement.getSelectStatement().getAliasTableName(); SqlWrapper wrapper = toMySqlStatement.getSqlWrapper(); parameters.putAll(wrapper.getParameters()); sb.append("(").append(wrapper.getSql()).append(")"); sb.append(" ").append(toTableAsName); } sb.append(" on "); } else { sb.append(" and "); } sb.append(this.fromSelectStatement.getAliasTableName()).append(".`"); sb.append(this.fromSelectStatement.getTableInfo().getColumnByPropertyName(fromPropertyName).getColumnName()); sb.append("`="); if (toSelectStatement != null){ sb.append(toSelectStatement.getAliasTableName()).append(".").append("`"); sb.append(toSelectStatement.getTableInfo().getColumnByPropertyName(toPropertyName).getColumnName()); sb.append("`"); } else { sb.append(toMySqlStatement.getSelectStatement().getAliasTableName()); sb.append(".`"); sb.append(toMySqlStatement.getSelectStatement().getPropertyResultMap().get(toPropertyName)); sb.append("`"); } } this.setSqlWrapper(new SqlWrapper(sb.toString(), parameters)); } private String getJoinTypeSqlString(JoinType joinType){ String str; switch (joinType){ case LEFT_JOIN: str = "left join"; break; case INNER_JOIN: str = "inner join"; break; case RIGHT_JOIN: str = "right join"; break; default: str = "inner join"; break; } return str; }}

SingleJoinStatement支持了两个表的连接和表与一个查询对象(子查询)的连接

package cw.frame.mybatisext.provider.mysql.statement;import cw.frame.mybatisext.base.BaseSqlStatement;import cw.frame.mybatisext.SqlStatement;import cw.frame.mybatisext.base.SqlWrapper;import cw.frame.mybatisext.base.entity.BaseExtEnum;import cw.frame.mybatisext.enumeration.ConditionType;import java.lang.reflect.Array;import java.util.HashMap;import java.util.Map;public class SingleConditionStatement extends BaseSqlStatement {    private ConditionType conditionType;    private String columnName;    private Object propertyValue;    private String tableName = "";    public SingleConditionStatement(String tableName, String columnName, ConditionType conditionType, Object propertyValue){        this.columnName = columnName;        this.conditionType = conditionType;        this.propertyValue = propertyValue;        this.tableName = tableName;    }    public String getColumnName() {        return columnName;    }    public ConditionType getConditionType() {        return conditionType;    }    public Object getPropertyValue() {        return propertyValue;    }    @Override    protected void prepare(){        Map
parameters = new HashMap
(); StringBuilder sb = new StringBuilder(); String conditionColumnName = "`" + this.columnName + "`"; if (!this.tableName.isEmpty()){ conditionColumnName = this.tableName + "." + conditionColumnName; } switch (this.conditionType){ case IN: sb.append(" find_in_set (").append(conditionColumnName).append(","); break; case NOT_IN: sb.append(" not find_in_set (").append(conditionColumnName).append(","); break; case EQUAL: sb.append(conditionColumnName); sb.append("="); break; case NOT_EQUAL: sb.append(conditionColumnName); sb.append("<>"); break; case GREATER: sb.append(conditionColumnName); sb.append(">"); break; case GREATER_AND_EQUAL: sb.append(conditionColumnName); sb.append(">="); break; case LESS: sb.append(conditionColumnName); sb.append("<"); break; case LESS_AND_EQUAL: sb.append(conditionColumnName); sb.append("<="); break; case LIKE: sb.append(conditionColumnName); sb.append(" like "); break; case NOT_LIKE: sb.append(conditionColumnName); sb.append(" not like "); break; } if (this.propertyValue instanceof SqlStatement){ SqlStatement sqlStatement = (SqlStatement) this.propertyValue; SqlWrapper sqlWrapper = sqlStatement.getSqlWrapper(); String sql = sqlWrapper.getSql(); sb.append(sql); parameters.putAll(sqlWrapper.getParameters()); } else { String parameterName = this.getParameterName(this.tableName, this.columnName); sb.append(parameterName); if (this.conditionType == ConditionType.IN || this.conditionType == ConditionType.NOT_IN){ if (this.propertyValue.getClass().isArray()){ StringBuilder sbValue = new StringBuilder(); for (int i=0; i
0){ sbValue.append(","); } sbValue.append(Array.get(this.propertyValue, i)); } parameters.put(parameterName, this.getPropertyValue(this.propertyValue).toString()); } else { parameters.put(parameterName, this.getPropertyValue(this.propertyValue)); } } else { parameters.put(parameterName, this.getPropertyValue(this.propertyValue)); } } if (this.conditionType == ConditionType.IN || this.conditionType == ConditionType.NOT_IN){ sb.append(")"); } this.setSqlWrapper(new SqlWrapper(sb.toString(), parameters)); } private Object getPropertyValue(Object propertyValue){ if (propertyValue instanceof BaseExtEnum){ return ((BaseExtEnum) propertyValue).getValue(); } else { return propertyValue; } }}
package cw.frame.mybatisext.provider.mysql.statement;import cw.frame.mybatisext.base.BaseSqlStatement;import cw.frame.mybatisext.base.SqlWrapper;public class SingleGroupStatement extends BaseSqlStatement {    private String columnName;    private String tableName = "";    private SqlWrapper sqlWrapper;    public SingleGroupStatement(String columnName){        this.columnName = columnName;    }    public SingleGroupStatement(String columnName, String tableName){        this.columnName = columnName;        this.tableName = tableName;    }    @Override    protected void prepare(){        StringBuilder sb = new StringBuilder();        sb.append(this.tableName).append(".`");        sb.append(this.columnName).append("`");        this.setSqlWrapper(new SqlWrapper(sb.toString()));    }}
package cw.frame.mybatisext.provider.mysql.statement;import cw.frame.mybatisext.base.BaseSqlStatement;import cw.frame.mybatisext.base.SqlWrapper;import cw.frame.mybatisext.enumeration.OrderType;public class SingleOrderStatement extends BaseSqlStatement {    private String columnName;    private String tableName = "";    private OrderType orderType = OrderType.DESCENDING;    private SqlWrapper sqlWrapper;    public SingleOrderStatement(String columnName){        this.columnName = columnName;    }    public SingleOrderStatement(String columnName, String tableName){        this.columnName = columnName;        this.tableName = tableName;    }    public SingleOrderStatement(String columnName, OrderType orderType){        this.columnName = columnName;        this.orderType = orderType;    }    public SingleOrderStatement(String columnName, OrderType orderType, String tableName){        this.columnName = columnName;        this.orderType = orderType;        this.tableName = tableName;    }    @Override    protected void prepare(){        StringBuilder sb = new StringBuilder();        sb.append(this.tableName).append(".`");        sb.append(this.columnName).append("`");        if (this.orderType == OrderType.DESCENDING){            sb.append(" desc");        }        this.setSqlWrapper(new SqlWrapper(sb.toString()));    }}
package cw.frame.mybatisext.provider.mysql.statement;import cw.frame.mybatisext.base.BaseSqlStatement;import cw.frame.mybatisext.SqlStatement;import cw.frame.mybatisext.base.SqlWrapper;import java.util.ArrayList;import java.util.List;public class MutiSqlStatement extends BaseSqlStatement {    private List
statements; private String joinStr; public MutiSqlStatement(String joinStr){ this.statements = new ArrayList
(); this.joinStr = joinStr; } public MutiSqlStatement(List
statements, String joinStr){ this.statements = statements; this.joinStr = joinStr; } public MutiSqlStatement addStatement(SqlStatement statement){ this.statements.add(statement); this.unsetSqlWrapper(); return this; } @Override protected void prepare(){ SqlWrapper wrapper = this.combineSqlWrappers(this.statements, this.joinStr); this.setSqlWrapper(wrapper); }}

MutiSqlStatement其实就是多个查询对象的集合,并把每个查询对象通过指定的连接字符串进行连接,参数进行合并

MysqlStatement

最后,为了方便用户编写sql,不用过多关心以上那些类,创建了一个MysqlStatement类,同样继承了BaseSqlStatement

package cw.frame.mybatisext.provider.mysql;import cw.frame.mybatisext.SqlStatement;import cw.frame.mybatisext.base.BaseSqlStatement;import cw.frame.mybatisext.base.ResultMap;import cw.frame.mybatisext.base.SqlWrapper;import cw.frame.mybatisext.base.TableIndentityProvider;import cw.frame.mybatisext.base.entity.RelationshipInfo;import cw.frame.mybatisext.base.entity.TableInfo;import cw.frame.mybatisext.base.entity.BaseExtEntity;import cw.frame.mybatisext.enumeration.ConditionType;import cw.frame.mybatisext.enumeration.JoinType;import cw.frame.mybatisext.enumeration.OrderType;import cw.frame.mybatisext.provider.mysql.statement.*;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class MySqlStatement extends BaseSqlStatement {    private Class
entityClass; private TableInfo tableInfo; private TableIndentityProvider tableIndentityProvider; private OperateType operateType; private SelectStatement selectStatement = null; private List
selectSubMySqlStatements = null; private MutiSqlStatement joinStatements = null; private MutiSqlStatement conditionStatemennts = null; private MutiSqlStatement orderStatemennts = null; private MutiSqlStatement groupStatemennts = null; private MutiSqlStatement havingStatemennts = null; private String limitString = ""; private List
updateSetItems = new ArrayList
(); public static MySqlStatement createSelectStatement(Class
entityClass){ return new MySqlStatement(entityClass, OperateType.SELECT); } public static MySqlStatement createUpdateStatement(Class
entityClass){ return new MySqlStatement(entityClass, OperateType.UPDATE); } public static MySqlStatement createDeleteStatement(Class
entityClass){ return new MySqlStatement(entityClass, OperateType.DELETE); } public MySqlStatement(Class
entityClass, TableIndentityProvider tableIndentityProvider){ this.init(entityClass, tableIndentityProvider); this.operateType = OperateType.SELECT; } private MySqlStatement(Class
entityClass, OperateType operateType){ this.init(entityClass, new TableIndentityProvider()); this.operateType = operateType; } public SelectStatement getSelectStatement() { return this.selectStatement; } public MySqlStatement select(String... propertyNames){ this.selectStatement.select(propertyNames); return this; } public MySqlStatement selectAs(String propertyName, String resultPropertyName){ this.selectStatement.selectAs(propertyName, resultPropertyName); return this; } public MySqlStatement selectAs(Map
propertyNameMap){ this.selectStatement.selectAs(propertyNameMap); return this; } public MySqlStatement set(String propertyName, Object propertyValue){ this.updateSetItems.add(new UpdateSetItem(propertyName, propertyValue)); return this; } /** * set a.name = b.name * @param propertyName * @param subQuery * @param subPropertyName * @return */ public MySqlStatement set(String propertyName, MySqlStatement subQuery, String subPropertyName){ this.updateSetItems.add(new UpdateSetItem(propertyName, subQuery.getSelectStatement().getAliasTableName(), subPropertyName)); return this; } public MySqlStatement set(Map
propertyMap){ for (String propertyName : propertyMap.keySet()){ this.updateSetItems.add(new UpdateSetItem(propertyName, propertyMap.get(propertyName))); } return this; } public MySqlStatement join(Class
classType, JoinType joinType, String fromPropertyName, String toPropertyName){ SingleJoinStatement singleJoinStatement = this.getSingleJoinStatement(classType, joinType); singleJoinStatement.setRelationship(fromPropertyName, toPropertyName); return this; } public MySqlStatement join(Class
classType, JoinType joinType, Map
relationshipMap){ SingleJoinStatement singleJoinStatement = this.getSingleJoinStatement(classType, joinType); for (String fromPropertyName : relationshipMap.keySet()){ singleJoinStatement.setRelationship(fromPropertyName, relationshipMap.get(fromPropertyName)); } return this; } public MySqlStatement join(MySqlStatement subQuery, JoinType joinType, String fromPropertyName, String toPropertyName, boolean joinByQuery, String relationshipPropertyName){ if (joinByQuery){ SingleJoinStatement statement = this.getSingleJoinStatement(subQuery, joinType); statement.setRelationship(fromPropertyName, toPropertyName); } else { SingleJoinStatement singleJoinStatement = this.getSingleJoinStatement(subQuery.getSelectStatement(), joinType); singleJoinStatement.setRelationship(fromPropertyName, toPropertyName); } if (this.selectSubMySqlStatements == null){ this.selectSubMySqlStatements = new ArrayList
(); } this.selectSubMySqlStatements.add(subQuery); this.getResultMap().addSubResultMap(subQuery.getResultMap(), relationshipPropertyName); return this; } public MySqlStatement join(MySqlStatement subQuery, JoinType joinType, Map
relationshipMap, boolean joinByQuery){ SingleJoinStatement singleJoinStatement; if (joinByQuery){ singleJoinStatement = this.getSingleJoinStatement(subQuery, joinType); } else { singleJoinStatement = this.getSingleJoinStatement(subQuery.getSelectStatement(), joinType); } for (String fromPropertyName : relationshipMap.keySet()){ singleJoinStatement.setRelationship(fromPropertyName, relationshipMap.get(fromPropertyName)); } return this; } public MySqlStatement where(String propertyName, ConditionType conditionType, Object value){ this.setCondition(this.selectStatement, propertyName, conditionType, value); return this; } public MySqlStatement where(MySqlStatement subQuery, String propertyName, ConditionType conditionType, Object value){ this.setCondition(subQuery.getSelectStatement(), propertyName, conditionType, value); return this; } public MySqlStatement orderBy(String propertyName, OrderType orderType){ this.setOrderBy(this.selectStatement, propertyName, orderType); return this; } public MySqlStatement orderBy(MySqlStatement subQuery, String propertyName, OrderType orderType){ this.setOrderBy(subQuery.getSelectStatement(), propertyName, orderType); return this; } public MySqlStatement groupBy(String propertyName){ this.setGroupBy(this.selectStatement, propertyName); return this; } public MySqlStatement groupBy(MySqlStatement subQuery, String propertyName){ this.setGroupBy(subQuery.getSelectStatement(), propertyName); return this; } public MySqlStatement having(String expression, ConditionType conditionType, Object value){ this.setHaving(this.selectStatement, expression, conditionType, value); return this; } public MySqlStatement having(MySqlStatement subQuery, String expression, ConditionType conditionType, Object value){ this.setHaving(subQuery.getSelectStatement(), expression, conditionType, value); return this; } public MySqlStatement limit(int limit){ return this.limit(limit, 0); } public MySqlStatement limit(int limit, int skip){ StringBuilder sb = new StringBuilder(); sb.append("limit "); if (skip > 0){ sb.append(skip).append(",").append(limit); } else { sb.append(limit); } this.limitString = sb.toString(); return this; } /** * 根据实体类型创建子查询对象,不会有查询字段返回 * @param entityClass * @return MySqlStatement */ public MySqlStatement createSubQuery(Class
entityClass){ MySqlStatement operator = new MySqlStatement(entityClass, this.tableIndentityProvider); return operator; } /** * 创建子查询对象,结果存储于@OneOne or @OneMany定义的关系字段, 采用inner join连接 * @param relationshipPropertyName 关系字段名 * @return MySqlStatement */ public MySqlStatement createSubQuery(String relationshipPropertyName){ return this.createSubQuery(relationshipPropertyName, JoinType.INNER_JOIN); } /** * 创建子查询对象,结果存储于@OneOne or @OneMany定义的关系字段 * @param relationshipPropertyName 关系字段名 * @param joinType inner/left/right join * @return MySqlStatement */ public MySqlStatement createSubQuery(String relationshipPropertyName, JoinType joinType){ RelationshipInfo relationshipInfo = this.tableInfo.getOneManyMap().getOrDefault(relationshipPropertyName, null); if (relationshipInfo == null){ relationshipInfo = this.tableInfo.getOneOneMap().getOrDefault(relationshipPropertyName, null); } if (relationshipInfo == null){ throw new IllegalArgumentException("relationshipPropertyName error: " + relationshipPropertyName); } MySqlStatement operator = new MySqlStatement(relationshipInfo.getSubTable().getTableEntityClass(), this.tableIndentityProvider); this.join(operator, joinType, relationshipInfo.getPropertyKey(), relationshipInfo.getForeignKey(), false, relationshipPropertyName); return operator; } @Override protected void prepare(){ StringBuilder sb = new StringBuilder(); Map
parameters = new HashMap
(); switch (this.operateType){ case SELECT: sb.append("select "); SqlWrapper selectSqlWrapper = this.selectStatement.getSqlWrapper(); sb.append(selectSqlWrapper.getSql()); parameters.putAll(selectSqlWrapper.getParameters()); this.setSubSelectFieldsSql(this.selectSubMySqlStatements, sb, parameters); sb.append(" from ").append(this.selectStatement.getTableInfo().getTableName()).append(" "); sb.append(this.selectStatement.getAliasTableName()); this.combineByWrapper(this.joinStatements, sb, parameters, " "); this.combineByWrapper(this.conditionStatemennts, sb, parameters, " where "); this.combineByWrapper(this.orderStatemennts, sb, parameters, " order by "); this.combineByWrapper(this.groupStatemennts, sb, parameters, " group by "); this.combineByWrapper(this.havingStatemennts, sb, parameters, " having "); if (this.limitString != null && !this.limitString.isEmpty()){ sb.append(" ").append(this.limitString); } break; case UPDATE: sb.append("update ").append(this.selectStatement.getTableInfo().getTableName()).append(" "); sb.append(this.selectStatement.getAliasTableName()); this.combineByWrapper(this.joinStatements, sb, parameters, " "); sb.append(" set "); int i=0; for (UpdateSetItem updateSetItem : this.updateSetItems){ if (i > 0){ sb.append(","); } String parameterName = this.getParameterName(this.selectStatement.getAliasTableName(), updateSetItem.getPropertyName()); sb.append(this.selectStatement.getAliasTableName()).append(".`"); sb.append(updateSetItem.getPropertyName()); sb.append("`="); if (updateSetItem.isUseTargetTableProperty()){ sb.append(updateSetItem.getTargetTableName()).append(".`"); sb.append(updateSetItem.targetPropertyName).append("`"); } else { sb.append(parameterName); parameters.put(parameterName, updateSetItem.getPropertyValue()); } i++; } this.combineByWrapper(this.conditionStatemennts, sb, parameters, " where "); break; case DELETE: sb.append("delete ").append(this.selectStatement.getAliasTableName()).append(" from ").append(this.selectStatement.getTableInfo().getTableName()).append(" "); sb.append(this.selectStatement.getAliasTableName()); this.combineByWrapper(this.joinStatements, sb, parameters, " "); this.combineByWrapper(this.conditionStatemennts, sb, parameters, " where "); break; } this.setSqlWrapper(sb.toString(), parameters); } public List
getSelectSubMySqlStatements(){ return this.selectSubMySqlStatements; } @Override public ResultMap getResultMap(){ return this.selectStatement.getResultMap(); } private void setGroupBy(SelectStatement statement, String propertyName){ String tableName = statement.getAliasTableName(); String columnName = statement.getTableInfo().getColumnByPropertyName(propertyName).getColumnName(); SingleGroupStatement groupStatement = new SingleGroupStatement(columnName, tableName); if (this.groupStatemennts == null){ this.groupStatemennts = new MutiSqlStatement(","); } this.groupStatemennts.addStatement(groupStatement); } private void setSubSelectFieldsSql(List
subMySqlStatements, StringBuilder sb, Map
parameters){ if (subMySqlStatements != null){ for (MySqlStatement operator : subMySqlStatements){ SelectStatement statement = operator.getSelectStatement(); if (statement.hasSelectFields()){ this.combineByWrapper(statement, sb, parameters, ","); } this.setSubSelectFieldsSql(operator.getSelectSubMySqlStatements(), sb, parameters); } } } private void setOrderBy(SelectStatement statement, String propertyName, OrderType orderType){ String tableName = statement.getAliasTableName(); String columnName = statement.getTableInfo().getColumnByPropertyName(propertyName).getColumnName(); SingleOrderStatement singleOrderStatement = new SingleOrderStatement(columnName, orderType, tableName); if (this.orderStatemennts == null){ this.orderStatemennts = new MutiSqlStatement(","); } this.orderStatemennts.addStatement(singleOrderStatement); } private void setCondition(SelectStatement statement, String propertyName, ConditionType conditionType, Object value){ if (this.conditionStatemennts == null){ this.conditionStatemennts = new MutiSqlStatement(" and "); } String tableName = statement.getAliasTableName(); String columnName = statement.getTableInfo().getColumnByPropertyName(propertyName).getColumnName(); SingleConditionStatement singleConditionStatement = new SingleConditionStatement(tableName, columnName, conditionType, value); this.conditionStatemennts.addStatement(singleConditionStatement); } private SingleJoinStatement getSingleJoinStatement(Class
classType, JoinType joinType){ SelectStatement statement = new SelectStatement(classType, this.tableIndentityProvider.getNextTableAsName()); return this.getSingleJoinStatement(statement, joinType); } private SingleJoinStatement getSingleJoinStatement(SelectStatement statement, JoinType joinType){ this.initJoinStatements(); SingleJoinStatement singleJoinStatement = new SingleJoinStatement(this.selectStatement, statement, joinType); this.joinStatements.addStatement(singleJoinStatement); return singleJoinStatement; } private SingleJoinStatement getSingleJoinStatement(MySqlStatement subQuery, JoinType joinType){ this.initJoinStatements(); SingleJoinStatement singleJoinStatement = new SingleJoinStatement(this.selectStatement, subQuery, joinType); this.joinStatements.addStatement(singleJoinStatement); return singleJoinStatement; } private void initJoinStatements(){ if (this.joinStatements == null){ this.joinStatements = new MutiSqlStatement(" "); } } private void setHaving(SelectStatement statement, String expression, ConditionType conditionType, Object value){ if (this.havingStatemennts == null){ this.havingStatemennts = new MutiSqlStatement(","); } SingleHavingStatement singleHavingStatement = new SingleHavingStatement(statement, expression, conditionType, value); this.havingStatemennts.addStatement(singleHavingStatement); } private void combineByWrapper(SqlStatement statement, StringBuilder sb, Map
parameters, String preStr){ if (statement != null){ sb.append(preStr); SqlWrapper wrapper = statement.getSqlWrapper(); sb.append(wrapper.getSql()); parameters.putAll(wrapper.getParameters()); } } private void init(Class
entityClass, TableIndentityProvider tableIndentityProvider){ this.entityClass = entityClass; this.tableIndentityProvider = tableIndentityProvider; this.tableInfo = TableInfo.getTableInfo(this.entityClass); this.selectStatement = new SelectStatement(this.entityClass, this.tableIndentityProvider.getNextTableAsName()); } private enum OperateType { SELECT, UPDATE, DELETE, } private class UpdateSetItem{ private String propertyName; private Object propertyValue; private String targetTableName; private String targetPropertyName; private boolean useTargetTableProperty; public UpdateSetItem(String propertyName, Object propertyValue){ this.propertyName = propertyName; this.propertyValue = propertyValue; this.useTargetTableProperty = false; } public UpdateSetItem(String propertyName, String targetTableName, String targetPropertyName){ this.propertyName = propertyName; this.targetTableName = targetTableName; this.targetPropertyName = targetPropertyName; this.useTargetTableProperty = true; } public String getPropertyName() { return propertyName; } public Object getPropertyValue() { return propertyValue; } public String getTargetPropertyName() { return targetPropertyName; } public String getTargetTableName() { return targetTableName; } public boolean isUseTargetTableProperty() { return useTargetTableProperty; } }}

查询对象就先介绍到这里,源码

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

上一篇:Mybatis(拦截器实现)通用mapper及全ORM实现(三)
下一篇:Mybatis(拦截器实现)通用mapper及全ORM实现(五)-- springboot+mybatis多数据源设置

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月20日 12时55分27秒