ado.net快速上手疑问及解答

 一、代码中的问题

  1、伪SqlMapper的基类为什么用抽象类BaseSqlMapper而不用接口?

  答:楼猪也知道在IBatis下的SqlMapper的基类就是一个接口ISqlMapper,但是楼猪写代码的时候,发现泛型约束在抽象基类里写一次,在SqlMapper下就不要再写了,而用接口就必须写两遍约束。呵呵,一时偷懒的后果,没有深刻意识到“针对接口编程”这一条常识,提出这个问题的童鞋明显可以看出技高楼猪一筹啊,,哈哈,楼猪吸取这个教训了,本文最后的demo楼猪将BaseSqlMapper统一换成了ISqlMapper接口,请留意。

  2、在前台页面里面写SQL语句太多,是不是不太好?

  这个问题也很好。在实际的项目中,SQL语句通常都写在具体的Dao文件中,比如前文demo中提到的PersonDao类。我们在添加一个Person的时候,示例中是通过view plaincopy to clipboardPRint?

  public int Insert(string sqlInsert)

  public int Insert(string sqlInsert)

  这种形式的方法执行插入的,但是在实际项目中的时候,我们通常都会写view plaincopy to clipboardprint?

  public int Insert(Person model)

  public int Insert(Person model)

  这种类型的方法执行数据库插入操作。所以在前台(表现层)写SQL语句其实是不合理的。再次多多感谢指出代码问题的童鞋们。如果已经对某些新手造成某些误导,楼猪在这里要深刻反省和检讨(demo写的明显有点随意和偷懒),在这里,楼猪郑重提醒,SQL语句的位置请不要模仿demo中这种糟糕的写法,楼猪也是过来人,因为使用Batis.net的时候都是放在Dal层xml下的,请务必重视起来。

  二、疑问(直接摘录邮件内容)

  1、“数据库切换貌似没有是吧.怎样切换MSSQL。ACC,XML等等呢”?

  答:这个应该是说源码对多种数据库的支持问题。哦,楼猪还没有实现。看源码,Sql Server简单的基本的CRUD功能已经支持了。如果要扩展支持其他数据库,模仿SqlServer类里的具体实现即可。楼猪的机器环境上没有安装Oracle或者MySQL等数据库,所以写完了也不好测试。您如果条件具备,自己可以试着完成它。至于说数据库的切换,理想状态的实现莫过于最经典的抽象工厂模式,呵呵,配置文件配合反射就行了。但是楼猪建议您简单使用伪SqlMapper进行数据库类型切换。具体操作,其实只要在配置文件appsetting中加一个数据库类型节点sqlType,配合类里的常用数据库类型的枚举即可。

  <appSettings>

  <add key="db_timeOut" value="5000"/>

  <!--数据库类型 0 SqlServer 1 Orcale 2 MySql-->

  <add key="sqlType" value="0"/>

  </appSettings>

  枚举如下:

  代码

  namespace AdoNetDataaccess.Mapper

  {

  public enum SqlEnum

  {

  Default = 0,

  SQLServer = 0,

  Oracle = 1,

  MySql = 1

  }

  }

  然后,就是一些实例化SqlMapper的过程判断了,将数据库切换的问题完全转移到实例化SqlMapper上来:

  代码

  using System;

  using System.Collections.Generic;

  using System.Configuration;

  namespace AdoNetDataAccess.Mapper

  {

  using AdoNetDataAccess.Core.Contract;

  using AdoNetDataAccess.Core.Implement;

  #region enum

  public enum SqlEnum

  {

  Default = 0,

  SQLServer = 0,

  Oracle = 1,

  MySql = 1

  }

  #endregion

  public sealed class MapperUtill

  {

  #region fields

  public static string currentSqlKey = "sqlConn";

  public static int cmdTimeOut = 15;

  private static int sqlType = 0;//数据库类型 0 SqlServer 1 Orcale 2 MySql

  private static readonly object objSync = new object();

  private static readonly IDictionary<string, ISqlMapper> dictMappers = new Dictionary<string, ISqlMapper>();

  #endregion

  #region constructor and methods

  private MapperUtill()

  {

  }

  static MapperUtill()

  {

  try

  {

  cmdTimeOut = int.Parse(ConfigurationManager.AppSettings["db_timeOut"]);

  }

  catch

  {

  cmdTimeOut = 15;

  }

  try

  {

  sqlType = int.Parse(ConfigurationManager.AppSettings["sqlType"]);

  }

  catch (Exception ex)

  {

  throw ex;

  }

  //实例化SqlDbMapper

  for (int i = 0; i < ConfigurationManager.ConnectionStrings.Count; i++)

  {

  string key = ConfigurationManager.ConnectionStrings[i].Name;

  string value = ConfigurationManager.ConnectionStrings[i].ConnectionString;

  CreateMapper(key, value, cmdTimeOut);

  }

  }

 

  public static ISqlMapper GetSqlMapper(string key)

  {

  return MapperUtill.GetMapper(key);

  }

  public static ISqlMapper GetCurrentSqlMapper()

  {

  return MapperUtill.GetMapper(currentSqlKey);

  }

  public static void CreateMapper(string connKey, string sqlConStr, int connTimeOut)

  {

  IDbOperation operation = null;

  switch (sqlType)

  {

  default:

  case 0:

  operation = new SqlServer(sqlConStr, connTimeOut);

  break;

  case 1:

  //operation = new Orcale(sqlConStr, connTimeOut);//Orcale 未实现

  break;

  case 2:

  //operation = new MySql(sqlConStr, connTimeOut);//MySql 也没有实现呢

  break;

  }

  if (operation == null)

  {

  throw new Exception("您配置的数据库类型有可能那啥出问题了");

  }

  SqlMapper mapper = new SqlMapper(operation);

  dictMappers.Add(connKey.ToUpper().Trim(), mapper);//不区分大小写

  }

  public static ISqlMapper GetMapper(string sqlConKey)

  {

  if (string.IsNullOrEmpty(sqlConKey))

  {

  throw new Exception("数据库连接字符串主键为空!");

  }

  sqlConKey = sqlConKey.ToUpper();//不区分大小写

  ISqlMapper mapper = null;

  if (dictMappers.ContainsKey(sqlConKey))

  {

  mapper = dictMappers[sqlConKey];

  }

  else

  {

  throw new Exception(string.Format("没有{0}所对应的数据库连接", sqlConKey));

  }

  return mapper;

  }

  /// <summary>

  /// 释放所有

  /// </summary>

  public void Release()

  {

  foreach (KeyValuePair<string, ISqlMapper> kv in dictMappers)

  {

  SqlMapper mapper = kv.Value as SqlMapper;

  if (mapper == null)

  {

  continue;

  }

  mapper.CurrentDbOperation.CloseConnection();

  }

  dictMappers.Clear();

  }

  #endregion

  }

  }

  必须要注意,这里的数据库切换方式不是绝对的,您可以按照自己喜欢的习惯的其他方式编程完成切换,楼猪这里只是抛砖而已。

  2、“我对ORM不熟悉,想问下您的这个ORM到底是节省了哪部分工作? 我看里面有大量的反射,这样是不是非常影响效率?”

  首先,楼猪对ORM也不太熟悉。现在实现的这个严格来说也根本谈不上算是ORM,但是有楼猪自己使用过的两个ORM的影子。

  其次,当前实现的东东不是为了节省哪部分工作而设计的,楼猪的初衷是重读ado.net经典红皮书而做的复习笔记。

  第三,反射相对于没有使用反射,当然非常影响效率。需要说明的是,要不要使用反射应该根据实际的项目需要。根据楼猪个人开发经验,对于大多数程序员要实现的简单的常见的前后台mis系统,在保证基本需求的情况下,客户如果对效率没有意见,用用没有太大关系,大部分工作就交给服务器完成去吧,程序员不用做太多工作。但是对于访问频繁的大型网站,实时系统或者应对大数据量操作的系统等等,建议不要使用反射,而且可能要重点花精力在数据“装潢”上面。

  最后,如果有童鞋对ORM感兴趣,不妨在网上搜搜大牛们的作品,大名鼎鼎的NHibernate,iBatis.net,WebSharp,LINQ等等(这么多ORM,一个一个都要熟悉,源码也研究不过来啊,建议新手熟练一两种足矣),也许对您有更多的启发。如果您自己实现了类似其他流行ORM的主流功能(如自动生成SQL语句或者通过XML配置,缓存,延迟加载等等),并且功能更加强大,用起来更加顺手方便的新ORM,呵呵,真诚期待您的功德圆满那一天早日到来,快点来造福万千程序员吧。

