【开源.NET】轻量级内容管理框架Grissom.CMS(第三篇解析配置文件和数据以转换成 sql)

该篇是 Grissom.CMS 框架系列文章的第三篇, 主要介绍框架用到的核心库 EasyJsonToSql, 把标准的配置文件和数据结构解析成可执行的 sql。
该框架能实现自动化增删改查得益于 EasyJsonToSql 类库的功能:解析配置好的表结构和要进行数据库操作的数据,生成 sql,减少普通的增删改查代码量,简化“数据库 - 后端- 前端”之间的交互。

【开源.NET】 轻量级内容管理框架Grissom.CMS(第一篇分享一个前后端分离框架)
【开源.NET】 轻量级内容管理框架Grissom.CMS(第二篇前后端交互数据结构分析)
【开源.NET】 轻量级内容管理框架Grissom.CMS(第三篇解析配置文件和数据以转换成 sql)

安装

Nuget 命令

Install-Package EasyJsonToSql

或Nuget 界面搜索: EasyJsonToSql
或下载源码(看文章底部)

Kick Start

1) 假设有一张表

CREATE TABLE `BasUser` (
  `Id` bigint(20) NOT NULL AUTO_INCREMENT,
  `Name` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`Id`)
);

2) 后台配置 sqlconfig

    const string sqlJson = @"
    {
        ""Select"":""user.*"",
        ""From"":""BasUser user"",
        ""Where"":{
            ""Fields"":[
                {""Name"":""Name"",""Cp"":""like""}
            ]
        },
        ""OrderBy"":{""Default"":""Id""},
        ""ID"":""Id"",
        ""Table"":""BasUser"",
        ""Insert"":{
            ""Fields"":[
                {""Name"":""Name"",""IsIgnore"":""false""}
                ]
            }
        }
    ";


3) 查询 reqeust url: http://localhost:9819/api/user/get?name=test

        public dynamic Get(string name)
        {
            var dt = new DataTable(); 

            // 用 json 的配置
            var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);
            var sqlSb = new StringBuilder();
            var nameValues = new NameValueCollection();
            nameValues.Add("name", name);
            var builder = new Proxy().ToSelectBuilder(sqlconfig, nameValues);
            var builderData = builder.Data;
            sqlSb.AppendFormat("Select {0} From {1} Where {2}", builderData.Select, builderData.From, builderData.Where);
         
            using (var da = new MySqlDataAdapter(sqlSb.ToString(), cnnStr))
            {
                da.Fill(dt);
            }
            return dt;
        }

返回结果: [{"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"}}]}}

  public dynamic Post()
        {
            var json = "";
            using (StreamReader sr = new StreamReader(HttpContext.Current.Request.InputStream))
            {
                json = sr.ReadToEnd();
            }
            var jobj = JObject.Parse(json); 

            // json 的配置
            var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);
            var builder = new Proxy().ToDbBuilders(sqlconfig, jobj);

            var insertSqlSb = new StringBuilder();
            //获取第一个sqlconfig
            var data = builder[0].Data;
            insertSqlSb.AppendFormat("insert into {0}(", data.TableName);
            var valueSqlSb = new StringBuilder();
            var paras = new List<MySqlParameter>();
            foreach (var dbField in data.Fields)
            {
                // 不是自增的字段才添加
                if (!dbField.IsId)
                {
                    insertSqlSb.AppendFormat("{0}", dbField.DbName);
                    valueSqlSb.AppendFormat("@{0}", dbField.DbName);
                    paras.Add(new MySqlParameter("@" + dbField.DbName, dbField.Value));
                }
            }
            insertSqlSb.AppendFormat(") values({0})", valueSqlSb);

            var affectCount = 0;
            using (var cnn = new MySqlConnection(cnnStr))
            {
                using (var cmd = new MySqlCommand(insertSqlSb.ToString(), cnn))
                {
                    cnn.Open();
                    cmd.Parameters.AddRange(paras.ToArray());
                    affectCount = cmd.ExecuteNonQuery();
                }
            }
            return affectCount;
        }

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

简介

Proxy

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

方法

1) 获取 SelectBuilder

    const string sqlJson = @"
    {
        ""Select"":""user.*"",
        ""From"":""BasUser user"",
        ""Where"":{
            ""Fields"":[
                {""Name"":""Name"",""Cp"":""like""}
            ]
        },
        ""OrderBy"":{""Default"":""Id""},
        ""ID"":""Id"",
        ""Table"":""BasUser"",
        ""Insert"":{
            ""Fields"":[
                {""Name"":""Name"",""IsIgnore"":""false""}
                ]
            }
        }
    ";

    var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);
    var builder = new Proxy().ToSelectBuilder(sqlconfig, nameValues);

2) 获取 DbBuilder


   // 插入数据
    var postJson = @"{""master"":{""inserted"":[{""data"":{""Name"":""abc1""}}]}}";

    var jobj = JObject.Parse(postJson);
    var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);
    var builder = new Proxy().ToDbBuilders(sqlconfig, jobj);

SelectBuilder

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

关键属性

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

常用方法

1) AddWhere: 添加 where 条件 sql,

 builder.AddWhere("And table1.Id = 1");
 builder.AddWhere("And table1.Id = @Id").AddParam("Id",1);

2) AddParam: 添加参数, builder.AddParam("Id",1)

用法演示

var data = builder.Data;
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;

 builder.AddWhere("And table1.Id = 1");
 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);

关键字段
public class SqlConfig
{
    public SqlConfig()
    {
        this.Where = new Where();
        this.Children = new List<SqlConfig>();
        this.OrderBy = new OrderBy();
        this.GroupBy = new GroupBy();
        this.Dependency = new Dependency();
        this.Insert = new Insert();
        this.Update = new Update();
        this.Delete = new Delete();
        this.SingleQuery = new SingleQuery();
        this.Export = new Export();
        this.Import = new Import();
        this.BillCodeRule = new BillCodeRule();
    }

