UMC ORM 数据访问

Apiumc

One Code移动开发架构

UMC ORM 是我们UMC架构的数据访问层,已经用java.net实现,他简化了数据库访问的方式方法,极大的提高后台工程师的coding效率,有效减少70%的数据访问代码 还充分提高可读性
在我们后台工程师,大部分的开发都是与数据库打交道,与数据库的开发是整个后台的重中之重,在这块内容,如何提高,有点工作经验都有采用一个开发数据访问架构来加快效率,这此架构强行把业务逻辑与数据层分开,美其名曰分层开发,数据操作本身就是业务逻辑的一种,采用强行分开,会导致代码可读性大大减弱,特别时间一长,或者人员离职交接,更能体现这个问题;还有乙方面对客户现场各样的数据库,如果有一个与数据库无关的实现数据访问,将能很好的减轻的开发强度,这此内容都是困绕我们的后台工程师,拥有这块内容解决方案,相信能大大提高工程师的产能,解放了人员的生产力。
UMC架构,从实战中回来,特意优化数据库访问方式,让我们采用链式操作就能完成更新、删除、插入,整个过程都不用写SQL,采用链式操作,看上去更像自然语言表达,大大提供的可读性,在安全上,全面排除的SQL注入风险,在coding的代码量上可以说,能有效帮助后端工程师少写70%与数据库访问的代码,还提高的可读性,感觉非常有必要单独拿拿出来与大家讲解,UMC ORM也是一套实体管理SQL的方式方法,目前已实现了java.net的实体链式访问方式层,下面我们就用java实例与大家讲解,各个方法.net都有,执行结果都是一致的;同样 UMC ORM为各个数据库提供一致操作方式,现在的业务逻辑,不用再考虑使用什么数据库了,不再考虑怎么划分访问层了,从此你发现,原来访问数据coding也可以这样优美。
实例讲解实现
下面我就用用户实体类做实例讲解:
//用户实体类
public class User {
    public String Username{get;set;}
    public String Alias{get;set;};
    public int? Flags{get;set;};
    public DateTime? RegistrTime{get;set;};
    public DateTime? ActiveTime{get;set;};
    public Guid? Id{get;set;};
}
 
注意:UMC ORM的实体类字段类型要使用引用类型,不能使用值类型
实体插入
看一我们的实现链式访问,是怎么样完成一个用户注册的呢,看下面代码:
    var mapUser = new UMC.Web.WebMeta();
    User user = new User();
    UMC.Data.Reflection.SetProperty(user, mapUser.GetDictionary());//实体赋值

    //数据库操作
    Database.Instance().ObjectEntity<User>()
    .Where.And().Equal(new User { Username = user.Username })
    .Entities.IFF(e => e.Count() == 0, e => e.Insert(user));
    //代码完成了重名检测,再插入到数据库
从上面完成了用户注册了,我的数据库访问简单明了,再不用强行多出多层来来实现,架构会自己生成对应的SQL来插入数据库,这生成 的SQL是采用SQL92标准,只要支持SQL92标准的数据库都支持,市面上没有不支持SQL92标准的关系性数据库,所有我们就也完成了与数据库无关的操作了。
下面我们再进行查询分布,排序,分组,看我们此架构是怎么完成的
实体更新、查询、分组
  var entity = Database.Instance().ObjectEntity<User>();
    //这是like查询,会自动加入%号 
    entity.Where.And().Like(new User { Alias = "吴顺明" });
    //或下面的
    //entity.Where.And().Like("Alias", "吴顺明");

    //这是排序 
    entity.Order.Asc(new User { RegistrTime = DateTime.MaxValue });
    //或下面的
    //entity.Order.Asc("RegistrTime");

    ///分页查询
    User[] users = entity.Query(0, 12);
    //自动生成SQL分页查询,返回此条件下的0-12行用户

    //这是分组查询 
    entity.GroupBy(new User { Flags = 0 }).Max(new User { RegistrTime = DateTime.MaxValue }).Query();
    //查看不同的Flags最近注册时间

    //包含多条件,例如 在此条件同时Flags=2或者1的也就是Username like '%d%' and (Flags=2 or Flags=1);
    entity.Where.Contains().And().Equal("Flags", 2).Or().Equal("Flags", 1);

    entity.Update(new User { Flags = 0 });//只会更新非空字段

    //把非空字段插入到数据库,可插入多个
    entity.Insert(new User());

    //删除条件数据,返回删除的条数
    entity.Delete();
从上面实例说可以看出,我们是在where条件可以采用实体非null字段来进行条件赋值,也可以直接字段赋值,在其他地方采用非null字段确认采用那此字段来参与运行。还有更多的方法操作实现数据与数据库打交通,基本我们的应用开发就不用再写SQL语句,SQL不会再散落在代码中,大大的提可读性,和稳定性,现在我就不一一例举,最好的掌握方式就是实践。
上面代码,是不是更像自然语言表达,后期我们维护起来就简单高效,现在是不是有信心提高自己的产能,不再996,从现在做好朝九晚五的技术人生。
SQL语句
UMC ORM,他是个优秀的数据库访问组件,当前也支持我们写SQL了,他让大家的SQL写的更简单,
var sqler = Database.Instance().Sqler();
var user = sqler.ExecuteSingle("select *FROM User where (Username={0} Or Alias={0}) and Flags={1}", "吴顺明", 1);

 //也可以绑定实体类查询

