自已接触过的数据访问方式总结

程序=代码+数据。数据这里主要说关于数据库的操作。

基本的SQL是高度非过程化的语言,简单理解,就是没有流程控制,像条件判断和循环。满足不了开发需要。

所以为了实现查询的流程控制。有以下几种方法。

嵌入式SQL语句,简单说就是把SQL嵌入到高级语言里,SQL语句还是直接执行,由高级语言来实现流程控制。

比如if(**){exec sql **},这方面基本全忘光了,貌似学PB的时候用过,这种技术比较底层,很古老,高级开发很少用到。

PL/SQL和存储过程,存储过程实质就是一个特殊的PL/SQL块,可以永久的保存在数据库中以供其他程序调用。

PL/SQL是对基本SQL语句的扩展,增加了过程化语句的功能,由SQL语句自已实现流程控制。

书上的原话:

PL/SQL块主要有两种类型,即命名块和匿名块。匿名块每次使用时都要进行编译,除此之外,该类块不在数据库中存储并且不能直接从其他的PL/SQL块中调用。过程、函数、包和触发器都属于命名块,这类构造没有匿名块的限制,它们可以存储数据库中并在适当的时候运行。

我个人只接触过存储过程和触发器。

简单的存储过程示例

ALTER PROCEDURE [dbo].[firelateinvitation]
	-- Add the parameters for the stored procedure here
@num int,
@type int

AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from
	-- interfering with SELECT statements.
	SET NOCOUNT ON;

if @type=1
begin

select top (@num) * from TB_Forum_Invitation,TB_Forum_Plate
where TB_Forum_Invitation.Invitation_Plateid=TB_Forum_Plate.Plate_Id
order by Invitation_Ftime desc

end

else if @type=2
begin
select top (@num) * from TB_Forum_Invitation,TB_Forum_Plate
where TB_Forum_Invitation.Invitation_Plateid=TB_Forum_Plate.Plate_Id
order by Invitation_Ranking desc
end

END

  

  if就是过程化语句的流程控制的一种。

PS:存储过程不止能反回查询结果,还可以有其他单独的返回值,由参数决定

        IN类型的参数    OUT类型的参数         IN-OUT类型的参数   

值被  传递给子程序   返回给调用环境      传递给子程序且,返回给调用环境   

默认为IN型。

简单的触发器示例

ALTER trigger [dbo].[lastbacktime]
   ON  [dbo].[TB_Forum_Invitation]
   AFTER INSERT
AS 
BEGIN
update  database_Forum.dbo.TB_Forum_Invitation set Invitation_LastBackTime=getdate()
where Invitation_Id=(select Invitation_Id from inserted) 

END

……工作需求并未要求写太复杂的触发器,有印象的是为了实现级联删除和修改,也不提倡写大量的复杂的触发器,不利于维护。

实际上,会写SQL查询的只要再多一点的付出就能写出同样功能的存储过程,我工作中其实用的不多。

存储过程优点主要是省流量高效:传一大串SQL语句,到数据库里编译再执行。传几个参数调用已经编译好的方法,性能哪个高很明显。至于分布式,工作还没接触到。

ODBC,JDBC等各种数据库的区别,只是业余看过几篇文章,说实在的,不是很清楚。

在这里写的也都是开发里用过的技术。

ODBC,PB课程设计用过,要建立ODBC数据源,程序才可以访问,Access和PowerDesign也用到过。

JDBC,JAVA练习时用过。

OleDb,操用EXCEL时,使用ACCESS数据库里用过。

ADO.NET是封装的ODBC,用的最多程序使用ADO.NET,ADO.NET通过ODBC实现功能,这里也主要说ADO.NET。

第一份net 工作开发主要用的就是ADO.NET。

数据库操作方法。

最基本的ADO.NET。

主要对象
connection,连接,最主要用的sqlconnection

command SqlCommand,CommandType 类型,可以指定是SQL语句Text,还是存储过程StoredProcedure,text查询语句(type为语句),存储过程名(type为存储过程)。
sqlparameter,参数,防止注入。
查询方法,ExecuteNonQuery,返回影向的行数

SqlTransaction cmd.Connection = conn;
// SqlTransaction tx = conn.BeginTransaction();
// cmd.Transaction = tx;
事务操作。


sqlparameter,参数,防止SQL注入。
查询方法,ExecuteNonQuery,返回影向的行数
ExecuteReader 游标,返回一条再下一条,要保持数据库的连接,嵌入式SQL,ODBC都有游标的概念。
ExecuteScalar 有则返回第一条,无则返回NULL

SqlDataAdapter 适配器
da.Fill(ds, "ds"); 适配器的原理是,调用sqlcommand的ExecuteReader方法,把每一条数据放入dataSet中的某改表中的一行。迭代。

迭代完成后就断开与数据库的连接,反回dataset与DataReader相比省数据库的资源,但占内存。