时间: 2024-09-09 11:12:21

ado.net快速上手疑问及解答的相关文章

微信公众平台快速上手教程Part9 详解自定义菜单与大家疑问

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 延伸阅读:微信公众平台快速上手教程Part8 微信是后端服务营销利器微信公众平台快速上手教程Part7 微信运营十大要决微信公众平台快速上手教程Part6 公众会议帐号微信公众平台快速上手教程Part5 开发模式讲解微信公众平台快速上手教程Part4 关键词自动回复微信公众平台快速上手教程Part3 素材编辑微信公众平台快速上手教程Part2

微信公众平台快速上手教程Part4 关键词自动回复

中介交易 SEO诊断 淘宝客 云主机 技术大厅 课程来到了第四部分,这部分主要讲解自定义关键词应答设置,这是微信公众平台最核心部分希望大家可以认真阅读.如果对本篇教程有任何疑问或错漏之处欢迎留言或直接联系我进行更正修改. 我们点击高级功能会看到下图页面,里面有两种模式,一种是编辑模式,这也是我们最常用到的,另一种是开发模式,下一节课我们就会讲这个模式.现在我们点击进入编辑模式. 进入编辑模式后我们会看到默认开启的状态,点击里面的"设置"按钮,开始设置自动回复功能. 进入自动回复设置界面