    private string _settingName;
    /// <summary>
    /// 配置名称,默认和表名一致,一般不会用到,方法以后扩展,如一个配置文件出现相同的表时,用来区分不同的配置
    /// </summary>
    public string SettingName
    {
        get
        {
            if (string.IsNullOrEmpty(_settingName))
            {
                _settingName = Table;
            }
            return _settingName;
        }
        set
        {
            _settingName = value;
        }
    }

    #region 查询配置
    /// <summary>
    /// 查询的字段
    /// </summary>
    public string Select { get; set; }
    /// <summary>
    /// 查询的表名以及关联的表名,如 left join, right join
    /// </summary>
    public string From { get; set; }
    /// <summary>
    /// 查询的条件
    /// 前端返回的查询条件,只有出现在这些配置好的字段,才会生成为了 sql 的 where 条件,
    /// 没出现的字段会被忽略
    /// </summary>
    public Where Where { get; set; }
    /// <summary>
    /// 分页时必须会乃至的排序规则
    /// </summary>
    public OrderBy OrderBy { get; set; }

    public GroupBy GroupBy { get; set; }
    /// <summary>
    /// 页码
    /// </summary>
    public int PageNumber { get; set; }
    /// <summary>
    /// 页大小
    /// </summary>
    public int PageSize { get; set; }


    #endregion 查询配置

    /// <summary>
    /// 指定该配置所属于的表
    /// </summary>
    public string Table { get; set; }

    #region 增删改配置
    /// <summary>
    /// 对应前端返回的 json 格式数据的键名
    /// e.g.: {master:{inserted:[{data:{}}]}} 中的 master 就是这里要对应的 JsonName
    /// 注意默认主表的 jsonName 是 master, 所以主表一般可省略不写, 但子表必须得指定
    /// </summary>
    public string JsonName { get; set; }
    /// <summary>
    /// 自增的字段,指定了自增的字段,在 insert 时会自动忽略该字段
    /// </summary>
    public string ID { get; set; }
    /// <summary>
    /// 主键, 在保存成功后会返回主键的值; 
    /// </summary>
    public string PKs { get; set; }
    /// <summary>
    /// 唯一值的字段,对应数据库 unique, 在 insert,update 前会判断是否已存在
    /// </summary>
    public string Uniques { get; set; }
    /// <summary>
    /// 唯一值的字段的值是否允许为空
    /// </summary>
    public string UniqueAllowEmptys { get; set; }
    /// <summary>
    /// 所属的父级配置, 在 xml 中不用指定,程序会自动分析
    /// </summary>
    public SqlConfig Parent { get; set; }
    /// <summary>
    /// 包含的子级配置, 即子表的配置,需要在 xml 中配置
    /// </summary>
    public List<SqlConfig> Children { get; set; }
    /// <summary>
    /// 依赖父表的字段
    /// </summary>
    public Dependency Dependency { get; set; }
    /// <summary>
    /// insert 的配置
    /// </summary>
    public Insert Insert { get; set; }
    /// <summary>
    /// update 的配置
    /// </summary>
    public Update Update { get; set; }
    /// <summary>
    /// delete 的配置
    /// </summary>
    public Delete Delete { get; set; }
    #endregion
    /// <summary>
    /// 单条记录查询的配置,一般用在配置列表双击弹出那条记录的获取的 sql 
    /// </summary>
    public SingleQuery SingleQuery { get; set; }
    /// <summary>
    /// 导出配置
    /// </summary>
    public Export Export { get; set; }
    /// <summary>
    /// 导入配置
    /// </summary>
    public Import Import { get; set; }
    /// <summary>
    /// 是否物理删除?
    /// </summary>
    public bool DeleteAnyway { get; set; }
    /// <summary>
    /// 表单编码的生成配置
    /// </summary>
    public BillCodeRule BillCodeRule { get; set; }


}
用法

可以用 xml、json 或对象来配置表关系,如果用了 xml 或 json配置, 把它反射成对象即可。

1) xml 配置

string sqlXml = @"
<SqlConfig>
    <Select>
        user.*
    </Select>
    <From>
        BasUser user
    </From>
    <Where>
        <Fields>
            <Field Name=""Name"" Cp=""like""></Field>
        </Fields>
    </Where>
    <OrderBy>
        <Default>Id</Default>
    </OrderBy>
    <IDs>Id</IDs>
    <PKs>Id</PKs>
    <Table>BasUser</Table>
    <Insert>
        <Fields>
            <Field Name=""Name"" IsIgnore=""false""></Field>
        </Fields>
    </Insert>
</SqlConfig>
            ";


2) json 配置

 string sqlJson = @"
{
    ""Select"":""user.*"",
    ""From"":""BasUser user"",
    ""Where"":{
        ""Fields"":[
            {""Name"":""Name"",""Cp"":""like""}
        ]
    },
    ""OrderBy"":{""Default"":""Id""},
    ""ID"":""Id"",
    ""PKs"":""Id"",
    ""Table"":""BasUser"",
    ""Insert"":{
        ""Fields"":[
            {""Name"":""Name"",""IsIgnore"":""false""}
            ]
        }
    }
";
var sqlconfig = JsonConvert.DeserializeObject<SqlConfig>(sqlJson);
Grissom.CMS框架源码 https://github.com/grissomlau/Grissom.CMS

初始化登录名:admin, 密码: 123

EasyJsonToSql类库源码 https://github.com/grissomlau/EasyJsonToSql

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值