User user = sqler.ExecuteSingle<User>("select *FROM User where (Username={0} Or Alias={0}) and Flags={1}", "吴顺明", 1);
从上面,我们可以得知,UMC ORM的 Sqler 访问数据库,采用的格式索引传参方式,是不是比我们传统的方式更优美,更安全呢,连SQL的可读性都更高。
Sqler 中有好几种与数据库访问的方法,如下
 
        /// <summary>
        ///  执行 SQL 语句。
        /// </summary>
        /// <param name="sqlText">索引格式化脚本</param>
        /// <param name="paramers">参数</param>
        /// <returns>返回影响行数</returns>
        int ExecuteNonQuery(string sqlText, params object[] paramers);
        /// <summary>
        ///  执行 SQL 语句。
        /// </summary>
        /// <param name="sqlText">字典格式化脚本</param>
        /// <param name="paramKeys">字典参数</param>
        /// <returns>返回影响行数</returns>
        int ExecuteNonQuery(string sqlText, System.Collections.IDictionary paramKeys);
        /// <summary>
        ///  执行查询,并返回查询所返回的结果集中第一行的第一列。所有其他的列和行将被忽略。
        /// </summary>
        /// <param name="sqlText">索引格式化脚本</param>
        /// <param name="paramers">参数</param>
        /// <returns>结果集中第一行的第一列。</returns>
        object ExecuteScalar(string sqlText, params object[] paramers);

        /// <param name="sqlText">字典格式化脚本</param>
        /// <param name="paramKeys">字典参数</param>
        object ExecuteScalar(string sqlText, System.Collections.IDictionary paramKeys);
        /// <summary>
        ///  在 System.Data.DataSet 中添加或刷新行以匹配使用 System.Data.DataSet 名称的数据源中的行,并创建一个 System.Data.DataTable。
        /// </summary>
        /// <param name="sqlText">索引格式化脚本</param>
        /// <param name="paramers">参数</param>
        /// <returns>包含从数据源返回的架构信息的 System.Data.DataTable 对象。</returns>
        System.Data.DataTable ExecuteTable(string sqlText, params object[] paramers);
        /// <param name="sqlText">字典格式化脚本</param>
        /// <param name="paramKeys">字典参数</param>
        System.Data.DataTable ExecuteTable(string sqlText, System.Collections.IDictionary paramKeys);
        /// <summary>
        /// 返回分页的数据表
        /// </summary>
        /// <param name="sqlText">sql查询文本</param>
        /// <param name="start">开始位置</param>
        /// <param name="limit">记录数</param>
        /// <param name="paramers">参数</param>
        /// <returns></returns>
        System.Data.DataTable Execute(string sqlText, int start, int limit, params object[] paramers);
        /// <param name="sqlText">字典格式化脚本</param>
        /// <param name="start">开始位置</param>
        /// <param name="limit">记录数</param>
        /// <param name="paramKeys">字典参数</param>
        System.Data.DataTable Execute(string sqlText, int start, int limit, System.Collections.IDictionary paramKeys);
        /// <summary>
        /// 返回DataSet,注意查询不能包含20个表集
        /// </summary>
        /// <param name="sqlText">索引格式化脚本</param>
        /// <param name="paramers">参数</param>
        /// <returns>返回一个DataSet</returns>
        System.Data.DataSet ExecuteDataSet(string sqlText, params object[] paramers);
        /// <param name="sqlText">字典格式化脚本</param>
        /// <param name="paramKeys">字典参数</param>
        System.Data.DataSet ExecuteDataSet(string sqlText, System.Collections.IDictionary paramKeys);
        /// <summary>
        /// 返回查询的第一行,并把他字典
        /// </summary>
        /// <param name="sqlText">索引格式化脚本</param>
        /// <param name="paramers">参数</param>
        /// <returns></returns>
        System.Collections.IDictionary ExecuteSingle(string sqlText, params object[] paramers);
        /// <param name="sqlText">字典格式化脚本</param>
        /// <param name="paramKeys">字典参数</param>
        System.Collections.IDictionary ExecuteSingle(string sqlText, System.Collections.IDictionary paramKeys);

        /// <summary>
        /// 把查询到的字段转化对应的单个实体
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="sqlText">SQL查询文本</param>
        /// <param name="paramers">参数</param>
        /// <returns></returns>
        T ExecuteSingle<T>(string sqlText, params object[] paramers);
        /// <param name="sqlText">字典格式化脚本</param>
        /// <param name="paramKeys">字典参数</param>
        T ExecuteSingle<T>(string sqlText, System.Collections.IDictionary paramKeys);
        /// <summary>
        /// 把查询到的字段转化对应的实体集
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="sqlText">SQL查询文本</param>
        /// <param name="paramers">参数</param>
        /// <returns></returns>
        List<T> Execute<T>(string sqlText, params object[] paramers);
        /// <summary>
        /// 把查询到的字段转化对应的实体集
        /// </summary>
        /// <param name="sqlText">字典格式化脚本</param>
        /// <param name="paramKeys">字典参数</param>
        List<T> Execute<T>(string sqlText, System.Collections.IDictionary paramKeys);
        /// <summary>
        /// 自定义处理一个查询只读的结果集
        /// </summary>
        /// <param name="sqlText">SQL查询文本</param>
        /// <param name="reader">处理数据集代理</param>
        /// <param name="paramers">参数</param>
        void Execute<T>(string sqlText, DataReader<T> reader, params object[] paramers);
        /// <summary>
        /// 返回分页的数据表
        /// </summary>
        /// <param name="sqlText">sql查询文本</param>
        /// <param name="start">开始位置</param>
        /// <param name="limit">记录数</param>
        /// <param name="reader">处理数据集代理</param>
        /// <param name="paramers">参数</param>
        /// <returns></returns>
        void Execute<T>(string sqlText, int start, int limit, DataReader<T> reader, params object[] paramers);

        /// <summary>
        /// 返回分页的数据表
        /// </summary>
        /// <param name="sqlText">sql查询文本</param>
        /// <param name="start">开始位置</param>
        /// <param name="limit">记录数</param>
        /// <param name="paramers">参数</param>
        /// <returns></returns>
        List<T> Execute<T>(string sqlText, int start, int limit, params object[] paramers);
        /// <summary>
        /// 返回分页的数据表
        /// </summary>
        /// <param name="sqlText">字典格式化脚本</param>
        /// <param name="start">开始位置</param>
        /// <param name="limit">记录数</param>
        /// <param name="paramKeys">字典参数</param>
        List<T> Execute<T>(string sqlText, int start, int limit, System.Collections.IDictionary paramKeys);
        /// <summary>
        /// 自定义处理一个查询只读的结果集
        /// </summary>
        /// <param name="sqlText">SQL查询文本</param>
        /// <param name="reader">处理数据集代理</param>
        /// <param name="paramers">参数</param>
        void Execute(string sqlText, DataReader reader, params object[] paramers);


        /// <summary>
        /// 处理分页的数据集,注意:此DataReader是已经Read过的,请在reader中不要调用Read方法
        /// </summary>
        /// <param name="sqlText">sql查询文本</param>
        /// <param name="start">开始位置</param>
        /// <param name="limit">记录数</param>
        /// <param name="reader">处理数据集代理</param>
        /// <param name="paramers">参数</param>
        /// <returns></returns>
        void Execute(string sqlText, int start, int limit, DataRecord reader, params object[] paramers);
        /// <summary>
        /// 处理分页的数据集,注意:此DataReader是已经Read过的,请在reader中不要调用Read方法
        /// </summary>
        /// <param name="sqlText">字典格式化脚本</param>
        /// <param name="start">开始位置</param>
        /// <param name="limit">记录数</param>
        /// <param name="reader">处理数据集代理</param>
        /// <param name="paramKeys">字典参数</param>
        void Execute(string sqlText, int start, int limit, DataRecord reader, System.Collections.IDictionary paramKeys);

        /// <summary>
        /// 自定义处理一个查询只读的结果集
        /// </summary>
        /// <param name="sqlText">SQL查询文本</param>
        /// <param name="reader">处理数据集代理</param>
        /// <param name="paramKeys">参数字典</param>
        void Execute(string sqlText, DataReader reader, System.Collections.IDictionary paramKeys);
        /// <summary>
        /// 批量执行脚本,返回每个脚本的返回影响行数
        /// </summary>
        /// <param name="paramKeys"></param>
        /// <param name="sqlTexts"></param>
        /// <returns></returns>
        int[] ExecuteNonQuery(System.Collections.IDictionary paramKeys, params string[] sqlTexts);
        /// <summary>
        /// 批量执行脚本,返回每个脚本的返回影响行数
        /// </summary>
        /// <param name="scripts"></param>
        /// <returns></returns>
        int[] ExecuteNonQuery(params Script[] scripts);

        /// <summary>
        /// 批量执行脚本 , 当predicate返回true才执行action,并运行在action中设置script对象的脚本参数
        /// </summary>
        /// <param name="predicate">当predicate返回为true时,则会回调以Script,参数初始化cmdexec</param>
        /// <param name="cmdexec">执行的脚本</param>
        void Execute(System.Predicate<Script> predicate, System.Action<System.Data.Common.DbCommand> cmdexec);
从中,可我看到我们读起数据的方式应有尽有,简化的不只是一点点。

管理员 | 阅读(41) | 评论(0)

评论
点赞
已读
暂无评论