1、框架简介 http://www.cnblogs.com/qixiaoyizhan/p/7417467.html
html
2、框架使用方式介绍 http://www.cnblogs.com/qixiaoyizhan/p/7418058.htmlgit
3、框架性能对比 近期补充程序员
ORM(Object Relational Mapping)框架采用元数据来描述对象一关系映射细节,框架根据对象之间的关系以及对象自身的属性能够框架内部自动生成sql语句,简化了程序员的sql开发,极大地提高了编码效率,同时也使得程序错误代码的发生率下降,提升程序的可读性,在使用上相较传统的DAO Sql语句的写法有极大的优点。github
任何优秀的新事物都是一把双刃剑,有利就有弊,关键看使用这把剑的人如何去操做。不尽其然,ORM框架也是有碧如执行比较慢缺点,可是舍弃性能的同时提高开发效率,某些程度上也是能够广为接受的,所以,ORM开发的重点又突出在了易使用和高性能两个方面。web
今天,我这里推出一款本人花费一周时间独立开发的ORM框架:Bantina 初版sql
该框架采用特性的方式作数据表关系映射,吸纳了Microsoft的EntityFramework的一些思想,而且简化了EntityFramework的功能,同时极力向原生的sql语句靠拢,以提升程序执行效率。自带缓存的支持提高查询效率,做为Bantina初版,咱们先暂时支持SqlServer数据库的操做,在后续的版本升级中,逐步开放对Mysql、Oracle甚至是NoSql的支持。数据库
下面咱们对Bantina 1.0 作详细介绍。缓存
介绍以前,咱们先在本地建立一个数据库,做为演示使用实例以及数据库查询对比的操做对象,该数据库结构以下图所示:app
数据库名:DB_QX_Frame_Test框架
其中包含三张表:TB_ClassName (班级名称)
TB_People (人员表)
TB_Score (分数表)
表之间的关系是TB_People中有TB_ClassName的外键
咱们先对Bantina1.0 ORM框架支持的功能作列表介绍,突出框架封装的简单操做方法以及框架支持的简介操做的特性。
数据库实体类继承自框架Bantina,而后在构造方法里面提供数据库链接字符串,有多种参数可供选择。
1 public class DB_QX_Frame_Test : Bantina 2 { 3 public DB_QX_Frame_Test() : base("data source=.;initial catalog=DB_QX_Frame_Test;persist security info=True;user id=Sa;password=Sa123456;MultipleActiveResultSets=True;App=EntityFramework") { } 4 }
在数据库初始化的同时,传入的数据库链接字符串能够进行读写库的分离设置,极大方便了数据库读写分离的操做(框架原生支持读写分离)。
若是传递单条链接字符串,那么读写库使用一个,至关于关闭读写分离。
该特性沿袭了EntityFramework的特色,可是并不必定追求实体类必定要和数据库结构彻底一致,不存在匹配一致性检测,全部的数据库表字段使用特性标签的方式标记识别。
在主外键上,直接将外键表的属性添加进主表便可,并添加标签[ForeignTable]声明外键表便可。
1 [Table(TableName = "TB_People")] 2 public class TB_People 3 { 4 [Key] 5 public Guid Uid { get; set; } 6 [Column] 7 public string Name { get; set; } 8 [Column] 9 public int Age { get; set; } 10 [Column] 11 [ForeignKey] 12 public int ClassId { get; set; } 13 [ForeignTable] 14 public TB_ClassName TB_ClassName { get; set; } 15 } 16 17 [Table(TableName = "TB_ClassName")] 18 public class TB_ClassName 19 { 20 // PK(identity) 21 [Key] 22 public Int32 ClassId { get; set; } 23 // 24 [Column] 25 public String ClassName { get; set; } 26 }
这里标签Table能够支持数据库的表名和实体类的表名不一致,在参数TableName声明数据库真实的表名便可。
在alpha版本里,字段也是支持修改并配置的,可是为了支持后续的特性Lambda表达式参数,将此功能去掉,以便简化框架代码,所以,字段名称是须要类属性和表的字段彻底一致的状况下进行操做的。
这里字段的标签Key以及Column也是有必要的,在后续的使用中会进行逐步讲解。这里你们可能会有疑问,每一个属性手动写标签会比较多,比较麻烦,这里有专门匹配的代码生成器进行生成,避免了手动添加的繁琐。
Sql查询的耗时主要出如今大量数据的查询上,一套系统若是没有良好的设计,每次获取数据都要进行大量耗时查询操做,那么系统的用户体验感将会降到极低,直接影响到了用户的使用心情。
Bantina框架原生自带了缓存特性,在对数据库的查询操做时,并不会直接对全部数据进行缓存,只会对当前的查询操做执行的结果进行缓存,当对操做的表进行增删改操做时,又会智能识别下次从新获取数据并覆盖缓存。这样避免了全表数据缓存查询的耗时时间,又能在数据查询的缓存支持上获得很好的效率。
缓存的智能消除,极力维护了系统数据一致性,避免了等待缓存过时形成的数据尴尬问题。
这里查询同一组集合数据的三段一样的代码耗时展现(单位:毫秒):
能够看出,第一次是从数据库进行获取数据,并添加到缓存,第二次和第三次是从缓存中获取的数据,速度很是快;
原生支持各类经常使用查询结果,不须要后续进行遍历等格式转化操做,一切以对象及集合说话,彻底符合面向对象行为方式。
这里的Query查询方法包含了Entity<T>单个实体对象的查询以及Entities<T>多个实体对象List列表的查询。
1 TEntity QueryEntity<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class; 2 List<TEntity> QueryEntities<TEntity>() where TEntity : class; 3 List<TEntity> QueryEntities<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class;
这里我展现Bantina经常使用的方法接口:
1 public interface IBantina 2 { 3 Task<bool> Add<TEntity>(TEntity entity) where TEntity : class; 4 Task<bool> Update<TEntity>(TEntity entity) where TEntity : class; 5 Task<bool> Update<TEntity>(TEntity entity, Expression<Func<TEntity, bool>> where) where TEntity : class; 6 Task<bool> Delete<TEntity>(TEntity entity) where TEntity : class; 7 Task<bool> Delete<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class; 8 bool QueryExist<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class; 9 int QueryCount<TEntity>() where TEntity : class; 10 int QueryCount<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class; 11 TEntity QueryEntity<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class; 12 List<TEntity> QueryEntities<TEntity>() where TEntity : class; 13 List<TEntity> QueryEntities<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class; 14 List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, bool isDESC = false) where TEntity : class; 15 List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, Expression<Func<TEntity, bool>> where, bool isDESC = false) where TEntity : class; 16 List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, out int count, bool isDESC = false) where TEntity : class; 17 List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, Expression<Func<TEntity, bool>> where, out int count, bool isDESC = false) where TEntity : class; 18 DataTable QueryDataTable<TEntity>(string sql, params SqlParameter[] parms) where TEntity : class; 19 DataSet QueryDataDataSet<TEntity>(string sql, params SqlParameter[] parms) where TEntity : class; 20 int ExecuteSql<TEntity>(string sql, params SqlParameter[] parms) where TEntity : class; 21 List<TEntity> ExecuteSqlToList<TEntity>(string sql, params SqlParameter[] parms) where TEntity : class; 22 int ExecuteStoredProcedure<TEntity>(string storedProcedureName, params object[] parms) where TEntity : class; 23 List<TEntity> ExecuteStoredProcedureToList<TEntity>(string storedProcedureName, params object[] parms) where TEntity : class; 24 }
数据库的查询自带分页查询方法,不须要咱们后续进行查所有集合后的分页操做,极大地提高了开发的效率。
分页的条件完整全面且易于传递及操做,对程序员的开发有较大的帮助。
1 List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, bool isDESC = false) where TEntity : class; 2 List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, Expression<Func<TEntity, bool>> where, bool isDESC = false) where TEntity : class; 3 List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, out int count, bool isDESC = false) where TEntity : class; 4 List<TEntity> QueryEntitiesPaging<TEntity, TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, TKey>> orderBy, Expression<Func<TEntity, bool>> where, out int count, bool isDESC = false) where TEntity : class;
对数据集合的查询条件所有统一使用Lambda表达式,便于操做的同时,极大下降了手动拼写错误的风险。
这里的Lambda表达式彻底使用标准的Linq风格,在Lambda的支持条件下,查询条件对String类型的字段默认支持一下几种筛选条件:
t.Equals(""); //彻底匹配
t.Contains(""); //模糊查询
t.StartWith(""); //模糊查询起始字符固定
t.EndsWith(""); //模糊查询结束字符固定
...
例如咱们须要查询People表Name字段包含2的全部数据的数目,操做方法以下图所示:
Bantina在提倡框架风格使用的基础上,也提供了对原生SQL语句和存储过程执行的支持,便于适应多变的生产环境。
Bantina的增删改操做所有采用异步Task线程执行的方式,提升了程序的执行效率。
在多行数据的批量添加修改删除循环调用的时候,会提高插入操做执行的效率。
默认对异步的支持,也可使得web服务的响应获得提高,间接提升了用户体验感。
1 Task<bool> Add<TEntity>(TEntity entity) where TEntity : class; 2 Task<bool> Update<TEntity>(TEntity entity) where TEntity : class; 3 Task<bool> Update<TEntity>(TEntity entity, Expression<Func<TEntity, bool>> where) where TEntity : class; 4 Task<bool> Delete<TEntity>(TEntity entity) where TEntity : class; 5 Task<bool> Delete<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class;
Bantina框架封装了对事务的支持,并且调用很是简洁。
只须要数据库上下文对象调用事务方法,而后传递一个委托给方法做为参数执行委托事件便可。
下面我使用了匿名委托的方式进行调用事务执行操做,在委托方法里面分别执行了几组须要支持事务操做的数据库操做,而后方法自动提交事务,若是有事务失败的操做,那么方法会自动回滚操做。
代码展现以下图所示:
Bantina能够经过配置主外键关系,经过特定的特性标签来标识主外键关系,而后达到主外键关联查询的目的。
配置代码见该介绍第三条 三、特性标签的方式标记实体类
例如咱们要支持关联外键表TB_ClassName的查询,并将班级的名称显示,经过配置后,咱们能够进行以下查询操做:
查询结果以下图所示:
Bantina实现了如上的关联查询操做方式。
介绍完咱们的Bantina框架后,咱们将在下一章对Bantina的使用方法进行介绍:
2、框架使用方式介绍 http://www.cnblogs.com/qixiaoyizhan/p/7418058.html
一、Nuget获取:Nuget搜索 QX_Frame.Helper_DG
二、GitHub查看源代码:https://github.com/dong666/QX_Frame.Helper_DG
注:bantina已正式更名为Bankinate,新版本GitHub:https://github.com/dong666/QX_Frame.Bantina
三、联系本人获取,联系方式在下方博客签名中,qq、email都可。