clickhouse数据库,http请求访问,支持参数化

csharp 复制代码
public class ClickHouseClient
{
    private static readonly HttpClient _httpClient = new HttpClient();
    private readonly string _clickHouseUrl;
    private readonly string _username;
    private readonly string _password;
    private string _database;
    private static readonly string _searchFormat = " FORMAT JSON";

    public ClickHouseClient()
    {
        _clickHouseUrl = "url";
        _username = "user_name";
        _password = "password";
        if (string.IsNullOrWhiteSpace(_clickHouseUrl) || string.IsNullOrWhiteSpace(_username) || string.IsNullOrWhiteSpace(_password))
        {
            System.Text.StringBuilder str = new System.Text.StringBuilder();
            str.Append("ClickHouse配置缺失,CloudStorage:ClickHouse");
            if (string.IsNullOrWhiteSpace(_clickHouseUrl))
            {
                str.Append("节点EndPoint,");
            }
            if (string.IsNullOrWhiteSpace(_username))
            {
                str.Append("节点UId,");
            }
            if (string.IsNullOrWhiteSpace(_password))
            {
                str.Append("节点Password,");
            }
            throw new Exception($"{str.ToString().TrimEnd(',')}未配置");
        }
        _database = "default";
        SetAuthorizationHeader();
    }

    /// <summary>
    /// 设置查询数据库
    /// </summary>
    /// <param name="database"></param>
    public void SetDatabase(string database)
    {
        _database = database;
        SetAuthorizationHeader();
    }

    /// <summary>
    /// 单个查询,参数化格式:sql语句中:{id:String},赋值:{"id","666"}
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="query"></param>
    /// <param name="parameters"></param>
    /// <returns></returns>
    public List<T> ExecuteQuery<T>(string query, Dictionary<string, string> parameters = null) where T : class
    {
        try
        {
            var response = SendRequest($"{query} {_searchFormat}", parameters);
            var responseString = response.Content.ReadAsStringAsync().Result;
            var data = System.Text.Json.JsonSerializer.Deserialize<ClickHouseBaseModel<T>>(responseString);
            return data?.data;
        }
        catch (HttpRequestException)
        {
            throw;
        }
    }

    /// <summary>
    /// 单条插入,参数化格式:sql语句中:{id:String},赋值:{"id","666"}
    /// </summary>
    /// <param name="query"></param>
    /// <param name="parameters"></param>
    public void ExecuteNonQuery(string query, Dictionary<string, string> parameters = null)
    {
        try
        {
            SendRequest(query, parameters);
        }
        catch (HttpRequestException)
        {
            throw;
        }
    }

    /// <summary>
    /// 设置访问信息
    /// </summary>
    private void SetAuthorizationHeader()
    {
        _httpClient.DefaultRequestHeaders.Clear();
        _httpClient.DefaultRequestHeaders.Add("X-ClickHouse-User", _username);
        _httpClient.DefaultRequestHeaders.Add("X-ClickHouse-Key", _password);
        _httpClient.DefaultRequestHeaders.Add("X-ClickHouse-Database", _database);
    }

    /// <summary>
    /// 进行访问
    /// </summary>
    /// <param name="query"></param>
    /// <param name="parameters"></param>
    /// <returns></returns>
    private HttpResponseMessage SendRequest(string query, Dictionary<string, string> parameters = null)
    {
        var formData = new MultipartFormDataContent
        {
            { new StringContent(query), "query" }
        };

        if (parameters != null)
        {
            foreach (var param in parameters)
            {
                string paramKey = param.Key;
                if (!param.Key.StartsWith("param_"))
                {
                    paramKey = $"param_{paramKey}";
                }

                formData.Add(new StringContent(param.Value), paramKey);
            }
        }

        var response = _httpClient.PostAsync(_clickHouseUrl, formData).Result;
        response.EnsureSuccessStatusCode();
        return response;
    }
}
csharp 复制代码
      public void TestClickHouse()
      {
          var client = new ClickHouseClient();
          client.SetDatabase("default");
          var sqlSearch = "select id Id, serial_number SerialNumber from test_table";
          var result = client.ExecuteQuery<TestTable>(sqlSearch);

          var sql = "insert into test_table(id,serial_number) values({id:String},{serial_number:UInt32})";
          var param = new Dictionary<string, string>()
          {
              {"id","777"},
              {"serial_number","1234"}
          };
          client.ExecuteNonQuery(sql, param);
      }

      public class TestTable
      {
          public string Id { get; set; }
          public long SerialNumber { get; set; }
      }
相关推荐
NineData3 小时前
数据库迁移总踩坑?用 NineData 迁移评估,提前识别所有兼容性风险
数据库·程序员·云计算
赵渝强老师5 小时前
【赵渝强老师】PostgreSQL中表的碎片
数据库·postgresql
全栈老石9 小时前
拆解低代码引擎核心:元数据驱动的"万能表"架构
数据库·低代码
倔强的石头_1 天前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
不可能的是1 天前
前端 SSE 流式请求三种实现方案全解析
前端·http
jiayou642 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤3 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区4 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1774 天前
《从零搭建NestJS项目》
数据库·typescript
加号35 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql