我的编程空间,编程开发者的网络收藏夹
学习永远不晚

数据访问层DAL是怎样实现的

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

数据访问层DAL是怎样实现的

数据访问层DAL的实现过程是怎么样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

这里为了演示上简单,假设:后台数据库(暂为SqlServer只有用户表User与部门表Department),各表字段相应精简:

User(用户表)
Id主键
Name姓名
DeptId部门编号
其余字段省略......
Department(部门表)
Id主键
Name名称
Desc部门描述
其余字段省略......

后台数据库:testdb的情况

数据访问层DAL是怎样实现的

建立相关的存储过程:

数据访问层DAL是怎样实现的

一般我个人也喜欢ORM转换成实体对象(见截图)

数据访问层DAL是怎样实现的

数据访问层DAL是怎样实现的

(注意:这里增加了DeptTitle属性<部门名称>)

现在就是访问数据库SqlServer类型,封装到SqlserverProvider中。如果将来访问Access数据库,对应访问封装到AccessProvider中。

(Provider这里表示数据访问提供程序)

数据访问层DAL是怎样实现的

SqlUserProvier专门实现对SqlServer的表User的操作,AccessUserProvider专门实现对Access的表User的操作,很显然,操作功能都相同(增删改查<CRUD>),因而对不同子类的相同部分抽象出来,形成父类(UserProvider)。

数据访问层DAL是怎样实现的

开始着手具体子类实现:SqlUserProvider:UserProvider

数据访问层DAL是怎样实现的

(上图数据库连接串错误:单词integrated才是正确的,***面调试错误后改正。)

我们发现重载的GetUsers方法,大量代码重复,进行方法重构(重复代码重构为方法GetUsersFromReader)!

数据访问层DAL是怎样实现的

继续具体实现父类的抽象方法:GetUserById,发现该方法的部分代码与先前的GetUsersFromReader方法中的部分代码又重复了!

数据访问层DAL是怎样实现的

发现上图红色部分重复(该图GetUserById方法忘记传递存储过程所需的参数了),再接着方法重构,提炼重复的代码,避免以后改动的多次修改。

数据访问层DAL是怎样实现的

接着编写该类后续的方法(增/删/改):(可以打开VS开发环境中的<服务器资源管理器>,连接上对应的数据库后,看存储过程的参数,以免编码遗忘传参)

数据访问层DAL是怎样实现的

接着也来看看 类:AccessUserProvider,见下图

数据访问层DAL是怎样实现的

上图GetUsers方法中的查询语句没有联合查询,后续会改动。(这里仅仅示范,其似Access是可以类似建立查询表<后台调用类似存储过程方式>)

我们发现UserProvider的两个子类的方法GetUserFromReader和GetUsersFromReader有重复代码(仅仅是方法的参数不同) [想办法抽象出来,放在父类中]

数据访问层DAL是怎样实现的

而方法的参数虽然是SqlDataReader与OleDbDataReader,但是查看定义,看到它们有自己的父类:DbDataReader。

public class SqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord

public sealed class OleDbDataReader : DbDataReader

改写父类:UserProvider

数据访问层DAL是怎样实现的

父类的方法加上修饰符protected,是为了确保只有子类能够访问。

子类便可以直接调用父类的方法了(GetUserFromReader和GetUsersFromReader方法),见截图:

数据访问层DAL是怎样实现的

类似的完善SqlDepartmentProvider类和AccessDepartmentProvider类的代码

(父类:DepartmentProvider提供保护方法GetDeparmentFromReader和GetDepartmentsFromReader)

数据访问层DAL是怎样实现的

每个具体的子类Provider都重复了属性:ConnString,所以决定建一个父类:DataAccess来存放该属性(UserProvider与DepartProvider都继承自它),实际上DataAccess还可以包含其它的属性和共用方法。

namespace抽象工厂模式.DAL  {  publicabstractclassDataAccess  {  privatestring_connString ="";  publicstringConnString  { get{ return_connString; } }  }  }

public abstract class UserProvider:DataAccess

public abstract class DepartmentProvider:DataAccess

