本文共 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 Mapparameters = 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 MapresultMap; 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, Mapparameters) { 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
接下来就是定义具体的查询对象了,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 SetselectPropertyNames = 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 MapjoinRelationshipMap = 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(){ Mapparameters = 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 Liststatements; 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 ListselectSubMySqlStatements = 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!