feat: initial commit - HJHA game server full source
6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
This commit is contained in:
59
MrWu/DB/DataResult.cs
Normal file
59
MrWu/DB/DataResult.cs
Normal file
@ -0,0 +1,59 @@
|
||||
/********************************
|
||||
*
|
||||
* 作者:吴隆健
|
||||
* 创建时间: 2019-06-06 16:07:29
|
||||
*
|
||||
********************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
||||
namespace MrWu.DB {
|
||||
/// <summary>
|
||||
/// 定时器执行得到的数据结果集
|
||||
/// </summary>
|
||||
public class DataResult {
|
||||
/// <summary>
|
||||
/// 参数
|
||||
/// </summary>
|
||||
public Dictionary<string, object> pms { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回的数据集
|
||||
/// </summary>
|
||||
public DataSet data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据结果集
|
||||
/// </summary>
|
||||
public DataResult() { }
|
||||
|
||||
/// <summary>
|
||||
/// 数据结果集
|
||||
/// </summary>
|
||||
/// <param name="pms"></param>
|
||||
public DataResult(Dictionary<string, object> pms) {
|
||||
this.pms = pms;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据结果集
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public DataResult(DataSet data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据结果集
|
||||
/// </summary>
|
||||
/// <param name="pms">存储过程参数</param>
|
||||
/// <param name="data">返回的数据</param>
|
||||
public DataResult(Dictionary<string, object> pms, DataSet data) {
|
||||
this.pms = pms;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
7
MrWu/DB/DbConst.cs
Normal file
7
MrWu/DB/DbConst.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace MrWu.DB
|
||||
{
|
||||
public static class DbConst
|
||||
{
|
||||
public const string RowsAffected = "RowsAffected";
|
||||
}
|
||||
}
|
||||
31
MrWu/DB/IConnectionPool.cs
Normal file
31
MrWu/DB/IConnectionPool.cs
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 作者:吴隆健
|
||||
* 日期: 2019-04-23
|
||||
* 时间: 13:17
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using MrWu.Model;
|
||||
|
||||
namespace MrWu.DB {
|
||||
/// <summary>
|
||||
/// 连接池 T是链接类型
|
||||
/// </summary>
|
||||
public interface IConnectionPool<T> : IPool<T>{
|
||||
/// <summary>
|
||||
/// 链接字符串
|
||||
/// </summary>
|
||||
string connecStr {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 链接池
|
||||
/// </summary>
|
||||
ConcurrentQueue<T> conns {
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
||||
45
MrWu/DB/IProdureParameter.cs
Normal file
45
MrWu/DB/IProdureParameter.cs
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 作者:吴隆健
|
||||
* 日期: 2019-04-23
|
||||
* 时间: 13:17
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace MrWu.DB {
|
||||
/// <summary>
|
||||
/// 存储过程参数 T是指令类型
|
||||
/// </summary>
|
||||
public interface IProdureParameter<T> : IDisposable {
|
||||
|
||||
/// <summary>
|
||||
/// 数据库名称
|
||||
/// </summary>
|
||||
string dbName {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sql命令
|
||||
/// </summary>
|
||||
T command {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
Exception exception {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
bool isException {
|
||||
get;
|
||||
}
|
||||
}
|
||||
}
|
||||
49
MrWu/DB/ISqlAloneParameter.cs
Normal file
49
MrWu/DB/ISqlAloneParameter.cs
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 作者:吴隆健
|
||||
* 日期: 2019-04-23
|
||||
* 时间: 13:21
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
|
||||
namespace MrWu.DB {
|
||||
/// <summary>
|
||||
/// sql参数 T是数据类型
|
||||
/// </summary>
|
||||
public interface ISqlAloneParameter<T> {
|
||||
/// <summary>
|
||||
/// 参数名称
|
||||
/// </summary>
|
||||
string paramname {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 参数值
|
||||
/// </summary>
|
||||
object paramvalue {
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 参数类型
|
||||
/// </summary>
|
||||
T type {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 值的长度
|
||||
/// </summary>
|
||||
int valueLength {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Direction
|
||||
/// </summary>
|
||||
ParameterDirection Direction { get; set; }
|
||||
}
|
||||
}
|
||||
169
MrWu/DB/ISqlEx.cs
Normal file
169
MrWu/DB/ISqlEx.cs
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 作者:吴隆健
|
||||
* 日期: 2019-04-23
|
||||
* 时间: 13:17
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MrWu.DB {
|
||||
/// <summary>
|
||||
/// sql链接 T是sql的链接类型 K是指令类型 M是参数类型
|
||||
/// </summary>
|
||||
public interface ISqlEx<T,K,M,N> {
|
||||
/// <summary>
|
||||
/// 链接池
|
||||
/// </summary>
|
||||
IConnectionPool<T> connPool {
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个连接
|
||||
/// </summary>
|
||||
/// <param name="dbbase"></param>
|
||||
/// <returns></returns>
|
||||
T GetConnection(string dbbase);
|
||||
|
||||
/// <summary>
|
||||
/// 开始执行存储过程
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="procedure">存储过程名称</param>
|
||||
/// <returns></returns>
|
||||
IProdureParameter<K> BeginProcedure(string dbbase,string procedure);
|
||||
|
||||
/// <summary>
|
||||
/// 给存储过程添加参数
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程命令</param>
|
||||
/// <param name="paramName">参数名</param>
|
||||
/// <param name="value">参数值</param>
|
||||
/// <param name="type">参数类型</param>
|
||||
/// <param name="pd">参数种类</param>
|
||||
void AddParam(IProdureParameter<K> spp,string paramName,object value,M type,ParameterDirection pd = ParameterDirection.Input);
|
||||
|
||||
/// <summary>
|
||||
/// 提交存储过程
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程命令</param>
|
||||
/// <param name="ds">查询的结果集</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>执行存储过程所有参数</returns>
|
||||
Dictionary<string, object> SubProcedure(IProdureParameter<K> spp, DataSet ds = null,int againCount = -1);
|
||||
|
||||
/// <summary>
|
||||
/// 执行sql语句
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="sql">sql语句</param>
|
||||
/// <param name="sqlparams">sql的额外参数</param>
|
||||
/// <param name="ds">查询的结果集</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>受影响的行数</returns>
|
||||
int ExecuteSql(string dbbase,string sql,IEnumerable<N> sqlparams = null,DataSet ds = null,int againCount = -1);
|
||||
|
||||
/// <summary>
|
||||
/// 执行一个普通的查询
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="table">数据库表名</param>
|
||||
/// <param name="column">查询的列</param>
|
||||
/// <param name="where">查询条件</param>
|
||||
/// <param name="count">查询的行数</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <param name="sqlparams">sql参数</param>
|
||||
/// <returns>查询的结果集</returns>
|
||||
DataTable Select(string dbbase, string table, string[] column = null, string where = null, int count = 0,int againCount = -1, IEnumerable<N> sqlparams = null);
|
||||
|
||||
/// <summary>
|
||||
/// 执行cmd
|
||||
/// </summary>
|
||||
/// <param name="cmd">数据库指令</param>
|
||||
/// <param name="dbname">数据库名称</param>
|
||||
/// <param name="ds">结果集</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>受影响的行数</returns>
|
||||
int Execute(K cmd,string dbname, DataSet ds = null,int againCount = -1);
|
||||
|
||||
/// <summary>
|
||||
/// 执行一个事务
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <returns>存储过程指令</returns>
|
||||
IProdureParameter<K> BeginTransaction(string dbbase);
|
||||
|
||||
/// <summary>
|
||||
/// 为事务添加sql语句
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程指令</param>
|
||||
/// <param name="sql">sql语句</param>
|
||||
/// <param name="sqlparams">额外参数</param>
|
||||
int TransactionAddSql(IProdureParameter<K> spp, string sql, List<ISqlAloneParameter<M>> sqlparams = null);
|
||||
|
||||
/// <summary>
|
||||
/// 提交一个事务
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程指令</param>
|
||||
/// <returns></returns>
|
||||
bool SubTransaction(IProdureParameter<K> spp);
|
||||
|
||||
/// <summary>
|
||||
/// 回滚事务
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
void RollbackTransaction(IProdureParameter<K> spp);
|
||||
|
||||
#region 异步方法
|
||||
|
||||
/// <summary>
|
||||
/// 异步提交存储过程
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程命令</param>
|
||||
/// <param name="ds">查询的结果集</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>执行存储过程所有参数</returns>
|
||||
Task<Dictionary<string, object>> SubProcedureAsync(IProdureParameter<K> spp, DataSet ds = null, int againCount = -1);
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行sql语句
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="sql">sql语句</param>
|
||||
/// <param name="sqlparams">sql的额外参数</param>
|
||||
/// <param name="ds">查询的结果集</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>受影响的行数</returns>
|
||||
Task<int> ExecuteSqlAsync(string dbbase, string sql, IEnumerable<N> sqlparams = null, DataSet ds = null, int againCount = -1);
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行一个普通的查询
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="table">数据库表名</param>
|
||||
/// <param name="column">查询的列</param>
|
||||
/// <param name="where">查询条件</param>
|
||||
/// <param name="count">查询的行数</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <param name="sqlparams">sql参数</param>
|
||||
/// <returns>查询的结果集</returns>
|
||||
Task<DataTable> SelectAsync(string dbbase, string table, string[] column = null, string where = null, int count = 0, int againCount = -1, IEnumerable<N> sqlparams = null);
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行cmd
|
||||
/// </summary>
|
||||
/// <param name="cmd">数据库指令</param>
|
||||
/// <param name="dbname">数据库名称</param>
|
||||
/// <param name="ds">结果集</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>受影响的行数</returns>
|
||||
Task<int> ExecuteAsync(K cmd, string dbname, DataSet ds = null, int againCount = -1);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
600
MrWu/DB/MMSSQL.cs
Normal file
600
MrWu/DB/MMSSQL.cs
Normal file
@ -0,0 +1,600 @@
|
||||
/*
|
||||
* 由SharpDevelop创建。
|
||||
* 用户:吴隆健
|
||||
* 日期: 2019-03-21
|
||||
* 时间: 10:07
|
||||
*
|
||||
*/
|
||||
|
||||
#if MMSQL
|
||||
|
||||
using MrWu.Model;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MrWu.DB
|
||||
{
|
||||
/// <summary>
|
||||
/// sqlServer 操作
|
||||
/// </summary>
|
||||
public class MMSSQL : SqlEx<SqlConnection, SqlCommand, SqlDbType, SqlParameter>
|
||||
{
|
||||
#region 属性与字段
|
||||
|
||||
/// <summary>
|
||||
/// 链接池
|
||||
/// </summary>
|
||||
public override IConnectionPool<SqlConnection> connPool
|
||||
{
|
||||
get => null; // _ConnPool;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string connectionString { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region CTOR
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
public MMSSQL(SqlConfig config)
|
||||
{
|
||||
//this._ConnPool = new ConnectionPool(config);
|
||||
this.connectionString =
|
||||
string.Format("Data Source={0},{1};user id={2};pwd={3};Max Pool Size=512;initial catalog=", config.host,
|
||||
config.port, config.username, config.pwd);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL存储过程
|
||||
|
||||
/// <summary>
|
||||
/// 开始存储过程
|
||||
/// </summary>
|
||||
/// <param name="dbbase">存储过程所在的数据库</param>
|
||||
/// <param name="procedure">存储过程名</param>
|
||||
/// <returns></returns>
|
||||
public override IProdureParameter<SqlCommand> BeginProcedure(string dbbase, string procedure)
|
||||
{
|
||||
//if (_ConnPool == null)
|
||||
// throw new Exception("you dont hava init");
|
||||
|
||||
SqlCommand cmd = new SqlCommand(procedure); //, GetConnection(dbbase)
|
||||
SqlProcedureParameter result = new SqlProcedureParameter(cmd, dbbase);
|
||||
//存储过程模式
|
||||
cmd.CommandType = System.Data.CommandType.StoredProcedure;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加参数
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程查询键</param>
|
||||
/// <param name="paramName">参数名</param>
|
||||
/// <param name="value">参数值</param>
|
||||
/// <param name="type">参数类型</param>
|
||||
/// <param name="pd">参数种类</param>
|
||||
public override void AddParam(IProdureParameter<SqlCommand> spp, string paramName, object value, SqlDbType type,
|
||||
ParameterDirection pd = ParameterDirection.Input)
|
||||
{
|
||||
if (spp == null || spp.command == null)
|
||||
throw new Exception("param spp null");
|
||||
SqlParameter param = spp.command.Parameters.Add(paramName, type);
|
||||
param.Direction = pd;
|
||||
if (value == null)
|
||||
param.Value = DBNull.Value;
|
||||
else
|
||||
param.Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交存储过程
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程查询键</param>
|
||||
/// <param name="ds">如果 存储过程中有查询表操作,则需要传递DataSet实例</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>参数值,输出参数从字典中获取</returns>
|
||||
public override Dictionary<string, object> SubProcedure(IProdureParameter<SqlCommand> spp, DataSet ds = null,
|
||||
int againCount = -1)
|
||||
{
|
||||
if (spp == null || spp.command == null)
|
||||
throw new Exception("param spp null");
|
||||
|
||||
int cnt = Execute(spp.command, spp.dbName, ds, againCount);
|
||||
|
||||
Dictionary<string, object> dic = new Dictionary<string, object>();
|
||||
var pms = spp.command.Parameters;
|
||||
int len = pms.Count;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
dic.Add(pms[i].ParameterName, pms[i].Value);
|
||||
}
|
||||
|
||||
if (!dic.ContainsKey(DbConst.RowsAffected))
|
||||
{
|
||||
dic[DbConst.RowsAffected] = cnt;
|
||||
}
|
||||
|
||||
spp.Dispose();
|
||||
return dic;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL Query
|
||||
|
||||
/// <summary>
|
||||
/// 执行sql语句
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库</param>
|
||||
/// <param name="sql">sql语句</param>
|
||||
/// <param name="sqlparams">单独设置sql语句的参数 一般用来设置二进制参数 或者过长的文字字符串</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <param name="ds">如果是查询 使用传入ds实例</param>
|
||||
public override int ExecuteSql(string dbbase, string sql, IEnumerable<SqlParameter> sqlparams = null,
|
||||
DataSet ds = null, int againCount = -1)
|
||||
{
|
||||
SqlCommand cmd = new SqlCommand(sql); //, GetConnection(dbbase)
|
||||
cmd.CommandType = CommandType.Text;
|
||||
|
||||
if (sqlparams != null)
|
||||
{
|
||||
//int len = sqlparams.Count();
|
||||
//for (int i = 0; i < len; i++) {
|
||||
// ISqlAloneParameter<SqlDbType> sap = sqlparams[i];
|
||||
// cmd.Parameters.Add(sap.paramname, sap.type, sap.valueLength);
|
||||
// cmd.Parameters[sap.paramname].Value = sap.paramvalue;
|
||||
//}
|
||||
foreach (var param in sqlparams)
|
||||
{
|
||||
cmd.Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
|
||||
return Execute(cmd, dbbase, ds, againCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 普通查询一个表
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="table">表名</param>
|
||||
/// <param name="column">列名</param>
|
||||
/// <param name="where">条件</param>
|
||||
/// <param name="count">查询的数量</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <param name="sqlparams">sql参数</param>
|
||||
/// <returns>查询到的表</returns>
|
||||
public override DataTable Select(string dbbase, string table, string[] column = null, string where = null,
|
||||
int count = 0, int againCount = -1, IEnumerable<SqlParameter> sqlparams = null)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("select ");
|
||||
if (count > 0)
|
||||
{
|
||||
sb.Append(string.Format("Top {0} ", count));
|
||||
}
|
||||
|
||||
if (column != null && column.Length > 0)
|
||||
{
|
||||
int len = column.Length;
|
||||
for (int i = len - 1; i >= 0; i--)
|
||||
{
|
||||
sb.Append(column[i]);
|
||||
if (i > 0)
|
||||
sb.Append(",");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("*");
|
||||
}
|
||||
|
||||
sb.Append(" from ");
|
||||
sb.Append(table);
|
||||
if (!string.IsNullOrEmpty(where))
|
||||
{
|
||||
sb.Append(" where ");
|
||||
sb.Append(where);
|
||||
}
|
||||
|
||||
DataSet ds = new DataSet();
|
||||
|
||||
//Debug.Debug.Info("sql:" + sb.ToString());
|
||||
ExecuteSql(dbbase, sb.ToString(), sqlparams, ds, againCount);
|
||||
if (ds.Tables == null || ds.Tables.Count == 0)
|
||||
return null;
|
||||
return ds.Tables[0];
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL 事务
|
||||
|
||||
/// <summary>
|
||||
/// 开始一个事务
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库</param>
|
||||
/// <returns></returns>
|
||||
public override IProdureParameter<SqlCommand> BeginTransaction(string dbbase)
|
||||
{
|
||||
SqlCommand cmd = new SqlCommand();
|
||||
SqlProcedureParameter spp = new SqlProcedureParameter(cmd, dbbase);
|
||||
try
|
||||
{
|
||||
var conn = GetConnection(dbbase);
|
||||
{
|
||||
conn.Open();
|
||||
cmd.Connection = conn;
|
||||
cmd.Connection.ChangeDatabase(dbbase);
|
||||
cmd.Transaction = cmd.Connection.BeginTransaction(); //开始事务,还可以设置隔离等级
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
spp.exception = e;
|
||||
if (cmd.Connection != null)
|
||||
{
|
||||
cmd.Connection.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return spp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事务添加sql语句
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="sqlparams"></param>
|
||||
public override int TransactionAddSql(IProdureParameter<SqlCommand> spp, string sql,
|
||||
List<ISqlAloneParameter<SqlDbType>> sqlparams = null)
|
||||
{
|
||||
if (spp.isException)
|
||||
return 0;
|
||||
try
|
||||
{
|
||||
SqlCommand cmd = spp.command;
|
||||
cmd.CommandText = sql;
|
||||
|
||||
cmd.Parameters.Clear();
|
||||
if (sqlparams != null)
|
||||
{
|
||||
int len = sqlparams.Count;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
ISqlAloneParameter<SqlDbType> sap = sqlparams[i];
|
||||
if (sap.valueLength > 0)
|
||||
cmd.Parameters.Add(sap.paramname, sap.type, sap.valueLength);
|
||||
else
|
||||
cmd.Parameters.Add(sap.paramname, sap.type);
|
||||
cmd.Parameters[sap.paramname].Value = sap.paramvalue;
|
||||
cmd.Parameters[sap.paramname].Direction = sap.Direction;
|
||||
}
|
||||
}
|
||||
|
||||
var result = cmd.ExecuteNonQuery();
|
||||
if (sqlparams != null)
|
||||
{
|
||||
for (int i = 0; i < sqlparams.Count; i++)
|
||||
{
|
||||
sqlparams[i].paramvalue = cmd.Parameters[i].Value;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
spp.command.Transaction.Rollback(); //事务步骤异常,主动回滚事务
|
||||
spp.exception = e;
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交事务
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
/// <returns>true 表示提交成功 false 表示提交失败</returns>
|
||||
public override bool SubTransaction(IProdureParameter<SqlCommand> spp)
|
||||
{
|
||||
using (spp)
|
||||
{
|
||||
using (spp.command)
|
||||
{
|
||||
using (spp.command.Connection)
|
||||
{
|
||||
using (spp.command.Transaction)
|
||||
{
|
||||
try
|
||||
{
|
||||
spp.command.Transaction.Commit();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
spp.exception = e;
|
||||
spp.command.Transaction.Rollback();
|
||||
}
|
||||
|
||||
return spp.exception == null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回滚事务
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
public override void RollbackTransaction(IProdureParameter<SqlCommand> spp)
|
||||
{
|
||||
try
|
||||
{
|
||||
spp.command.Transaction.Rollback(); //事务步骤异常,主动回滚事务
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
|
||||
spp.command.Transaction?.Dispose();
|
||||
spp.command.Connection?.Dispose();
|
||||
spp.command.Dispose();
|
||||
spp.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 异步方法
|
||||
|
||||
/// <summary>
|
||||
/// 异步提交存储过程
|
||||
/// </summary>
|
||||
public override async Task<Dictionary<string, object>> SubProcedureAsync(IProdureParameter<SqlCommand> spp,
|
||||
DataSet ds = null, int againCount = -1)
|
||||
{
|
||||
if (spp == null || spp.command == null)
|
||||
throw new Exception("param spp null");
|
||||
|
||||
int cnt = await ExecuteAsync(spp.command, spp.dbName, ds, againCount);
|
||||
|
||||
Dictionary<string, object> dic = new Dictionary<string, object>();
|
||||
var pms = spp.command.Parameters;
|
||||
int len = pms.Count;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
dic.Add(pms[i].ParameterName, pms[i].Value);
|
||||
}
|
||||
|
||||
if (!dic.ContainsKey(DbConst.RowsAffected))
|
||||
{
|
||||
dic[DbConst.RowsAffected] = cnt;
|
||||
}
|
||||
|
||||
spp.Dispose();
|
||||
return dic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行sql语句
|
||||
/// </summary>
|
||||
public override async Task<int> ExecuteSqlAsync(string dbbase, string sql,
|
||||
IEnumerable<SqlParameter> sqlparams = null, DataSet ds = null, int againCount = -1)
|
||||
{
|
||||
SqlCommand cmd = new SqlCommand(sql);
|
||||
cmd.CommandType = CommandType.Text;
|
||||
|
||||
if (sqlparams != null)
|
||||
{
|
||||
foreach (var param in sqlparams)
|
||||
{
|
||||
cmd.Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
|
||||
return await ExecuteAsync(cmd, dbbase, ds, againCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步查询
|
||||
/// </summary>
|
||||
public override async Task<DataTable> SelectAsync(string dbbase, string table, string[] column = null,
|
||||
string where = null, int count = 0, int againCount = -1, IEnumerable<SqlParameter> sqlparams = null)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("select ");
|
||||
if (count > 0)
|
||||
{
|
||||
sb.Append(string.Format("Top {0} ", count));
|
||||
}
|
||||
|
||||
if (column != null && column.Length > 0)
|
||||
{
|
||||
int len = column.Length;
|
||||
for (int i = len - 1; i >= 0; i--)
|
||||
{
|
||||
sb.Append(column[i]);
|
||||
if (i > 0)
|
||||
sb.Append(",");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("*");
|
||||
}
|
||||
|
||||
sb.Append(" from ");
|
||||
sb.Append(table);
|
||||
if (!string.IsNullOrEmpty(where))
|
||||
{
|
||||
sb.Append(" where ");
|
||||
sb.Append(where);
|
||||
}
|
||||
|
||||
DataSet ds = new DataSet();
|
||||
|
||||
await ExecuteSqlAsync(dbbase, sb.ToString(), sqlparams, ds, againCount);
|
||||
if (ds.Tables == null || ds.Tables.Count == 0)
|
||||
return null;
|
||||
return ds.Tables[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行cmd
|
||||
/// </summary>
|
||||
public override async Task<int> ExecuteAsync(SqlCommand cmd, string dbname, DataSet ds = null,
|
||||
int againCount = -1)
|
||||
{
|
||||
int result = 0;
|
||||
int exceCnt = 0;
|
||||
if (againCount < 0)
|
||||
againCount = errorTryAgainCount;
|
||||
|
||||
while (exceCnt <= againCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
using (var conn = GetConnection(dbname))
|
||||
{
|
||||
await conn.OpenAsync();
|
||||
cmd.Connection = conn;
|
||||
cmd.Connection.ChangeDatabase(dbname);
|
||||
if (ds == null)
|
||||
{
|
||||
result = await cmd.ExecuteNonQueryAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var sda = new SqlDataAdapter())
|
||||
{
|
||||
sda.SelectCommand = cmd;
|
||||
sda.Fill(ds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (exceCnt < againCount)
|
||||
{
|
||||
Debug.Debug.Warning("数据库异步执行错误重试次数:" + exceCnt + ",错误类型:" + e.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
int time = errorAgainTime + errorAgainTimeInc * exceCnt;
|
||||
exceCnt++;
|
||||
await Task.Delay(time);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region SQL Common
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个连接
|
||||
/// </summary>
|
||||
/// <param name="dbbase"></param>
|
||||
/// <returns></returns>
|
||||
public override SqlConnection GetConnection(string dbbase) => new SqlConnection(connectionString + dbbase);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 执行sql命令
|
||||
/// </summary>
|
||||
/// <param name="cmd"></param>
|
||||
/// <param name="dbname">数据库名称</param>
|
||||
/// <param name="ds"></param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
public override int Execute(SqlCommand cmd, string dbname, DataSet ds = null, int againCount = -1)
|
||||
{
|
||||
int result = 0;
|
||||
int exceCnt = 0;
|
||||
if (againCount < 0)
|
||||
againCount = errorTryAgainCount;
|
||||
|
||||
while (exceCnt <= againCount)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (cmd)
|
||||
{
|
||||
// Debug.Debug.Info("链接字符串:" + connectionString);
|
||||
using (var conn = GetConnection(dbname))
|
||||
{
|
||||
conn.Open();
|
||||
cmd.Connection = conn;
|
||||
cmd.Connection.ChangeDatabase(dbname);
|
||||
if (ds == null)
|
||||
{
|
||||
result = cmd.ExecuteNonQuery();
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var sda = new SqlDataAdapter())
|
||||
{
|
||||
//一定要关闭,不然下次执行报错;
|
||||
sda.SelectCommand = cmd;
|
||||
sda.Fill(ds); //调用会自动执行 ExecuteNonQuery(); 不要重复调用,很容易出错!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (exceCnt < againCount)
|
||||
{
|
||||
Debug.Debug.Warning("数据库执行错误重试次数:" + exceCnt + ",错误类型:" + e.Message);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
int time = errorAgainTime + errorAgainTimeInc * exceCnt;
|
||||
exceCnt++; //执行次数+1
|
||||
Thread.Sleep(time);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
27
MrWu/DB/MethodType.cs
Normal file
27
MrWu/DB/MethodType.cs
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 作者:吴隆健
|
||||
* 日期: 2019-04-07
|
||||
* 时间: 20:05
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace MrWu.DB
|
||||
{
|
||||
/// <summary>
|
||||
/// 方法类型
|
||||
/// </summary>
|
||||
public enum MethodType
|
||||
{
|
||||
/// <summary>
|
||||
/// 过程
|
||||
/// </summary>
|
||||
Procedure = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 函数
|
||||
/// </summary>
|
||||
Function = 1,
|
||||
}
|
||||
}
|
||||
691
MrWu/DB/MySQL.cs
Normal file
691
MrWu/DB/MySQL.cs
Normal file
@ -0,0 +1,691 @@
|
||||
#if MySQL
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using MySql.Data.MySqlClient;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using MrWu.Model;
|
||||
using System.Threading;
|
||||
using MrWu.Debug;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace MrWu.DB {
|
||||
/// <summary>
|
||||
/// mysql操作
|
||||
/// </summary>
|
||||
public class MySQL : SqlEx<MySqlConnection, MySqlCommand, MySqlDbType,MySqlParameter> {
|
||||
/// <summary>
|
||||
/// 链接池
|
||||
/// </summary>
|
||||
private class ConnectionPool : IConnectionPool<MySqlConnection> {
|
||||
/// <summary>
|
||||
/// 链接字符串
|
||||
/// </summary>
|
||||
private readonly string _connstr;
|
||||
|
||||
string IConnectionPool<MySqlConnection>.connecStr => _connstr;
|
||||
|
||||
private readonly int _capsize;
|
||||
/// <summary>
|
||||
/// 最大的缓存链接数量
|
||||
/// </summary>
|
||||
int IPool<MySqlConnection>.capSize => _capsize;
|
||||
|
||||
private readonly int _surviveCountSize;
|
||||
|
||||
/// <summary>
|
||||
/// 同时存在最大的链接数量
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
int IPool<MySqlConnection>.surviveCountSize => _surviveCountSize;
|
||||
|
||||
/// <summary>
|
||||
/// 当前池中的数量
|
||||
/// </summary>
|
||||
int IPool<MySqlConnection>.capCount => _conns.Count;
|
||||
|
||||
long _surviveCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 当前存活数量
|
||||
/// </summary>
|
||||
int IPool<MySqlConnection>.surviveCount {
|
||||
get {
|
||||
return (int)Interlocked.Read(ref _surviveCount);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 所有的链接
|
||||
/// </summary>
|
||||
private readonly ConcurrentQueue<MySqlConnection> _conns = new ConcurrentQueue<MySqlConnection>();
|
||||
|
||||
ConcurrentQueue<MySqlConnection> IConnectionPool<MySqlConnection>.conns => _conns;
|
||||
|
||||
/// <summary>
|
||||
/// 用于异步等待连接可用的信号量
|
||||
/// </summary>
|
||||
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1);
|
||||
|
||||
public ConnectionPool(SqlConfig config) {
|
||||
this._capsize = config.cacheCount;
|
||||
this._surviveCountSize = config.surviveCountSize;
|
||||
this._connstr = string.Format("server={0};port={1};user={2};password={3};AllowUserVariables={4};pooling=true;database=",
|
||||
config.host, config.port, config.username, config.pwd, config.AllowUserVariables);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个连接
|
||||
/// </summary>
|
||||
/// <param name="dbbase"></param>
|
||||
/// <returns></returns>
|
||||
public MySqlConnection TakeOut(params object[] dbbase) {
|
||||
if (dbbase.Length <= 0) return null;
|
||||
string dbname = dbbase[0] as string;
|
||||
if (dbname == null) return null;
|
||||
MySqlConnection conn;
|
||||
if (_conns.TryDequeue(out conn)) {
|
||||
if (conn != null) {
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
if (this._surviveCountSize > 0 && Interlocked.Read(ref _surviveCount) >= this._surviveCountSize)
|
||||
return null;
|
||||
Interlocked.Increment(ref _surviveCount);
|
||||
return new MySqlConnection(this._connstr + dbname);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取一个连接(连接池满时不会阻塞线程)
|
||||
/// </summary>
|
||||
public async Task<MySqlConnection> TakeOutAsync(string dbname) {
|
||||
if (dbname == null) return null;
|
||||
while (true) {
|
||||
MySqlConnection conn;
|
||||
if (_conns.TryDequeue(out conn)) {
|
||||
if (conn != null) return conn;
|
||||
}
|
||||
if (this._surviveCountSize == 0 || Interlocked.Read(ref _surviveCount) < this._surviveCountSize) {
|
||||
Interlocked.Increment(ref _surviveCount);
|
||||
return new MySqlConnection(this._connstr + dbname);
|
||||
}
|
||||
// 连接池满,异步等待
|
||||
await _semaphore.WaitAsync();
|
||||
_semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 放入一个连接
|
||||
/// </summary>
|
||||
/// <param name="conn"></param>
|
||||
public void PutInto(MySqlConnection conn) {
|
||||
if (_capsize == 0 || _conns.Count < _capsize) {
|
||||
_conns.Enqueue(conn);
|
||||
} else {
|
||||
conn.Dispose();
|
||||
Interlocked.Decrement(ref _surviveCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 1.执行sql语句 获得执行sql语句后的结果
|
||||
* 2.执行存储过程 获得存储过程的结果
|
||||
*
|
||||
* 每个库都有一个链接
|
||||
*
|
||||
* */
|
||||
|
||||
private ConnectionPool _ConnPool = null;
|
||||
|
||||
/// <summary>
|
||||
/// 链接池
|
||||
/// </summary>
|
||||
public override IConnectionPool<MySqlConnection> connPool => _ConnPool;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
public MySQL(SqlConfig config) {
|
||||
this._ConnPool = new ConnectionPool(config);
|
||||
errorTryAgainCount = config.errorTryAgainCount;
|
||||
errorAgainTimeInc = config.errorAgainTimeInc;
|
||||
errorAgainTime = config.errorAgainTime;
|
||||
|
||||
if (errorTryAgainCount < 0)
|
||||
throw new ArgumentException("errorTryAgainCount 不能小于 0");
|
||||
if (errorAgainTimeInc < 0)
|
||||
throw new ArgumentException("errorAgainTimeInc 不能小于 0");
|
||||
if (errorAgainTime < 0)
|
||||
throw new ArgumentException("errorAgainTime 不能小于 0");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个连接
|
||||
/// </summary>
|
||||
/// <param name="dbbase"></param>
|
||||
/// <returns></returns>
|
||||
public override MySqlConnection GetConnection(string dbbase) {
|
||||
MySqlConnection tmp;
|
||||
while (true) {
|
||||
tmp = _ConnPool.TakeOut(dbbase);
|
||||
if (tmp != null)
|
||||
return tmp;
|
||||
Debug.Debug.Warning("链接数超过上限,等待重试");
|
||||
Thread.Sleep(2);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步获取一个连接(不会阻塞线程)
|
||||
/// </summary>
|
||||
public async Task<MySqlConnection> GetConnectionAsync(string dbbase) {
|
||||
return await _ConnPool.TakeOutAsync(dbbase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始存储过程
|
||||
/// </summary>
|
||||
/// <param name="dbbase">存储过程所在的数据库</param>
|
||||
/// <param name="procedure">存储过程名</param>
|
||||
/// <returns></returns>
|
||||
public override IProdureParameter<MySqlCommand> BeginProcedure(string dbbase, string procedure) {
|
||||
if (_ConnPool == null)
|
||||
throw new Exception("you dont hava init");
|
||||
|
||||
MySqlCommand cmd = new MySqlCommand(procedure, GetConnection(dbbase));
|
||||
MySqlProcedureParameter result = new MySqlProcedureParameter(cmd, dbbase);
|
||||
//存储过程模式
|
||||
cmd.CommandType = CommandType.StoredProcedure;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加参数
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程查询键</param>
|
||||
/// <param name="paramName">参数名</param>
|
||||
/// <param name="value">参数值</param>
|
||||
/// <param name="type">参数类型</param>
|
||||
/// <param name="pd">参数种类</param>
|
||||
public override void AddParam(IProdureParameter<MySqlCommand> spp, string paramName, object value, MySqlDbType type, ParameterDirection pd = ParameterDirection.Input) {
|
||||
if (spp == null || spp.command == null)
|
||||
throw new Exception("param spp null");
|
||||
MySqlParameter param = spp.command.Parameters.Add(paramName, type);
|
||||
param.Direction = pd;
|
||||
if (value == null)
|
||||
param.Value = DBNull.Value;
|
||||
else
|
||||
param.Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交存储过程
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程查询键</param>
|
||||
/// <param name="ds">如果 存储过程中有查询表操作,则需要传递DataSet实例</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>参数值,输出参数从字典中获取</returns>
|
||||
public override Dictionary<string, object> SubProcedure(IProdureParameter<MySqlCommand> spp, DataSet ds = null, int againCount = -1) {
|
||||
if (spp == null || spp.command == null)
|
||||
throw new Exception("param spp null");
|
||||
|
||||
int cnt = Execute(spp.command, spp.dbName, ds, againCount);
|
||||
|
||||
Dictionary<string, object> dic = new Dictionary<string, object>();
|
||||
var pms = spp.command.Parameters;
|
||||
int len = pms.Count;
|
||||
for (int i = 0; i < len; i++) {
|
||||
dic.Add(pms[i].ParameterName, pms[i].Value);
|
||||
}
|
||||
|
||||
if (!dic.ContainsKey(DbConst.RowsAffected))
|
||||
{
|
||||
dic[DbConst.RowsAffected] = cnt;
|
||||
}
|
||||
|
||||
spp.Dispose();
|
||||
return dic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行sql语句
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库</param>
|
||||
/// <param name="sql">sql语句</param>
|
||||
/// <param name="mysqlparams"></param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <param name="ds">如果是查询 使用传入ds实例</param>
|
||||
public override int ExecuteSql(string dbbase, string sql, IEnumerable<MySqlParameter> mysqlparams = null, DataSet ds = null, int againCount = -1) {
|
||||
MySqlCommand cmd = new MySqlCommand(sql, GetConnection(dbbase));
|
||||
cmd.CommandType = CommandType.Text;
|
||||
|
||||
if (mysqlparams != null) {
|
||||
//int len = mysqlparams.Count;
|
||||
//for (int i = 0; i < len; i++) {
|
||||
// ISqlAloneParameter<MySqlDbType> msap = mysqlparams[i];
|
||||
// cmd.Parameters.Add(msap.paramname, msap.type, msap.valueLength);
|
||||
// cmd.Parameters[msap.paramname].Value = msap.paramvalue;
|
||||
//}
|
||||
foreach (var param in mysqlparams) {
|
||||
cmd.Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
|
||||
return Execute(cmd, dbbase, ds, againCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行sql语句
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库</param>
|
||||
/// <param name="sql">sql语句</param>
|
||||
/// <param name="mysqlparams">附加参数</param>
|
||||
/// <returns></returns>
|
||||
public MySqlCommand GetCommandBySql(string dbbase, string sql, IEnumerable<MySqlParameter> mysqlparams = null) {
|
||||
MySqlCommand cmd = new MySqlCommand(sql, GetConnection(dbbase));
|
||||
cmd.CommandType = CommandType.Text;
|
||||
|
||||
if (mysqlparams != null) {
|
||||
//int len = mysqlparams.Count;
|
||||
//for (int i = 0; i < len; i++) {
|
||||
// ISqlAloneParameter<MySqlDbType> msap = mysqlparams[i];
|
||||
// cmd.Parameters.Add(msap.paramname, msap.type, msap.valueLength);
|
||||
// cmd.Parameters[msap.paramname].Value = msap.paramvalue;
|
||||
//}
|
||||
foreach (var param in mysqlparams) {
|
||||
cmd.Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 普通查询一个表
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="table">表名</param>
|
||||
/// <param name="column">列名</param>
|
||||
/// <param name="where">条件</param>
|
||||
/// <param name="count">查询的数量</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <param name="sqlparams">sqlparams</param>
|
||||
/// <returns>查询到的表</returns>
|
||||
public override DataTable Select(string dbbase, string table, string[] column = null, string where = null, int count = 0, int againCount = -1, IEnumerable<MySqlParameter> sqlparams = null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("select ");
|
||||
if (column != null && column.Length > 0) {
|
||||
int len = column.Length;
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
sb.Append(column[i]);
|
||||
if (i > 0)
|
||||
sb.Append(",");
|
||||
}
|
||||
} else {
|
||||
sb.Append("*");
|
||||
}
|
||||
|
||||
sb.Append(" from ");
|
||||
sb.Append(table);
|
||||
if (!string.IsNullOrEmpty(where)) {
|
||||
sb.Append(" where ");
|
||||
sb.Append(where);
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
sb.AppendFormat(" limit {0}", count);
|
||||
}
|
||||
|
||||
DataSet ds = new DataSet();
|
||||
|
||||
ExecuteSql(dbbase, sb.ToString(), sqlparams, ds, againCount);
|
||||
if (ds.Tables == null || ds.Tables.Count == 0)
|
||||
return null;
|
||||
return ds.Tables[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行sql命令
|
||||
/// </summary>
|
||||
/// <param name="cmd">指令</param>
|
||||
/// <param name="dbname">数据库名称</param>
|
||||
/// <param name="ds">null表示不需要查询结果集 有值将会把结果集放到 ds中</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
public override int Execute(MySqlCommand cmd, string dbname, DataSet ds = null, int againCount = -1) {
|
||||
|
||||
// Debug.Debug.Log("执行sql指令!");
|
||||
|
||||
int result = 0;
|
||||
int exceCnt = 0; //执行次数
|
||||
//重试次数
|
||||
if (againCount < 0)
|
||||
againCount = errorTryAgainCount;
|
||||
try {
|
||||
while (exceCnt <= againCount) {
|
||||
try {
|
||||
if (cmd.Connection.State == ConnectionState.Closed)
|
||||
cmd.Connection.Open();
|
||||
cmd.Connection.ChangeDatabase(dbname);
|
||||
|
||||
if (ds == null)
|
||||
result = cmd.ExecuteNonQuery();
|
||||
else {
|
||||
using(MySqlDataAdapter sda = new MySqlDataAdapter()) {
|
||||
sda.SelectCommand = cmd;
|
||||
sda.Fill(ds);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
cmd.Connection.Close();
|
||||
if (exceCnt < againCount)
|
||||
Debug.Debug.Error("数据库执行错误重试次数:" + exceCnt + ",错误类型:" + e.Message);
|
||||
else
|
||||
throw e;
|
||||
}
|
||||
|
||||
int time = errorAgainTime + errorAgainTimeInc * exceCnt;
|
||||
exceCnt++; //执行次数+1
|
||||
Thread.Sleep(time);
|
||||
}
|
||||
} finally {
|
||||
_ConnPool.PutInto(cmd.Connection); //放入链接
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始一个事务
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库</param>
|
||||
/// <returns></returns>
|
||||
public override IProdureParameter<MySqlCommand> BeginTransaction(string dbbase) {
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
MySqlProcedureParameter spp = new MySqlProcedureParameter(cmd, dbbase);
|
||||
try {
|
||||
cmd.Connection = GetConnection(dbbase);
|
||||
if (cmd.Connection.State == ConnectionState.Closed)
|
||||
cmd.Connection.Open();
|
||||
cmd.Connection.ChangeDatabase(dbbase);
|
||||
cmd.Transaction = cmd.Connection.BeginTransaction(); //开始事务,还可以设置隔离等级
|
||||
} catch (Exception e) {
|
||||
spp.exception = e;
|
||||
}
|
||||
return spp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事务添加sql语句
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="sqlparams"></param>
|
||||
public override int TransactionAddSql(IProdureParameter<MySqlCommand> spp, string sql, List<ISqlAloneParameter<MySqlDbType>> sqlparams = null) {
|
||||
if (spp.isException)
|
||||
return 0;
|
||||
try {
|
||||
MySqlCommand cmd = spp.command;
|
||||
cmd.CommandText = sql;
|
||||
cmd.Parameters.Clear();
|
||||
|
||||
if (sqlparams != null) {
|
||||
int len = sqlparams.Count;
|
||||
for (int i = 0; i < len; i++) {
|
||||
ISqlAloneParameter<MySqlDbType> sap = sqlparams[i];
|
||||
cmd.Parameters.Add(sap.paramname, sap.type, sap.valueLength);
|
||||
cmd.Parameters[sap.paramname].Value = sap.paramvalue;
|
||||
}
|
||||
}
|
||||
|
||||
return cmd.ExecuteNonQuery();
|
||||
} catch (Exception e) {
|
||||
spp.exception = e;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 提交事务
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
/// <returns>true 表示提交成功 false 表示提交失败</returns>
|
||||
public override bool SubTransaction(IProdureParameter<MySqlCommand> spp) {
|
||||
try {
|
||||
spp.command.Transaction.Commit();
|
||||
} catch (Exception e) {
|
||||
spp.exception = e;
|
||||
spp.command.Transaction.Rollback();
|
||||
} finally {
|
||||
_ConnPool.PutInto(spp.command.Connection);
|
||||
spp.Dispose();
|
||||
}
|
||||
return spp.exception == null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回滚事务
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
public override void RollbackTransaction(IProdureParameter<MySqlCommand> spp) {
|
||||
try {
|
||||
spp.command.Transaction.Rollback();
|
||||
} catch (Exception ex) {
|
||||
Debug.Debug.Error("RollbackTransaction ex: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
#region 异步方法
|
||||
|
||||
/// <summary>
|
||||
/// 异步提交存储过程
|
||||
/// </summary>
|
||||
public override async Task<Dictionary<string, object>> SubProcedureAsync(IProdureParameter<MySqlCommand> spp, DataSet ds = null, int againCount = -1) {
|
||||
if (spp == null || spp.command == null)
|
||||
throw new Exception("param spp null");
|
||||
|
||||
int cnt = await ExecuteAsync(spp.command, spp.dbName, ds, againCount);
|
||||
|
||||
Dictionary<string, object> dic = new Dictionary<string, object>();
|
||||
var pms = spp.command.Parameters;
|
||||
int len = pms.Count;
|
||||
for (int i = 0; i < len; i++) {
|
||||
dic.Add(pms[i].ParameterName, pms[i].Value);
|
||||
}
|
||||
|
||||
if (!dic.ContainsKey(DbConst.RowsAffected)) {
|
||||
dic[DbConst.RowsAffected] = cnt;
|
||||
}
|
||||
|
||||
spp.Dispose();
|
||||
return dic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行sql语句
|
||||
/// </summary>
|
||||
public override async Task<int> ExecuteSqlAsync(string dbbase, string sql, IEnumerable<MySqlParameter> mysqlparams = null, DataSet ds = null, int againCount = -1) {
|
||||
MySqlCommand cmd = new MySqlCommand(sql, await GetConnectionAsync(dbbase));
|
||||
cmd.CommandType = CommandType.Text;
|
||||
|
||||
if (mysqlparams != null) {
|
||||
foreach (var param in mysqlparams) {
|
||||
cmd.Parameters.Add(param);
|
||||
}
|
||||
}
|
||||
|
||||
return await ExecuteAsync(cmd, dbbase, ds, againCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步查询
|
||||
/// </summary>
|
||||
public override async Task<DataTable> SelectAsync(string dbbase, string table, string[] column = null, string where = null, int count = 0, int againCount = -1, IEnumerable<MySqlParameter> sqlparams = null) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("select ");
|
||||
if (column != null && column.Length > 0) {
|
||||
int len = column.Length;
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
sb.Append(column[i]);
|
||||
if (i > 0)
|
||||
sb.Append(",");
|
||||
}
|
||||
} else {
|
||||
sb.Append("*");
|
||||
}
|
||||
|
||||
sb.Append(" from ");
|
||||
sb.Append(table);
|
||||
if (!string.IsNullOrEmpty(where)) {
|
||||
sb.Append(" where ");
|
||||
sb.Append(where);
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
sb.AppendFormat(" limit {0}", count);
|
||||
}
|
||||
|
||||
DataSet ds = new DataSet();
|
||||
|
||||
await ExecuteSqlAsync(dbbase, sb.ToString(), sqlparams, ds, againCount);
|
||||
if (ds.Tables == null || ds.Tables.Count == 0)
|
||||
return null;
|
||||
return ds.Tables[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行sql命令
|
||||
/// </summary>
|
||||
public override async Task<int> ExecuteAsync(MySqlCommand cmd, string dbname, DataSet ds = null, int againCount = -1) {
|
||||
int result = 0;
|
||||
int exceCnt = 0;
|
||||
if (againCount < 0)
|
||||
againCount = errorTryAgainCount;
|
||||
try {
|
||||
while (exceCnt <= againCount) {
|
||||
try {
|
||||
if (cmd.Connection.State == ConnectionState.Closed)
|
||||
await cmd.Connection.OpenAsync();
|
||||
cmd.Connection.ChangeDatabase(dbname);
|
||||
|
||||
if (ds == null)
|
||||
result = await cmd.ExecuteNonQueryAsync();
|
||||
else {
|
||||
using(MySqlDataAdapter sda = new MySqlDataAdapter()) {
|
||||
sda.SelectCommand = cmd;
|
||||
sda.Fill(ds);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} catch (Exception e) {
|
||||
cmd.Connection.Close();
|
||||
if (exceCnt < againCount)
|
||||
Debug.Debug.Error("数据库异步执行错误重试次数:" + exceCnt + ",错误类型:" + e.Message);
|
||||
else
|
||||
throw;
|
||||
}
|
||||
|
||||
int time = errorAgainTime + errorAgainTimeInc * exceCnt;
|
||||
exceCnt++;
|
||||
await Task.Delay(time);
|
||||
}
|
||||
} finally {
|
||||
_ConnPool.PutInto(cmd.Connection);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 保存每个存储过程为单个文件
|
||||
/// </summary>
|
||||
/// <param name="dbbase">那个数据库的</param>
|
||||
/// <param name="path">存储的路径</param>
|
||||
/// <param name="method">如果导出其中一个存储过程,则填存储过程名称</param>
|
||||
public void SaveMethod(string dbbase, string path, string method = null) {
|
||||
|
||||
DataTable dt;
|
||||
|
||||
if (method == null)
|
||||
dt = Select("information_schema", "routines", new string[] { "routine_name", "routine_type" }, string.Format("routine_schema='{0}'", dbbase));
|
||||
else
|
||||
dt = Select("information_schema", "routines", new string[] { "routine_name", "routine_type" }, string.Format("routine_schema='{0}' and routine_name='{1}'", dbbase, method));
|
||||
|
||||
foreach (DataColumn item in dt.Columns) {
|
||||
Console.WriteLine(item.ColumnName);
|
||||
}
|
||||
int len = dt.Rows.Count;
|
||||
for (int i = 0; i < len; i++) {
|
||||
SaveMethod(dbbase, path, dt.Rows[i]["routine_name"] as string, dt.Rows[i]["routine_type"] as string);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存方法
|
||||
/// </summary>
|
||||
/// <param name="dbbase"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="methodName"></param>
|
||||
/// <param name="methodType"></param>
|
||||
private void SaveMethod(string dbbase, string path, string methodName, string methodType) {
|
||||
if (!Directory.Exists(path)) {
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
string sql = string.Format("show create {0} {1};", methodType, methodName);
|
||||
DataSet ds = new DataSet();
|
||||
ExecuteSql(dbbase, sql, null, ds);
|
||||
|
||||
if (ds.Tables == null || ds.Tables.Count == 0 || ds.Tables[0].Rows == null || ds.Tables[0].Rows.Count == 0)
|
||||
return;
|
||||
path = string.Format("{0}/{1}.sql", path, methodName);
|
||||
|
||||
string sqlCode = string.Format("Drop {0} if exists {1};{2}", methodType, methodName, Environment.NewLine);
|
||||
sqlCode += "Commit;" + Environment.NewLine;
|
||||
sqlCode += ds.Tables[0].Rows[0][string.Format("Create {0}", methodType)] as string;
|
||||
|
||||
File.WriteAllText(path, sqlCode, Encoding.UTF8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行sql文件
|
||||
/// </summary>
|
||||
/// <param name="dbbase"></param>
|
||||
/// <param name="path"></param>
|
||||
public void Execute(string dbbase, string path) {
|
||||
if (File.Exists(path)) {
|
||||
try {
|
||||
string sql = File.ReadAllText(path);
|
||||
ExecuteSql(dbbase, sql);
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine("运行出错:" + path + Environment.NewLine + e.ToString());
|
||||
}
|
||||
} else if (Directory.Exists(path)) {
|
||||
DirectoryInfo dinfo = new DirectoryInfo(path);
|
||||
|
||||
string[] paths = Directory.GetDirectories(path);
|
||||
|
||||
foreach (var item in paths) {
|
||||
|
||||
Console.WriteLine(item);
|
||||
|
||||
Execute(dbbase, item);
|
||||
}
|
||||
|
||||
FileInfo[] finfos = dinfo.GetFiles();
|
||||
|
||||
foreach (var fl in finfos) {
|
||||
Execute(dbbase, fl.FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
130
MrWu/DB/MySqlParameterData.cs
Normal file
130
MrWu/DB/MySqlParameterData.cs
Normal file
@ -0,0 +1,130 @@
|
||||
#if MySQL
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace MrWu.DB {
|
||||
/// <summary>
|
||||
/// 存储过程查询键
|
||||
/// </summary>
|
||||
public class MySqlProcedureParameter : IProdureParameter<MySqlCommand> {
|
||||
|
||||
MySqlCommand _command;
|
||||
|
||||
/// <summary>
|
||||
/// 指令
|
||||
/// </summary>
|
||||
public MySqlCommand command {
|
||||
get => _command;
|
||||
}
|
||||
|
||||
private string _dbName;
|
||||
|
||||
/// <summary>
|
||||
/// 数据库名称
|
||||
/// </summary>
|
||||
public string dbName {
|
||||
get => _dbName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
public Exception exception {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否报错
|
||||
/// </summary>
|
||||
public bool isException {
|
||||
get {
|
||||
return exception != null;
|
||||
}
|
||||
}
|
||||
|
||||
private MySqlProcedureParameter() { }
|
||||
|
||||
|
||||
internal MySqlProcedureParameter(MySqlCommand mysqlcommand,string dbName) {
|
||||
this._command = mysqlcommand;
|
||||
this._dbName = dbName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放
|
||||
/// </summary>
|
||||
public void Dispose() {
|
||||
if (_command != null) {
|
||||
_command.Dispose();
|
||||
_command = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单独设置参数
|
||||
/// </summary>
|
||||
public class MySqlAloneParameter : ISqlAloneParameter<MySqlDbType> {
|
||||
|
||||
string _paramname;
|
||||
|
||||
/// <summary>
|
||||
/// 参数名称
|
||||
/// </summary>
|
||||
public string paramname {
|
||||
get => _paramname;
|
||||
}
|
||||
|
||||
object _parmavalue;
|
||||
|
||||
/// <summary>
|
||||
/// 参数值
|
||||
/// </summary>
|
||||
public object paramvalue {
|
||||
get => _parmavalue;
|
||||
set => _parmavalue = value;
|
||||
}
|
||||
|
||||
MySqlDbType _type;
|
||||
|
||||
/// <summary>
|
||||
/// 参数类型
|
||||
/// </summary>
|
||||
public MySqlDbType type {
|
||||
get => _type;
|
||||
}
|
||||
|
||||
int _valueLength;
|
||||
|
||||
/// <summary>
|
||||
/// 参数长度
|
||||
/// </summary>
|
||||
public int valueLength {
|
||||
get => _valueLength;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// sql语句单独设置参数
|
||||
/// </summary>
|
||||
/// <param name="paramname">参数名称</param>
|
||||
/// <param name="paramvalue">参数值</param>
|
||||
/// <param name="valuelength">参数值的长度</param>
|
||||
/// <param name="type">参数类型</param>
|
||||
public MySqlAloneParameter(string paramname, object paramvalue, int valuelength, MySqlDbType type = MySqlDbType.Binary) {
|
||||
this._paramname = paramname;
|
||||
this._parmavalue = paramvalue;
|
||||
this._valueLength = valuelength;
|
||||
this._type = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Direction
|
||||
/// </summary>
|
||||
public ParameterDirection Direction { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
146
MrWu/DB/SqlConfig.cs
Normal file
146
MrWu/DB/SqlConfig.cs
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 由SharpDevelop创建。
|
||||
* 用户: Administrator
|
||||
* 日期: 2019-03-21
|
||||
* 时间: 10:10
|
||||
*
|
||||
* 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
|
||||
*/
|
||||
using System;
|
||||
using System.Net;
|
||||
|
||||
namespace MrWu.DB {
|
||||
/// <summary>
|
||||
/// sql 配置
|
||||
/// </summary>
|
||||
public class SqlConfig {
|
||||
/// <summary>
|
||||
/// 配置名称
|
||||
/// </summary>
|
||||
public string name {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string host {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 端口
|
||||
/// </summary>
|
||||
public int port {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
public string username {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
public string pwd {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 版本
|
||||
/// </summary>
|
||||
public string verison {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否允许使用会话变量
|
||||
/// </summary>
|
||||
public bool AllowUserVariables {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
private int errorTryAgainCount_ = 5;
|
||||
|
||||
/// <summary>
|
||||
/// 出错重试次数 0表示不重试
|
||||
/// </summary>
|
||||
public int errorTryAgainCount {
|
||||
get {
|
||||
return errorTryAgainCount_;
|
||||
}
|
||||
set {
|
||||
errorTryAgainCount_ = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 出错重试时间增量 单位毫秒 0表示以固定时间间隔重试
|
||||
/// </summary>
|
||||
public int errorAgainTimeInc {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 不启用SSL模式
|
||||
/// </summary>
|
||||
public string sslMode = "None";
|
||||
|
||||
private int _errorAginTime = 100;
|
||||
|
||||
/// <summary>
|
||||
/// 执行出错,第一次多少毫秒后进行重试
|
||||
/// </summary>
|
||||
public int errorAgainTime {
|
||||
get {
|
||||
return _errorAginTime;
|
||||
}
|
||||
set {
|
||||
_errorAginTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
private int _cacheCount = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 缓存链接数量
|
||||
/// </summary>
|
||||
public int cacheCount {
|
||||
get {
|
||||
return _cacheCount;
|
||||
}
|
||||
set {
|
||||
_cacheCount = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 限制链接数量
|
||||
/// </summary>
|
||||
private int _surviveCountSize = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 最大存活链接数
|
||||
/// </summary>
|
||||
public int surviveCountSize {
|
||||
get {
|
||||
return _surviveCountSize;
|
||||
}
|
||||
set {
|
||||
_surviveCountSize = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
173
MrWu/DB/SqlEx.cs
Normal file
173
MrWu/DB/SqlEx.cs
Normal file
@ -0,0 +1,173 @@
|
||||
/********************************
|
||||
*
|
||||
* 作者:吴隆健
|
||||
* 创建时间: 2019-06-06 13:34:46
|
||||
*
|
||||
********************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MrWu.DB {
|
||||
/// <summary>
|
||||
/// sql链接
|
||||
/// </summary>
|
||||
/// <typeparam name="T">T是sql的链接类型</typeparam>
|
||||
/// <typeparam name="K">K是指令类型</typeparam>
|
||||
/// <typeparam name="M">M是参数类型</typeparam>
|
||||
/// <typeparam name="N">M是参数类型</typeparam>
|
||||
public abstract class SqlEx<T, K, M,N> : ISqlEx<T, K, M,N> {
|
||||
|
||||
/// <summary>
|
||||
/// 出错的重试次数 0表示不重试
|
||||
/// </summary>
|
||||
public int errorTryAgainCount {
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 出错重试时间增量 单位毫秒 0表示以固定时间间隔重试
|
||||
/// </summary>
|
||||
public int errorAgainTimeInc {
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行出错 第一次多少秒后进行重试
|
||||
/// </summary>
|
||||
public int errorAgainTime {
|
||||
get;
|
||||
protected set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 链接池
|
||||
/// </summary>
|
||||
public abstract IConnectionPool<T> connPool { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 给存储过程添加参数
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程命令</param>
|
||||
/// <param name="paramName">参数名</param>
|
||||
/// <param name="value">参数值</param>
|
||||
/// <param name="type">参数类型</param>
|
||||
/// <param name="pd">参数种类</param>
|
||||
public abstract void AddParam(IProdureParameter<K> spp, string paramName, object value, M type, ParameterDirection pd = ParameterDirection.Input);
|
||||
|
||||
/// <summary>
|
||||
/// 开始执行存储过程
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="procedure">存储过程名称</param>
|
||||
/// <returns>存储过程指令</returns>
|
||||
public abstract IProdureParameter<K> BeginProcedure(string dbbase, string procedure);
|
||||
|
||||
/// <summary>
|
||||
/// 执行一个事务
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <returns>存储过程指令</returns>
|
||||
public abstract IProdureParameter<K> BeginTransaction(string dbbase);
|
||||
|
||||
/// <summary>
|
||||
/// 执行cmd
|
||||
/// </summary>
|
||||
/// <param name="cmd">数据库指令</param>
|
||||
/// <param name="dbname">数据库名称</param>
|
||||
/// <param name="ds">结果集</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>受影响的行数</returns>
|
||||
public abstract int Execute(K cmd,string dbname, DataSet ds = null,int againCount = -1);
|
||||
|
||||
/// <summary>
|
||||
/// 执行sql语句
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="sql">sql语句</param>
|
||||
/// <param name="sqlparams">sql的额外参数</param>
|
||||
/// <param name="ds">查询的结果集</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>受影响的行数</returns>
|
||||
public abstract int ExecuteSql(string dbbase, string sql, IEnumerable<N> sqlparams = null, DataSet ds = null,int againCount = -1);
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个连接
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <returns>返回链接</returns>
|
||||
public abstract T GetConnection(string dbbase);
|
||||
|
||||
/// <summary>
|
||||
/// 执行一个普通的查询
|
||||
/// </summary>
|
||||
/// <param name="dbbase">数据库名称</param>
|
||||
/// <param name="table">数据库表名</param>
|
||||
/// <param name="column">查询的列</param>
|
||||
/// <param name="where">查询条件</param>
|
||||
/// <param name="count">查询的行数</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <param name="sqlparams">Sql参数</param>
|
||||
/// <returns>查询的结果集</returns>
|
||||
public abstract DataTable Select(string dbbase, string table, string[] column = null, string where = null, int count = 0,int againCount = -1, IEnumerable<N> sqlparams = null);
|
||||
|
||||
/// <summary>
|
||||
/// 提交存储过程
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程命令</param>
|
||||
/// <param name="ds">查询的结果集</param>
|
||||
/// <param name="againCount">重试次数 小于0表示使用配置值 大于等于0表示自定义</param>
|
||||
/// <returns>执行存储过程所有参数</returns>
|
||||
public abstract Dictionary<string, object> SubProcedure(IProdureParameter<K> spp, DataSet ds = null,int againCount = -1);
|
||||
|
||||
/// <summary>
|
||||
/// 提交一个事务
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程指令</param>
|
||||
/// <returns>是否执行成功</returns>
|
||||
public abstract bool SubTransaction(IProdureParameter<K> spp);
|
||||
|
||||
/// <summary>
|
||||
/// 为事务添加sql语句
|
||||
/// </summary>
|
||||
/// <param name="spp">存储过程指令</param>
|
||||
/// <param name="sql">sql语句</param>
|
||||
/// <param name="sqlparams">额外参数</param>
|
||||
public abstract int TransactionAddSql(IProdureParameter<K> spp, string sql, List<ISqlAloneParameter<M>> sqlparams = null);
|
||||
|
||||
/// <summary>
|
||||
/// 回滚事务
|
||||
/// </summary>
|
||||
/// <param name="spp"></param>
|
||||
public abstract void RollbackTransaction(IProdureParameter<K> spp);
|
||||
|
||||
#region 异步方法
|
||||
|
||||
/// <summary>
|
||||
/// 异步提交存储过程
|
||||
/// </summary>
|
||||
public abstract Task<Dictionary<string, object>> SubProcedureAsync(IProdureParameter<K> spp, DataSet ds = null, int againCount = -1);
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行sql语句
|
||||
/// </summary>
|
||||
public abstract Task<int> ExecuteSqlAsync(string dbbase, string sql, IEnumerable<N> sqlparams = null, DataSet ds = null, int againCount = -1);
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行一个普通的查询
|
||||
/// </summary>
|
||||
public abstract Task<DataTable> SelectAsync(string dbbase, string table, string[] column = null, string where = null, int count = 0, int againCount = -1, IEnumerable<N> sqlparams = null);
|
||||
|
||||
/// <summary>
|
||||
/// 异步执行cmd
|
||||
/// </summary>
|
||||
public abstract Task<int> ExecuteAsync(K cmd, string dbname, DataSet ds = null, int againCount = -1);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
138
MrWu/DB/SqlParameterData.cs
Normal file
138
MrWu/DB/SqlParameterData.cs
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 作者:吴隆健
|
||||
* 日期: 2019-04-07
|
||||
* 时间: 20:05
|
||||
*
|
||||
*/
|
||||
|
||||
#if MMSQL
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace MrWu.DB
|
||||
{
|
||||
/// <summary>
|
||||
/// 存储过程查询键
|
||||
/// </summary>
|
||||
public class SqlProcedureParameter : IProdureParameter<SqlCommand>
|
||||
{
|
||||
SqlCommand _sqlcommand;
|
||||
|
||||
/// <summary>
|
||||
/// 查询键
|
||||
/// </summary>
|
||||
public SqlCommand command
|
||||
{
|
||||
get => _sqlcommand;
|
||||
}
|
||||
|
||||
private string _dbName;
|
||||
|
||||
/// <summary>
|
||||
/// 数据库名称
|
||||
/// </summary>
|
||||
public string dbName
|
||||
{
|
||||
get => _dbName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息
|
||||
/// </summary>
|
||||
public Exception exception { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否报错
|
||||
/// </summary>
|
||||
public bool isException
|
||||
{
|
||||
get { return exception != null; }
|
||||
}
|
||||
|
||||
private SqlProcedureParameter()
|
||||
{
|
||||
}
|
||||
|
||||
internal SqlProcedureParameter(SqlCommand sqlcommand, string dbName)
|
||||
{
|
||||
this._sqlcommand = sqlcommand;
|
||||
this._dbName = dbName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_sqlcommand != null)
|
||||
{
|
||||
_sqlcommand.Dispose();
|
||||
_sqlcommand = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单独设置参数
|
||||
/// </summary>
|
||||
public class SqlAloneParameter : ISqlAloneParameter<SqlDbType>
|
||||
{
|
||||
string _paramname;
|
||||
|
||||
/// <summary>
|
||||
/// 参数名称
|
||||
/// </summary>
|
||||
public string paramname
|
||||
{
|
||||
get => _paramname;
|
||||
}
|
||||
|
||||
object _paramvalue;
|
||||
|
||||
/// <summary>
|
||||
/// 参数值
|
||||
/// </summary>
|
||||
public object paramvalue
|
||||
{
|
||||
get => _paramvalue;
|
||||
set => _paramvalue = value;
|
||||
}
|
||||
|
||||
SqlDbType _type;
|
||||
|
||||
/// <summary>
|
||||
/// 参数类型
|
||||
/// </summary>
|
||||
public SqlDbType type => _type;
|
||||
|
||||
int _valueLength;
|
||||
|
||||
/// <summary>
|
||||
/// 参数长度
|
||||
/// </summary>
|
||||
public int valueLength => _valueLength;
|
||||
|
||||
/// <summary>
|
||||
/// sql语句单独设置参数
|
||||
/// </summary>
|
||||
/// <param name="paramname">参数名称</param>
|
||||
/// <param name="paramvalue">参数值</param>
|
||||
/// <param name="valuelength">参数值的长度</param>
|
||||
/// <param name="type">参数类型</param>
|
||||
public SqlAloneParameter(string paramname, object paramvalue, int valuelength = 0,
|
||||
SqlDbType type = SqlDbType.Binary)
|
||||
{
|
||||
this._paramname = paramname;
|
||||
this._paramvalue = paramvalue;
|
||||
this._valueLength = valuelength;
|
||||
this._type = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Direction
|
||||
/// </summary>
|
||||
public ParameterDirection Direction { get; set; }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
48
MrWu/DB/SqlTimer.cs
Normal file
48
MrWu/DB/SqlTimer.cs
Normal file
@ -0,0 +1,48 @@
|
||||
/********************************
|
||||
*
|
||||
* 作者:吴隆健
|
||||
* 创建时间: 2019-06-06 16:34:39
|
||||
*
|
||||
********************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace MrWu.DB {
|
||||
/// <summary>
|
||||
/// 数据库定时器
|
||||
/// </summary>
|
||||
public class SqlTimer {
|
||||
|
||||
/// <summary>
|
||||
/// 时间间隔单位秒
|
||||
/// </summary>
|
||||
public int interval;
|
||||
|
||||
/// <summary>
|
||||
/// 下次运行的时间点
|
||||
/// </summary>
|
||||
public long runTime;
|
||||
|
||||
/// <summary>
|
||||
/// 是否运行中
|
||||
/// </summary>
|
||||
public bool isRuning {
|
||||
get;
|
||||
internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动定时器
|
||||
/// </summary>
|
||||
public void Start() {
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止定时器
|
||||
/// </summary>
|
||||
public void Stop() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user