通常:数据库连接串的内容都是存储在对应的配置文件中,而不硬编码。

桌面应用程序&mdash;[app.config],web应用程序---[web.config],这里以app.config示例,数据库连接串先按照SqlServer数据库访问的。

数据访问层DAL是怎样实现的

<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="DBConnString" connectionString="SERVER=.sqlexpress;DATABASE=testdb;INTEGRATED SECURITY=true"/> </connectionStrings> </configuration>

数据访问层DAL是怎样实现的

一定要手动引用:System.configuration,然后通过ConfigurationManager类来访问连接串。

可以想象,根据数据库的类型不同,实际底层操控的数据提供程序为Sql__Provider或是Access__Provider。

但对于用户调用者(业务逻辑层)只需要操控Provider就可以了。

假设我所在城市有两个行政分区(东一区和西二区),有一家“真不错”总店[经营快餐系列的]在这两个区都有连锁店,对外统一电话:1111777。

(设一个总机号码当然方便了,总不至于将来开了10家分店,对外公布10个电话号码,谁能记住啊?)

比如说:我现在饿了,想吃这家提供的“经济型快餐(一素<炒莴苣>一汤<豆腐汤>)”,我只要打电话111177,那边只需要了解我的地址就可以了。(可以想象:知道了我的地址<就能明白所在行政区,然后公司总店去指派所在区的分店来服务>),对于客户我而言:如何指派哪家分店来服务,以及经济型快餐如何制作的,我都不会关心的。我只关心:要好吃,然后要快点(毕竟,饿太久会受不了的。)

回到我们的程序:

UserProvider好比一个物品蔬菜<莴苣>,DepartmentProvider好比汤菜<豆腐>。Access文件夹[经济型],SqlServer文件夹[商务型] (你会问一个题外问题:有荤菜吗?我的回答是:尽量别吃,如今都是激素喂出来的<现在人们消耗太快了,以前自然方式半年才能长大的动物,如今1个月人工方式就用激素喂成了>。吃多了,身体容易得病)。

只有一个问题:既然BLL(相对于DAL就是客户调用者)只认(UserProvider/DepartmentProvider),又是如何调用实际其作用的子类呢?

这就需要用到设计模式中的<简单工厂模式> (具体选择哪个子类实际上用父类来完成<根据客户配置需求>)

数据访问层DAL是怎样实现的

当然这里的配置文件:数据库连接串和providerType需要匹配好。

父类:UserProvider我们提供静态的Instance,来决定实际的子类(SqlUserProvider或者AccessUserProvider,根据配置文件的ProviderType的value来定)

数据访问层DAL是怎样实现的

如果将来出现了OracleUserProvider/DB2UserProvider/MySqlUserProvider/XmlUserProvider,这个蓝色框框仍然需要增加case分支。这就不好了,需要再编码(修改),好的设计方式应该是对扩展开放,对修改封闭。而且这里罗列出了所有的具体子类Provider,其实只需要一个子类Provider,但是其他的子类Provider也被迫出现在一起<大杂烩>(其实子类之间出现了耦合) 所以这种方式不可取,需要解决。

这里用反射的方式来解决这个问题。

首先约束:ProviderType的赋值需要规范,只能从(Sql/Access/DB2/MySql/Xml)选择一个呢。可以发现:实际的子类名:ProviderType的值+“UserProvider”。

staticpublicUserProvider Instance  {  get {  if(_instance == null)  {  stringproviderTypeName=ConfigurationManager.AppSettings["ProviderType"]  +"UserProvider";  _instance =  Activator.CreateInstance(Type.GetType(providerTypeName)) asUserProvider;  }  return_instance;  }  }

如果:你的DAL是单独用程序集方式建立的项目(类库),请使用Assembly.Load等方式,这里由于是以文件夹方式组织的(DAL文件夹)<用Activator.CreateInstance可以OK.>

以后客户端(BLL)调用的时候:比如删除用户表的记录,就可以如下调用了:

UserProvider.Instance.DeleteUser(id)了。//这里BLL已经不知道是由哪个子类(如SqlUserProvider)来实际工作的。

