/// <summary> /// 解析生成删除SQL /// </summary> /// <remarks>按主键数据作为查询依据</remarks> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="dataID">主键数据</param> /// <param name="shardingKeyValue">分库分表键值对</param> /// <returns>删除SQL</returns> public SqlStatementCollection ParseDeleteSqlByID(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, string dataID, ShardingValue shardingKeyValue = null) { var sqls = new SqlStatementCollection(); var sqlSchema = new SqlStatementCollection(); var routeInfo = routeService.RouteByDataID(domainModel, dataID, shardingKeyValue); var dataIDDic = CreatePkDataDictionary(domainModel, domainModel.RootDomainObject, dataID); var dataContext = DataContextBuilder.CreateDataContext<IDictionary<string, object>>(domainModel, domainObject, DataAccessOpType.D, dataIDDic); //解析SQL语句主干接口 ParseDeleteSqlSchema(sqlSchema, domainModel, domainObject, routeInfo, dataContext); //在SqlSchema上逐表添加数据 ParseDeleteSqlDetail(sqlSchema, sqls, domainModel, domainObject, dataContext, routeInfo); var result = new SqlStatementCollection(); foreach (var tempDomainObject in domainModel.ReverseDomainObjects) { var sql = sqls.FirstOrDefault(i => i.NodeID == tempDomainObject.ID); if (sql != null) { result.Add(sql); } } return result; }
/// <summary> /// 批量删除 /// </summary> /// <remarks>按主键数据作为查询依据</remarks> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="dataID">主键数据</param> /// <param name="shardingKeyValue">分库分表键值对</param> /// <returns>删除SQL</returns> public void DeleteByIDs(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, IEnumerable <string> dataIDs, ShardingValue shardingKeyValue = null) { if (domainModel == null) { throw new ArgumentNullException("DataDeleteService.DeleteByID.domainModel"); } if (domainObject == null) { throw new ArgumentNullException("DataDeleteService.DeleteByID.domainObject"); } if (dataIDs == null || dataIDs.Count() == 0) { throw new ArgumentNullException("DataDeleteService.DeleteByID.dataIDs"); } var sqlList = new SqlStatementCollection(); foreach (var dataID in dataIDs) { var sqls = SQLBuilderFactory.CreateSQLBuilder().ParseDeleteSqlByID(domainModel, domainObject, dataID, shardingKeyValue); sqlList.AddRange(sqls); } var db = DatabaseFactory.CreateDefaultDatabase(); db.ExecuteSQLWithTransaction(sqlList); }
/// <summary> /// 根据已经解析的SqlSchema,解析生成带数据的Update语句。 /// </summary> /// <param name="sqlSchemata">已经解析的SqlSchema。</param> /// <param name="domainModel">领域对象</param> /// <param name="context">数据上下文</param> /// <returns>Insert语句集合</returns> private SqlStatementCollection ParseUpdateSqlDetail(SqlStatementCollection sqlSchemata, DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, DataContext dataContext, Dictionary<string, ShardingTarget> routeInfo) { var result = new SqlStatementCollection(); if (!dataContext.Data.ContainsKey(domainObject.ID)) { return result; } var data = dataContext.Data[domainObject.ID]; if (data == null || data.Count == 0) return result; var strategy = new UpdateSqlBuildStrategy(); for (int i = 0; i < dataContext.Data[domainObject.ID].Count; i++) { dataContext.CurrentDataIndex = i; var context = new SqlBuildingContext(domainModel, domainObject, SQLBuilderUtils.GetCurrentDbType(), dataContext); context.RouteInfo = routeInfo; var rowSqls = new SqlStatementCollection(); var sqls = sqlSchemata.Where(s => s.SqlBuildingInfo.CurrentNode.ID == domainObject.ID).ToList(); rowSqls.AddRangeClone(sqls); strategy.BuildTableSqlDetail(rowSqls, context); result.AddRange(rowSqls); } return result; }
/// <summary> /// 保存领域模型数据 /// </summary> /// <param name="domainModel">领域模型</param> /// <param name="instanceList">对象实例集合</param> /// <param name="shardingValueList">分区分表键值对集合</param> public void SaveBatch(DomainModel.Spi.DomainModel domainModel, List <object> instanceList, List <ShardingValue> shardingValueList = null) { if (domainModel == null) { throw new ArgumentNullException("SaveService.Save.domainModel"); } if (instanceList == null) { throw new ArgumentNullException("SaveService.Save.instanceList"); } var sqls = new SqlStatementCollection(); for (int i = 0; i < instanceList.Count; i++) { var currentObj = instanceList[i]; ShardingValue shardingValue = null; if (shardingValueList != null) { shardingValue = shardingValueList[i]; } var sqlstatements = SQLBuilderFactory.CreateSQLBuilder().ParseInsertSql(domainModel, currentObj, shardingValue); sqls.AddRange(sqlstatements); } var db = DatabaseFactory.CreateDefaultDatabase(); db.ExecuteSQLWithTransaction(sqls); }
/// <summary> /// 批量增加SQL语句集合的副本。 /// </summary> /// <param name="childSqlCollection">SQL语句集合。</param> public void AddRangeClone(SqlStatementCollection childSqlCollection) { foreach (var sql in childSqlCollection) { this.Add(sql.Clone() as SqlStatement); } }
private void ParseDeleteSqlDetail(SqlStatementCollection sqlSchemata, SqlStatementCollection result, DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, DataContext dataContext, Dictionary <string, ShardingTarget> routeInfo) { //构造SQL语句的条件 var strategy = new DeleteSqlBuildStrategy(); var context = new SqlBuildingContext(domainModel, domainObject, domainObject.DataObject.DataSource.DbType, dataContext); context.RouteInfo = routeInfo; var rowSqls = new SqlStatementCollection(); var sqls = sqlSchemata.Where(s => s.SqlBuildingInfo.CurrentNode.ID == domainObject.ID).ToList(); rowSqls.AddRangeClone(sqls); strategy.BuildTableSqlDetail(rowSqls, context); result.AddRange(rowSqls); //递归处理子对象 if (domainObject.ChildDomainObjects.Count == 0) { return; } foreach (var childModelObject in domainObject.ChildDomainObjects) { ParseDeleteSqlDetail(sqlSchemata, result, domainModel, childModelObject, dataContext, routeInfo); } }
/// <summary> /// 构造不包含数据的Sql(即SqlSchema)。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override SqlStatementCollection BuildTableSqlSchema(SqlBuildingContext context) { if (context == null) { throw new ArgumentNullException("SelectSqlBuildStrategy.BuildTableSqlSchema"); } var sqls = new SqlStatementCollection(); var selectStatement = SQLStatementFactory.CreateSqlStatement(SqlStatementType.Select, context.DbType) as SelectSqlStatement; selectStatement.SqlBuildingInfo.DataSource = context.DataSource; //Parsing main part of query SQL statement BuildMainFrom(selectStatement, context.CommonObject, context.Node, context.DataObject, context.TableName, context); //Parsing query fields list BuildQueryFieldList(selectStatement, context.Node, context.DataObject); //Parsing inner join clause BuildMainInnerJoin(selectStatement, context); sqls.Add(selectStatement); sqls.ShardingInfo = context.RouteInfo; return(sqls); }
/// <summary> /// 在数据库事务中执行SQL语句返回影响行数 /// </summary> /// <param name="sqls">SQL语句</param> public void ExecuteSQLWithTransaction(SqlStatementCollection sqls) { if (sqls == null) { throw new ArgumentNullException("DatabaseImpl.ExecuteSQLWithTransaction.sqls"); } var sqlGroups = sqls.GroupBy(i => i.SqlBuildingInfo.DataSource); using (var ts = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted })) try { foreach (var sqlGroup in sqlGroups) { if (sqlGroup.Count() == 0) { continue; } var dataSourceName = sqlGroup.FirstOrDefault().SqlBuildingInfo.DataSource; using (var db = GetDatabase(dataSourceName)) { foreach (var sqlstatment in sqlGroup) { var sqlString = sqlstatment.ToSQL(); try { var parameters = new List <IDbDataParameter>(); parameters = CreateParameters(db, sqlstatment, parameters); if (parameters == null || parameters.Count == 0) { db.ExecSqlStatement(sqlString); } else { db.ExecSqlStatement(sqlString, parameters.ToArray()); } } catch (Exception e) { MonitorError(e, sqlString); throw; } } } } ts.Complete(); } catch (Exception e) { MonitorError(e, new string[sqls.Count]); throw; } }
/// <summary> /// 解析生成Insert语句。 /// </summary> /// <param name="domainModel">领域模型。</param> /// <param name="instance">要插入的数据。</param> /// <param name="shardingKeyValue">分库分表键值对</param> /// <returns>Insert语句集合。</returns> public SqlStatementCollection ParseInsertSql(DomainModel.Spi.DomainModel domainModel, object instance, ShardingValue shardingKeyValue = null) { var sqls = new SqlStatementCollection(); var routeInfo = routeService.Route(domainModel, instance, shardingKeyValue); var dataContext = DataContextBuilder.CreateDataContext<object>(domainModel, domainModel.RootDomainObject, DataAccessOpType.I, instance); //解析SQL语句主干接口 ParseInsertSqlSchema(sqls, domainModel, domainModel.RootDomainObject, routeInfo); //在SqlSchema上逐表添加数据 return ParseInsertSqlDetail(sqls, domainModel, dataContext, routeInfo); }
/// <summary> /// 在SqlSchema基础上,构造包含数据的Sql。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override void BuildTableSqlDetail(SqlStatementCollection sqls, SqlBuildingContext context) { var sql = sqls.FirstOrDefault(i => i.SqlBuildingInfo.CurrentNode.ID == context.Node.ID); if (sql == null) { throw new Exception("DomainObject cannot find SqlSchema, DomainObjectID: " + context.Node.ID); } var deleteStatement = sql as DeleteSqlStatement; this.HandlingCondition(deleteStatement, context); }
/// <summary> /// 在SqlSchema基础上,构造包含数据的Sql。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override void BuildTableSqlDetail(SqlStatementCollection sqls, SqlBuildingContext context) { var sql = sqls.FirstOrDefault(x => x.SqlBuildingInfo.TableName == context.TableName); if (sql == null) return; var querySQL = sql as SelectSqlStatement; //Parsing left join clause of query SQL statement BuildSQLJoin(querySQL, context); //Parsing where clause of query SQL statement BuildSQLCondition(querySQL, context); }
/// <summary> /// 在SqlSchema基础上,构造包含数据的Sql。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override void BuildTableSqlDetail(SqlStatementCollection sqls, SqlBuildingContext context) { var sql = sqls.FirstOrDefault(x => x.SqlBuildingInfo.TableName == context.TableName); if (sql == null) { return; } var updateSql = sql as UpdateSqlStatement; this.HandlingUpdateFields(updateSql, context); this.HandlingConditionInfoAddData(updateSql, context); }
/// <summary> /// 在SqlSchema基础上,构造包含数据的Sql。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override void BuildTableSqlDetail(SqlStatementCollection sqls, SqlBuildingContext context) { var sql = sqls.FirstOrDefault(x => x.SqlBuildingInfo.TableName == context.TableName); if (sql == null) { return; } var insertStatement = sql as InsertSqlStatement; //insertStatement.SqlBuildingInfo = InitSqlBuildingInfo(context.CommonObject, context.Node, context.DataObject, context.TableName); this.HandlingFieldsAddData(insertStatement, context); }
/// <summary> /// 根据已经解析的SqlSchema,解析生成带数据的Update语句。 /// </summary> /// <param name="sqlSchemata">已经解析的SqlSchema。</param> /// <param name="domainModel">领域对象</param> /// <param name="context">数据上下文</param> /// <returns>Insert语句集合</returns> private SqlStatementCollection ParseUpdateSqlDetail(SqlStatementCollection sqlSchemata, DomainModel.Spi.DomainModel domainModel, DataContext context, Dictionary<string, ShardingTarget> routeInfo) { var result = new SqlStatementCollection(); foreach (var node in domainModel.DomainObjects) { var data = context.Data[node.ID]; if (data == null || data.Count == 0) continue; context.ResetCurrentDataIndex(); var nodeSqls = ParseUpdateSqlDetail(sqlSchemata, domainModel, node, context, routeInfo); result.AddRange(nodeSqls); } return result; }
/// <summary> /// 处理sql集合中的参数,调用底层数据访问接口,返回受影响的行数据。 /// </summary> /// <param name="sqls">待处理的SQL语句集合</param> /// <returns>受影响的行数据</returns> public void ExecuteSQLs(SqlStatementCollection sqls) { if (sqls == null) { throw new ArgumentNullException("DatabaseImpl.ExecuteSQLs.sqls"); } if (sqls.Count == 0) { return; } foreach (var sqlstatment in sqls) { using (var db = GetDatabase(sqlstatment.SqlBuildingInfo.DataSource)) { var sqlString = sqlstatment.ToSQL(); try { var parameters = new List <IDbDataParameter>(); if (sqlstatment is InsertSqlStatement) { parameters = ParameterHandlerForInsert(sqlstatment, db); } else if (sqlstatment is UpdateSqlStatement) { parameters = ParameterHandlerForUpdate(sqlstatment, db); } if (parameters == null || parameters.Count == 0) { db.ExecSqlStatement(sqlString); } else { db.ExecSqlStatement(sqlString, parameters); } } catch (Exception e) { MonitorError(e, sqlString); throw; } } } }
/// <summary> /// 构造查询SQL语句的主干结构 /// </summary> /// <param name="dataObject">数据对象</param> /// <returns>查询SQL语句的主干结构</returns> private void ParseDeleteSqlSchema(SqlStatementCollection sqlSchemata, DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, Dictionary<string, ShardingTarget> routeInfo, DataContext dataContext) { var selectStrategy = new DeleteSqlBuildStrategy(); var context = new SqlBuildingContext(domainModel, domainObject, SQLBuilderUtils.GetCurrentDbType(), dataContext); context.RouteInfo = routeInfo; var nodeSqlSchemata = selectStrategy.BuildTableSqlSchema(context); sqlSchemata.AddRange(nodeSqlSchemata); //递归处理子对象 if (domainObject.ChildDomainObjects.Count == 0) return; foreach (var childModelObject in domainObject.ChildDomainObjects) { ParseDeleteSqlSchema(sqlSchemata, domainModel, childModelObject, routeInfo, dataContext); } }
/// <summary> /// 解析生成查询SQL /// </summary> /// <remarks>按主键数据作为查询依据</remarks> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="dataID">主键数据</param> /// <param name="shardingKeyValue">分库分表键值对</param> /// <returns>查询SQL</returns> public SqlStatementCollection ParseQuerySqlByID(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, string dataID, ShardingValue shardingKeyValue = null) { var sqls = new SqlStatementCollection(); var sqlSchema = new SqlStatementCollection(); var routeInfo = routeService.RouteByDataID(domainModel, dataID, shardingKeyValue); var dataIDDic = CreatePkDataDictionary(domainModel, domainObject, dataID); var dataContext = DataContextBuilder.CreateDataContext<IDictionary<string, object>>(domainModel, domainObject, DataAccessOpType.Q, dataIDDic); //解析SQL语句主干接口 ParseQuerySqlSchema(sqlSchema, domainModel, domainObject, routeInfo, dataContext); //在SqlSchema上逐表添加数据 ParseQuerySqlDetail(sqlSchema, sqls, domainModel, domainObject, dataContext, routeInfo); return sqlSchema; }
/// <summary> /// 构造不包含数据的Sql(即SqlSchema)。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override SqlStatementCollection BuildTableSqlSchema(SqlBuildingContext context) { if (context == null) { throw new ArgumentNullException("UpdateSqlBuildStrategy.BuildTableSqlSchema"); } var sqls = new SqlStatementCollection(); var updateStatement = SQLStatementFactory.CreateSqlStatement(SqlStatementType.Update, context.DbType) as UpdateSqlStatement; updateStatement.SqlBuildingInfo.DataSource = context.DataSource; base.HandlingSqlStatement(updateStatement, context); sqls.Add(updateStatement); return(sqls); }
/// <summary> /// 构造不包含数据的Sql(即SqlSchema)。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override SqlStatementCollection BuildTableSqlSchema(SqlBuildingContext context) { if (context == null) { throw new ArgumentNullException("InsertSqlBuilder.BuildTableSqlSchema"); } var sqls = new SqlStatementCollection(); var insertStatement = SQLStatementFactory.CreateSqlStatement(SqlStatementType.Insert, context.DbType) as InsertSqlStatement; base.HandlingSqlStatement(insertStatement, context); HandlingInsertFields(insertStatement, context); insertStatement.SqlBuildingInfo.DataSource = context.DataSource; sqls.Add(insertStatement); return(sqls); }
/// <summary> /// 构造不包含数据的Sql(即SqlSchema)。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public override SqlStatementCollection BuildTableSqlSchema(SqlBuildingContext context) { if (context == null) { throw new ArgumentNullException("DeleteSqlBuildStrategy.BuildTableSqlSchema"); } var sqls = new SqlStatementCollection(); //构造DeleteSql var sql = SQLStatementFactory.CreateSqlStatement(SqlStatementType.Delete, context.DbType) as DeleteSqlStatement; base.HandlingSqlStatement(sql, context); //构造DeleteSql的删除过滤条件 this.HandlingJoin(sql, context); sqls.Add(sql); return(sqls); }
/// <summary> /// 解析生成Insert语句的主干部分。 /// </summary> /// <param name="sqlSchemata">Insert语句的主干。</param> /// <param name="co">通用中间对象。</param> /// <param name="node">通用中间对象的节点。</param> /// <returns>Insert语句的主干部分。</returns> private void ParseInsertSqlSchema(SqlStatementCollection sqlSchemata, DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, Dictionary <string, ShardingTarget> routeInfo) { var insertStrategy = new InsertSqlBuildStrategy(); var context = new SqlBuildingContext(domainModel, domainObject, domainObject.DataObject.DataSource.DbType); context.RouteInfo = routeInfo; var nodeSqlSchemata = insertStrategy.BuildTableSqlSchema(context); sqlSchemata.AddRange(nodeSqlSchemata); //递归处理子对象 if (context.Node.ChildDomainObjects.Count == 0) { return; } foreach (var childModelObject in context.Node.ChildDomainObjects) { ParseInsertSqlSchema(sqlSchemata, domainModel, childModelObject, routeInfo); } }
/// <summary> /// 解析生成Insert语句的主干部分。 /// </summary> /// <param name="sqlSchemata">Insert语句的主干。</param> /// <param name="co">通用中间对象。</param> /// <param name="node">通用中间对象的节点。</param> /// <returns>Insert语句的主干部分。</returns> private void ParseUpdateSqlSchema(SqlStatementCollection sqlSchemata, DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, Dictionary <string, ShardingTarget> routeInfo, DataContext dataContext) { var updateStrategy = new UpdateSqlBuildStrategy(); var context = new SqlBuildingContext(domainModel, domainObject, domainObject.DataObject.DataSource.DbType); context.RouteInfo = routeInfo; if (dataContext.GetCurrentDataContextItem(domainObject.ID) != null) { var nodeSqlSchemata = updateStrategy.BuildTableSqlSchema(context); sqlSchemata.AddRange(nodeSqlSchemata); } //递归处理子对象 if (context.Node.ChildDomainObjects.Count == 0) { return; } foreach (var childModelObject in context.Node.ChildDomainObjects) { ParseUpdateSqlSchema(sqlSchemata, domainModel, childModelObject, routeInfo, dataContext); } }
/// <summary> /// 解析生成查询SQL /// </summary> /// <remarks>按主键数据作为查询依据</remarks> /// <param name="domainModel">领域模型</param> /// <param name="domainObject">领域对象</param> /// <param name="filter">过滤器</param> /// <returns>查询SQL</returns> public SqlStatementCollection ParseQuerySqlByFilter(DomainModel.Spi.DomainModel domainModel, DomainModel.Spi.DomainObject domainObject, QueryFilter filter) { var sqls = new SqlStatementCollection(); return sqls; }
/// <summary> /// 在SqlSchema基础上,构造GSPAbsDBTable包含数据的Sql。 /// </summary> /// <param name="sqls">Sql语句对象集合。</param> /// <param name="context">Sql构造的上下文信息。</param> public abstract void BuildTableSqlDetail(SqlStatementCollection sqls, SqlBuildingContext context);
/// <summary> /// 执行SQL获取数据 /// </summary> /// <param name="sql">SQL语句</param> /// <returns>数据</returns> public List <DataTable> GetDataCollection(SqlStatementCollection sqls) { if (sqls == null) { throw new ArgumentNullException("DatabaseImpl.GetData.sqls"); } var dataTables = new List <DataTable>(); var sqlGroups = sqls.GroupBy(i => i.SqlBuildingInfo.DataSource); try { foreach (var sqlGroup in sqlGroups) { if (sqlGroup.Count() == 0) { continue; } var dataSourceName = sqlGroup.FirstOrDefault().SqlBuildingInfo.DataSource; using (var db = GetDatabase(dataSourceName)) { foreach (var sqlstatment in sqlGroup) { var sqlString = sqlstatment.ToSQL(); try { var parameters = new List <IDbDataParameter>(); if (sqlstatment is SelectSqlStatement) { parameters = ParameterHandlerForSelect(sqlstatment, db); } var ds = new DataSet(); if (parameters == null || parameters.Count == 0) { ds = db.ExecuteDataSet(sqlString); } else { ds = db.ExecuteDataSet(sqlString, parameters.ToArray()); } if (ds != null) { foreach (DataTable dt in ds.Tables) { dataTables.Add(dt); } } } catch (Exception e) { MonitorError(e, sqlString); throw; } } } } return(dataTables); } catch (Exception e) { MonitorError(e, new string[sqls.Count]); throw; } }