项目作者: grissomlau

项目描述 :
把 json 结构数据解析成标准的 sql, 实现标准化和自动化的增删改查
高级语言: C#
项目地址: git://github.com/grissomlau/EasyJsonToSql.git
创建时间: 2017-02-28T09:20:10Z
项目社区:https://github.com/grissomlau/EasyJsonToSql

开源协议:MIT License

下载


EasyJsonToSql

把 json 结构数据解析成标准的 sql, 实现标准化和自动化的增删改查

Kick Start

  1. 假设有一张表
    1. CREATE TABLE `BasUser` (
    2. `Id` bigint(20) NOT NULL AUTO_INCREMENT,
    3. `Name` varchar(64) DEFAULT NULL,
    4. PRIMARY KEY (`Id`)
    5. );
  2. 后台配置 sqlconfig

    1. const string sqlJson = @"
    2. {
    3. ""Select"":""user.*"",
    4. ""From"":""BasUser user"",
    5. ""Where"":{
    6. ""Fields"":[
    7. {""Name"":""Name"",""Cp"":""like""}
    8. ]
    9. },
    10. ""OrderBy"":{""Default"":""Id""},
    11. ""ID"":""Id"",
    12. ""Table"":""BasUser"",
    13. ""Insert"":{
    14. ""Fields"":[
    15. {""Name"":""Name"",""IsIgnore"":""false""}
    16. ]
    17. }
    18. }
    19. ";
  3. 查询 reqeust url: `http://localhost:9819/api/user/get?name=test

    1. public dynamic Get(string name)
    2. {
    3. var dt = new DataTable();
    4. // 用 json 的配置
    5. var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);
    6. var sqlSb = new StringBuilder();
    7. var nameValues = new NameValueCollection();
    8. nameValues.Add("name", name);
    9. var builder = new Proxy().ToSelectBuilder(sqlconfig, nameValues);
    10. var builderData = builder.Data;
    11. sqlSb.AppendFormat("Select {0} From {1} Where {2}", builderData.Select, builderData.From, builderData.Where);
    12. using (var da = new MySqlDataAdapter(sqlSb.ToString(), cnnStr))
    13. {
    14. da.Fill(dt);
    15. }
    16. return dt;
    17. }

    返回结果: [{"Id":1,"Name":"test4"},{"Id":2,"Name":"test1"},{"Id":3,"Name":"test1"},{"Id":4,"Name":"test7"}]

  4. 新增 post url: http://localhost:9819/api/user/post , form data: {"master":{"inserted":[{"data":{"Name":"test1"}}]}}
  1. public dynamic Post()
  2. {
  3. var json = "";
  4. using (StreamReader sr = new StreamReader(HttpContext.Current.Request.InputStream))
  5. {
  6. json = sr.ReadToEnd();
  7. }
  8. var jobj = JObject.Parse(json);
  9. // json 的配置
  10. var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);
  11. var builder = new Proxy().ToDbBuilders(sqlconfig, jobj);
  12. var insertSqlSb = new StringBuilder();
  13. //获取第一个sqlconfig
  14. var data = builder[0].Data;
  15. insertSqlSb.AppendFormat("insert into {0}(", data.TableName);
  16. var valueSqlSb = new StringBuilder();
  17. var paras = new List<MySqlParameter>();
  18. foreach (var dbField in data.Fields)
  19. {
  20. // 不是自增的字段才添加
  21. if (!dbField.IsId)
  22. {
  23. insertSqlSb.AppendFormat("{0}", dbField.DbName);
  24. valueSqlSb.AppendFormat("@{0}", dbField.DbName);
  25. paras.Add(new MySqlParameter("@" + dbField.DbName, dbField.Value));
  26. }
  27. }
  28. insertSqlSb.AppendFormat(") values({0})", valueSqlSb);
  29. var affectCount = 0;
  30. using (var cnn = new MySqlConnection(cnnStr))
  31. {
  32. using (var cmd = new MySqlCommand(insertSqlSb.ToString(), cnn))
  33. {
  34. cnn.Open();
  35. cmd.Parameters.AddRange(paras.ToArray());
  36. affectCount = cmd.ExecuteNonQuery();
  37. }
  38. }
  39. return affectCount;
  40. }

上面可看到 get 和 post 方法是脱离业务的,所有业务都在 sqlJson 配置和 前端返回的 json 数据,从而实现了后台配置化操作数据库,不需创建额外的对象,就可以把前端返回的json 数据, 直接持久化到数据库了。

简介

Proxy

这个类是 EasyJsonToSql 入口,用来获取 SelectBuilder 和 DbBuilder 对象。

方法

  1. 获取 SelectBuilder
  1. const string sqlJson = @"
  2. {
  3. ""Select"":""user.*"",
  4. ""From"":""BasUser user"",
  5. ""Where"":{
  6. ""Fields"":[
  7. {""Name"":""Name"",""Cp"":""like""}
  8. ]
  9. },
  10. ""OrderBy"":{""Default"":""Id""},
  11. ""ID"":""Id"",
  12. ""Table"":""BasUser"",
  13. ""Insert"":{
  14. ""Fields"":[
  15. {""Name"":""Name"",""IsIgnore"":""false""}
  16. ]
  17. }
  18. }
  19. ";
  20. var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);
  21. var builder = new Proxy().ToSelectBuilder(sqlconfig, nameValues);
  1. 获取 DbBuilder
  1. // 插入数据
  2. var postJson = @"{""master"":{""inserted"":[{""data"":{""Name"":""abc1""}}]}}";
  3. var jobj = JObject.Parse(postJson);
  4. var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);
  5. var builder = new Proxy().ToDbBuilders(sqlconfig, jobj);

SelectBuilder

该类负责处理查询分析,把 json 转换成查询的 sql。

关键属性

  1. Data[SelectBuilderData]: 生成的 sql 对象。

常用方法

  1. AddWhere: 添加 where 条件 sql,
  1. builder.AddWhere("And table1.Id = 1");
  2. builder.AddWhere("And table1.Id = @Id").AddParam"Id",1);
  1. AddParam: 添加参数, builder.AddParam("Id",1)

用法演示

  1. var data = builder.Data;
  2. var sql = string.format("Select {0} From {1} Where {2}", data.Select, data.From, data.Where);

DbBuilder

该类负责处理增删改分析,把 json 转换成增删改的 sql。

关键属性

  1. Data[BuilderData]: 生成的 sql 对象。

常用方法

  1. AddChild: 添加子表对象。
  2. AddWhere: 添加 where 条件 sql;
    1. builder.AddWhere("And table1.Id = 1");
    2. builder.AddWhere("And table1.Id = @Id").AddParam("Id", 1);
  3. AddParam: 添加参数, builder.AddParam("Id",1);

SqlConfig

该类保存 select、from、where、insert、update、delete, 以及子表、依赖关系、自增字段、主键等 sql 相关对象,标准化 sql 配置以便脱离具体业务。
用来初始化 SelectBuilder 和 DBBuilder, 实现标准化的增删改查操作。
上面就是用 json 配置的来反射出 SqlConfig, var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);

关键字段

  1. public class SqlConfig
  2. {
  3. public SqlConfig()
  4. {
  5. this.Where = new Where();
  6. this.Children = new List<SqlConfig>();
  7. this.OrderBy = new OrderBy();
  8. this.GroupBy = new GroupBy();
  9. this.Dependency = new Dependency();
  10. this.Insert = new Insert();
  11. this.Update = new Update();
  12. this.Delete = new Delete();
  13. this.SingleQuery = new SingleQuery();
  14. this.Export = new Export();
  15. this.Import = new Import();
  16. this.BillCodeRule = new BillCodeRule();
  17. }
  18. private string _settingName;
  19. /// <summary>
  20. /// 配置名称,默认和表名一致,一般不会用到,方法以后扩展,如一个配置文件出现相同的表时,用来区分不同的配置
  21. /// </summary>
  22. public string SettingName
  23. {
  24. get
  25. {
  26. if (string.IsNullOrEmpty(_settingName))
  27. {
  28. _settingName = Table;
  29. }
  30. return _settingName;
  31. }
  32. set
  33. {
  34. _settingName = value;
  35. }
  36. }
  37. #region 查询配置
  38. /// <summary>
  39. /// 查询的字段
  40. /// </summary>
  41. public string Select { get; set; }
  42. /// <summary>
  43. /// 查询的表名以及关联的表名,如 left join, right join
  44. /// </summary>
  45. public string From { get; set; }
  46. /// <summary>
  47. /// 查询的条件
  48. /// 前端返回的查询条件,只有出现在这些配置好的字段,才会生成为了 sql 的 where 条件,
  49. /// 没出现的字段会被忽略
  50. /// </summary>
  51. public Where Where { get; set; }
  52. /// <summary>
  53. /// 分页时必须会乃至的排序规则
  54. /// </summary>
  55. public OrderBy OrderBy { get; set; }
  56. public GroupBy GroupBy { get; set; }
  57. /// <summary>
  58. /// 页码
  59. /// </summary>
  60. public int PageNumber { get; set; }
  61. /// <summary>
  62. /// 页大小
  63. /// </summary>
  64. public int PageSize { get; set; }
  65. #endregion 查询配置
  66. /// <summary>
  67. /// 指定该配置所属于的表
  68. /// </summary>
  69. public string Table { get; set; }
  70. #region 增删改配置
  71. /// <summary>
  72. /// 对应前端返回的 json 格式数据的键名
  73. /// e.g.: {master:{inserted:[{data:{}}]}} 中的 master 就是这里要对应的 JsonName
  74. /// 注意默认主表的 jsonName 是 master, 所以主表一般可省略不写, 但子表必须得指定
  75. /// </summary>
  76. public string JsonName { get; set; }
  77. /// <summary>
  78. /// 自增的字段,指定了自增的字段,在 insert 时会自动忽略该字段
  79. /// </summary>
  80. public string ID { get; set; }
  81. /// <summary>
  82. /// 主键, 在保存成功后会返回主键的值;
  83. /// </summary>
  84. public string PKs { get; set; }
  85. /// <summary>
  86. /// 唯一值的字段,对应数据库 unique, 在 insert,update 前会判断是否已存在
  87. /// </summary>
  88. public string Uniques { get; set; }
  89. /// <summary>
  90. /// 唯一值的字段的值是否允许为空
  91. /// </summary>
  92. public string UniqueAllowEmptys { get; set; }
  93. /// <summary>
  94. /// 所属的父级配置, 在 xml 中不用指定,程序会自动分析
  95. /// </summary>
  96. public SqlConfig Parent { get; set; }
  97. /// <summary>
  98. /// 包含的子级配置, 即子表的配置,需要在 xml 中配置
  99. /// </summary>
  100. public List<SqlConfig> Children { get; set; }
  101. /// <summary>
  102. /// 依赖父表的字段
  103. /// </summary>
  104. public Dependency Dependency { get; set; }
  105. /// <summary>
  106. /// insert 的配置
  107. /// </summary>
  108. public Insert Insert { get; set; }
  109. /// <summary>
  110. /// update 的配置
  111. /// </summary>
  112. public Update Update { get; set; }
  113. /// <summary>
  114. /// delete 的配置
  115. /// </summary>
  116. public Delete Delete { get; set; }
  117. #endregion
  118. /// <summary>
  119. /// 单条记录查询的配置,一般用在配置列表双击弹出那条记录的获取的 sql
  120. /// </summary>
  121. public SingleQuery SingleQuery { get; set; }
  122. /// <summary>
  123. /// 导出配置
  124. /// </summary>
  125. public Export Export { get; set; }
  126. /// <summary>
  127. /// 导入配置
  128. /// </summary>
  129. public Import Import { get; set; }
  130. /// <summary>
  131. /// 是否物理删除?
  132. /// </summary>
  133. public bool DeleteAnyway { get; set; }
  134. /// <summary>
  135. /// 表单编码的生成配置
  136. /// </summary>
  137. public BillCodeRule BillCodeRule { get; set; }
  138. }

用法

  1. xml 配置

    1. string sqlXml = @"
    2. <SqlConfig>
    3. <Select>
    4. user.*
    5. </Select>
    6. <From>
    7. BasUser user
    8. </From>
    9. <Where>
    10. <Fields>
    11. <Field Name=""Name"" Cp=""like""></Field>
    12. </Fields>
    13. </Where>
    14. <OrderBy>
    15. <Default>Id</Default>
    16. </OrderBy>
    17. <IDs>Id</IDs>
    18. <PKs>Id</PKs>
    19. <Table>BasUser</Table>
    20. <Insert>
    21. <Fields>
    22. <Field Name=""Name"" IsIgnore=""false""></Field>
    23. </Fields>
    24. </Insert>
    25. </SqlConfig>
    26. ";
  2. json 配置
    1. string sqlJson = @"
    2. {
    3. ""Select"":""user.*"",
    4. ""From"":""BasUser user"",
    5. ""Where"":{
    6. ""Fields"":[
    7. {""Name"":""Name"",""Cp"":""like""}
    8. ]
    9. },
    10. ""OrderBy"":{""Default"":""Id""},
    11. ""ID"":""Id"",
    12. ""PKs"":""Id"",
    13. ""Table"":""BasUser"",
    14. ""Insert"":{
    15. ""Fields"":[
    16. {""Name"":""Name"",""IsIgnore"":""false""}
    17. ]
    18. }
    19. }
    20. ";
    21. var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);