进行一下测试,看是否运行正常!

发现错误:一:数据库连接串需要修改:

数据访问层DAL是怎样实现的

二:文件夹SqlServer改成Sql。以前的命名空间对应改动下:

namespace抽象工厂模式.DAL.Provider.Sql

{

publicclassSqlDepartmentProvider:DepartmentProvider

&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.

namespace抽象工厂模式.DAL.Provider.Sql

{

publicclassSqlUserProvider:UserProvider

&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;&hellip;.

三:Type.GetType(需要完整的限定名)

数据访问层DAL是怎样实现的

测试通过:但发现没有DeptTitle数据,查找错误发现

publicUser(intid, stringname, intdeptId, stringdeptTitle)  {  this.Id = id;  this.Name = name;  this.DeptId = deptId;  this.DeptTitle = deptTitle; //DeptTitle;  }

数据访问层DAL是怎样实现的

附上:AccessUserProvider的代码如下:

AccessUserProvider代码

usingSystem;  usingSystem.Collections.Generic;  usingSystem.Text;  usingSystem.Data;  usingSystem.Data.OleDb;  using抽象工厂模式.DAL;  using抽象工厂模式.DAL.Entity;  namespace抽象工厂模式.DAL.Provider.Access  {  publicclassAccessUserProvider:UserProvider  {  publicoverrideList<User> GetUsers()  {  using(OleDbConnection conn = newOleDbConnection(ConnString))  {  vardbcmd = conn.CreateCommand();  dbcmd.CommandText = "GetUsers";  dbcmd.CommandType = CommandType.StoredProcedure;  conn.Open();  returnGetUsersFromReader(dbcmd.ExecuteReader());  }  }  publicoverrideList<User> GetUsers(intdeptId)  {  using(OleDbConnection conn = newOleDbConnection(ConnString))  {  vardbcmd = conn.CreateCommand();  dbcmd.CommandText = "GetUsersByDepartmentId";  dbcmd.CommandType = CommandType.StoredProcedure;  dbcmd.Parameters.Add("@DeptId", OleDbType.Integer).Value = deptId;  conn.Open();  returnGetUsersFromReader(dbcmd.ExecuteReader());  }  }  publicoverrideUser GetUserById(intid)  {  using(OleDbConnection conn = newOleDbConnection(ConnString))  {  vardbcmd = conn.CreateCommand();  dbcmd.CommandText = "GetUserById";  dbcmd.CommandType = CommandType.StoredProcedure;  dbcmd.Parameters.Add("@Id", OleDbType.Integer).Value =id ;  conn.Open();  returnGetUserFromReader(dbcmd.ExecuteReader());  }  }  publicoverrideboolDeleteUser(intid)  {  using(OleDbConnection conn = newOleDbConnection(ConnString))  {  OleDbCommand cmd = newOleDbCommand(  "delete from [user] where Id="+ id, conn);  conn.Open();  returncmd.ExecuteNonQuery() == 1;  }  }  publicoverrideintInsertUser(User user)  {  using(OleDbConnection conn = newOleDbConnection(ConnString))  {  OleDbCommand cmd = newOleDbCommand(  @"insert into [user](name,deptId) values(@id,@name);68select max(id) from [user] as newid",conn);  cmd.Parameters.Add("@id", OleDbType.Integer).Value = user.Id;  cmd.Parameters.Add("@name", OleDbType.VarChar).Value = user.Name;  conn.Open();  return(int)cmd.ExecuteScalar();  }  }  publicoverrideboolUpdateUser(User user)  {  using(OleDbConnection conn = newOleDbConnection(ConnString))  {  OleDbCommand cmd = newOleDbCommand(  "update [user] set name=@name,deptId=@deptid where Id=@id", conn);  cmd.Parameters.Add("@name", OleDbType.Integer).Value = user.Name;  cmd.Parameters.Add("@deptid", OleDbType.Integer).Value = user.DeptId;  cmd.Parameters.Add("@id", OleDbType.Integer).Value = user.Id;  conn.Open();  returncmd.ExecuteNonQuery() == 1;  }  }  }  }

后台的testdb.mdb截图:

数据访问层DAL是怎样实现的

关于数据访问层DAL的实现过程是怎么样的问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

数据访问层DAL是怎样实现的

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

数据访问层DAL是怎样实现的

数据访问层DAL的实现过程是怎么样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。这里为了演示上简单,假设:后台数据库(暂为SqlServer只有用户表User与部门表De
2023-06-17

Holer怎样实现外网访问MariaDB数据库

这篇文章给大家介绍Holer怎样实现外网访问MariaDB数据库,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。外网访问内网MariaDB数据库内网主机上安装了MariaDB数据库,只能在局域网内访问,怎样从公网也能访问
2023-06-04

ASP.NET数据访问层的概念是什么

本篇内容主要讲解“ASP.NET数据访问层的概念是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ASP.NET数据访问层的概念是什么”吧!如果不使用ASP.NET数据访问层,那么你的代码里会
2023-06-17

SpringBoot中Mybatis+Druid数据访问过程是怎样的

本篇内容主要讲解“SpringBoot中Mybatis+Druid数据访问过程是怎样的”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SpringBoot中Mybatis+Druid数据访问过程是
2023-06-25

Salesforce和SAP HANA的元数据访问加速是怎样的

本篇文章为大家展示了Salesforce和SAP HANA的元数据访问加速是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Salesforce在Jerry的其他文章曾经提到,Salesforc
2023-06-03

使用JDBC实现数据访问对象层(DAO)代码示例

JAVA是面向对象的语言,开发者在操作数据的时候,通常更习惯面对一个特定类型的对象,如一个用户就是一个User类的对象。DAO层需要做的,就是为上层提供充分的对象支持,让上层再也看不到具体的数据,而是一个个活生生的对象。增加,删除,查询和修
2023-05-31

怎样访问云服务器上的数据库

要访问云服务器上的数据库,可以使用以下步骤:打开你的云服务器管理应用程序,例如AmazonWebServices。打开数据库连接并创建一个新的连接到数据库。如果你有现成的数据库,可以通过连接数据库并导入数据来创建连接。向云服务器发送要访问的数据库地址。使用Google帐户登录云服务器,并使用你的Google账户登录数据库。在Google网站上搜索“data-db”来选择要访问的数据库
2023-10-26

怎么用SimpleFramework框架实现数据访问

本篇内容介绍了“怎么用SimpleFramework框架实现数据访问”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Simple数据访问层基于
2023-06-17

Holer怎么实现外网访问SQLServer数据库

本篇文章给大家分享的是有关Holer怎么实现外网访问SQLServer数据库,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。外网访问内网SQLServer数据库内网主机上安装了S
2023-06-04

jdbc连接池怎么实现数据库访问

JDBC连接池是一种管理数据库连接的技术,它可以提供可用的数据库连接给应用程序使用,从而提高数据库访问的性能和效率。以下是实现JDBC连接池的一般步骤:1. 导入相关的JDBC驱动程序:根据使用的数据库类型,需要导入相应的JDBC驱动程序。
2023-09-15

MySQL数据优化中的多层索引是怎么样的

这期内容当中小编将会给大家带来有关MySQL数据优化中的多层索引是怎么样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、多层索引1.创建环境:Jupyterimport numpy as npimpo
2023-06-22

CRM, C4C和SAP Hybris的数据库层设计是怎样的

CRM, C4C和SAP Hybris的数据库层设计是怎样的,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。SAP的product都是DB provider无关的。CRM大家都很
2023-06-04

Beam怎么实现分布式存储和访问数据

Beam是一个分布式数据处理框架,它本身并不提供存储数据的功能,但可以与各种存储系统集成来实现分布式存储和访问数据。在Beam中,可以通过一些存储系统的Connector来连接到不同的存储后端。要实现分布式存储和访问数据,可以按照以下步骤
Beam怎么实现分布式存储和访问数据
2024-05-11

Hybris Enterprise Commerce Platform 服务层的设计与实现是怎样的

本篇文章给大家分享的是有关Hybris Enterprise Commerce Platform 服务层的设计与实现是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。我们来
2023-06-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录