微信公众平台快速上手教程Part5 开发模式讲解

中介交易 SEO诊断 淘宝客 云主机 技术大厅 这部分主要讲解微信公众平台的开发模式,首先说明一下我不是程序员,所以本篇并非讲编程代码之类的,也并非开发模式的说明书,毕竟微信官方已经有一份详细的技术说明文档(在文章尾部提供文档地址),但是由于我们正在开发微信POP营销系统,所以我对开发模式有一定了解,这些了解应该会对准备尝试做微信开发的朋友会有一定帮助,少走部分弯路吧.如果对本篇教程有任何疑问或错漏之处欢迎留言或直接联系我进行更正修改. 首先我们要明确开发模式什么可以做,什么不可以做: 一.开发

Win8强大兼容性无需适应快速上手

  如果说使用Win7是在一个我们熟悉的环境中操作,那么Win8就是给我们带来了两个激动人心的环境,一个是新颖的"开始"屏幕及它的应用生态,还有一个就是我们熟悉的跟Win7一样的桌面系统.这也就意味着Win8具有很强的兼容性,可以毫不费力地运行Win7的程序,轻松上手无压力. 其实一个操作系统做到Windows这样,基本也不用太多的在意兼容性问题了.作为一个使用最广泛的操作系统,任何软件厂商都会千方百计地向其靠拢,以便能在新系统上运行它们的程序,这是一个向上兼容的过程. Win8不仅仅

Eclipse快速上手Hibernate--4. 继承映射(3)

继承     前两篇文章<Eclipse快速上手Hibernate--4. 继承映射(1) >和<继承映射(2)>中已经谈了每个类层次结构一个表(table per class hierarchy)与每个子类一个表(table per subclass)的策略,这篇文章主要说的是每个具体类一个表(table per concrete class).一些重复的部分这里就不说了,请参考前两篇文章.    这个策略很简单,抽象的基类不参与映射,具体子类参与映射.  1. 创建项目 · 

Eclipse快速上手Hibernate--4. 继承映射(1)

继承    前面的<Eclipse快速上手Hibernate--1. 入门实例 >等三篇文章已经谈了Hibernate的入门以及利用工具创建的方法.这篇文章主要说说在Hibernate中的继承映射.相关配置请参考前三篇文章.    如果程序中的对象含有继承的关系,在Hibernate中有以下三种策略将这种关系映射到数据表上:· 每个类层次结构一个表(table per class hierarchy)· 每个子类一个表(table per subclass) · 每个具体类一个表(table

Eclipse快速上手Hibernate--5. 组件映射

    这篇文章主要说的是在Hibernate中的组件(Component)映射,可以参考Hibernate官方文档的第7章.至于环境设置,可以参考这个系列的前面几篇文章.  1. 创建项目 ·  新建一个Java项目:ComponentMapping,注意选中"创建单独的源文件夹和输出文件夹",同时添加"用户库":hibernate.   2. 编写类文件 ·  新建一个类,包名:javamxj.hibernate.component,类名:Person.Pers

Eclipse快速上手Hibernate--4. 继承映射(2)

继承     上篇文章<Eclipse快速上手Hibernate--4. 继承映射(1) >中已经谈了每个类层次结构一个表(table per class hierarchy)的策略,这篇文章主要说的是每个子类一个表(table per subclass)的策略.一些重复的部分这里就不说了,请参考上篇文章. 1. 创建项目 ·  继续沿用上篇文章中所建的Java项目:InheritanceMapping.   2. 编写类文件 ·  新建一个类,包名:javamxj.inheritance.t

Eclipse快速上手Hibernate--2. 利用Hbm映射文件开发

   这篇文章是上篇文章<Eclipse快速上手Hibernate--1. 入门实例>的延续,主要说的是如何利用Hbm映射文件产生普通的Java对象及数据表.可以参考Hibernate自带的文档<HIBERNATE - 符合Java习惯的关系数据库持久化>的第15章--<工具箱指南>一节.同样,这篇文章没有过多谈理论,只是给出了一个完整的实例加以说明.相关配置请参考上篇文章.  1. 创建项目 ·  新建一个Java项目:HibernateBegin_2,注意选中&qu