dataset 可以存多个datatable。 

dataset datatable 很多老的项目,和写的自定义控件,都主要用的datatable,datarow作为操作对象。

JAVA里似乎没有与SqlDataAdapter 和dataset对应的对象 但可以自已实现(一般开发都会有写的工具类,实现了类似dataset的对象)。

DataAdapter 不止有用游标迭代填充到DataSet中的方法。

更高级的应用是,修改DataSet,然后再更新回数据库,等于是程序代写了SQL,这个功能,由另一个对象SqlCommandBuilder实现。再调用DataAdapter对象的Update方法。

常用的代码生成器的DAL层就是由ADO.NET实现。目前的不少公司还用这种方式开发,生成基本的,有其他需求,再自已拼SQL,而调用ADO.NET的过程多被封装在相应的SQLhelper工具类里。

缺点是:有时候拼些简单但繁琐的SQL很烦人。手拼SQL,容易拼错,没准就是哪块拼错了,浪费很多调试时间

我一开始写SQL的时候经常总忘写‘’,有时多写个where,有时拼。推荐在数据库写好语句拼好粘到程序里,我倒是经常直接在程序里拼……

更大的缺点的是不利于重用,不利于修改和扩充,不灵活。谁写的SQL,谁最清楚,但过段时间,可能也得想一会, 就更别说其他人了,而且,很多人写DLL层的SQL还不加注释。就算有注释,有时如果有需求,还得在之前的SQL语句里找修改的位置。

这是得到数据到DataSet的部分,而在取DataSet的数据时,多数是按DataRow列的名称或编号取,就算是复制也觉得麻烦


数据集
(补充:ObjectDataSourse,数据对象中的一种,其他的我没用过。
绑定的方法,可以是上面的BLL层,最初学net的时候,学的是ObjectDataSourse绑定数据集)

数据集,实现了强类型DataSet。比手写ADO.net好就是这一点,可以不再用row["string"]这种方式取了,能把查询的结果转换为强类型,可以.出相应的属性(字段)


其他和ADO.NET的 DLL层差不多,能定义方法写SQL。

缺点是SQL表之前的的连接不方便,优点是能转为强类型对象,数据集类能返回一个适配器对象,这个对象的实际是数据集内部类的实例。

表连接这里,我没用过,不知道其他人怎么用的,我只用到单表数据返回强类型,多表关连,得以A表查各的数据为参数再另外查询B表。

现在的三层架构代码生成器里有Tolist方法, 也可以把表转为强类型,也同样是单表。数据集和代码生成器差不多,实现方法也差不多,比纯ADO.NET,多了个TOLIST,转为MODEL类对象。

数据集和DLL层的TOlIST方法,都要有一个实体类的参于来实现,也算是简单的ORM,但多表联接是硬伤。

这个实体对象,点不出关联对象,得不到关联对象的属性。


ORM框架

高级的ORM框架,实现了,表与表,实体对象与实体对象的关联。

JAVA的hibernate(net移植为Nhibernate)和.net下的EF。

1:hibernate,
因为对ssh很好奇,工作之余自学了SSH,因此接触到了hibernate,来京找java方面的工作因缺少经验等比较着争等原因没找到,便又作回了net,在net里有相似的NHibernate。

2:linq to sql和EF
linq to sql已经不再支持,但依然可以学习,因为EF的查询语法和LINQ大多是相似的。

EF比LTS的性能高,可以参照LTS学习EF的查询语法。当然,小的项目,没有太多关系的小表(就算全部读到内存也不占多少地方,当然linq to sql声明过的对象,EF就得在另外的命名空间声明)还是可以用LTS的。

hibernate和EF的区别

关系配置:hibernate是通过XML配置,非侵入(不在代码里),EF是写在代码里,用特性实现(写在代码里)。

查询语句:hibernate用HQL,有SQL基础的学这其实不用多少功夫,只人注意几个特别的关键字 和以及查询结果和配置的关系,一个月左右,有问题查文档就可以熟悉了诸如fetch。缺点是没有编译时提示,可能会拼错。

hibernate还可以用ICriteria查询,完全面向对象,这个我还没真正用过,不过在一篇安卓的课程里见过。

EF linq,会linq linq to sql的再学来很容易,要拓展的时候则要注意,Linq的优点是,写代码时就可以查错。

看博客了解到Nhibernate有一个拓展DLL,实现了Linq查询。

缓存:hibernate原生实现了缓存。

事务:

最后一个就不是这两种技术的问题,而是支持问题了。

支持EF的数据库不多,或为有限支持。EF也只用于.net环境。

而hibernate,JAVA环境都可以使用,安卓上层开发用的JAVA,数据访问层和hibernate类似。

目前也是在学习熟悉中

原文地址:https://www.cnblogs.com/zihunqingxin/p/3132620.html