利用Delphi开发网络数据库应用,用Delphi开发数据
分类:新闻中心

Delphi 是具可视化界面的面向对象编程语言,它以其功能强大、简便易用等诸多特性,深受编程人员的欢迎。Delphi 中提供了数据库引擎 BDE(Borland Database Engine),并内含众多的数据库调用构件,为编程人员开发客户/服务器应用程序提供了方便。通常情况下,利用 Delphi 开发数据库应用程序,可以使用TTable、TDataSource、TDBEdit、TDBNavigator等构件。只要正确设置了构件的某些属性,再编写必要的程序代码对一些特定事件进行处理,就能够完成对多种数据库进行的数据处理,例如:记录的输入、修改、删除和查询等。这样做虽然只需要编写极少量的程序代码就能达到很好的效果,但如果在程序设计过程中,某些数据表的结构发生了改变,则必须修改与此数据表有关的所有构件的属性,这将使程序员陷入繁琐的重复劳动中。

存 储 过 程   介绍怎样使用存储过程。存储过程是数据库服务器端的一段程序,它有两种类型。一种类似于 SELECT查询,用于检索数据,检索到的数据能够以数据集的形式返回给客户。另一种类似于INSERT或DELETE查询,它不返回数据,只是执行一个 动作。有的服务器允许同一个存储过程既可以返回数据又可以执行动作。
10.1 概 述
在不同类型的服务器上,存储过程的工作方式是不同的。例如,对于InterBase服务器来说,它能够以输出参数的形式返回数据,而对于其他服务器如MicrosoftSQL Server和Sybase,能够以数据集的形式返回数据和信息。
在Delphi 4中,要访问和操纵服务器上的存储过程,可以使用TStoredProc构件或TQuery构件。至于到底选择哪一个,取决于存储过程本身是怎样编写的、 数据怎样返回和使用哪一种服务器。TStoredProc构件和TQuery构件都是从TDataSet继承下来的。
TStoredProc 构件适合于执行那些不需要返回数据,并且通过输出参数来返回信息的存储过程。TStoredProc构件的Params属性用于管理这些参数,同时, TStoredProc构件的GetResults函数可以显式地申请返回结果。总之,TStoredProc构件适合于执行那些不需要返回结果或者只是 通过输出参数返回结果的存储过程。
TQuery构件适合于执行那些能够返回数据集的存储过程,包括InterBase服务器上通过输出参数返回数据集的存储过程。当然,TQuery构件也适合于执行那些不需要返回结果或者只是通过输出参数返回结果的存储过程。
参数既可以由存储过程传递给客户程序,也可以由客户程序传递给存储过程,前者称为输出参数,后者称为输入参数。对于有的服务器来说,输出参数只能传递一个值,而有的服务器允许输出参数传递一个数据集。
10.2 什么时候需要用存储过程
如果服务器定义了存储过程,应当根据需要决定是否要用存储过程。存储过程通常是一些经常要执行的任务,这些任务往往是针对大量的记录而进行的。在服务器上执行存储过程,可以改善应用程序的性能。这是因为:
.服务器往往具有强大的计算能力和速度。
.避免把大量的数据下载到客户端,减少网络上的传输量。
例如,假设一个应用程序需要计算一个数据,这个数据需要涉及到许多记录。如果不使用存储过程的话,把这些数据下载到客户端,导致网络上的流量剧增。
不仅如此,客户端可能是一台老掉牙的计算机,它的运算速度很慢。而改用存储过程后,服务器会很快地把数据计算出来,并且只需传递一个数据给客户端,其效率之高是非常明显的。
10.3 怎样使用存储过程
应用程序怎样使用存储过程,取决于存储过程本身是怎样编写的、数据怎样返回和使用哪一种服务器。
10.3.1 使用存储过程的一般步骤
要访问服务器上的存储过程,一般是这么几个步骤:
第一步,把一个TStoredProc构件放到窗体或数据模块上。
第二步,设置DatabaseName属性指定一个数据库,可以设为BDE别名或者应用程序专用的别名(如果用TDatabase构件连接数据库的话)。
第三步,设置StoredProcName属性指定存储过程的名称。如果前面正确设置了DatabaseName属性,就可以从一个下拉列表中选择一个存储过程。由于经常要在运行期执行不同的存储过程,因此,StoredProcName属性一般是在运行期设置的。
第四步,单击Params边上的省略号按钮打开一个编辑器。如果第二步和第三步设置正确的话,在这个编辑器中将显示所有的输入和输出参数,否则,这个编辑器就是空的。
要说明的是,并不是所有的服务器都能够提供有关的参数的信息。如果服务器没有提供有关参数的信息,就得自己建立这些参数。
10.3.2 准备和执行存储过程
在执行存储过程之前,最好先通知服务器准备好,这就要调用TStoredProc构件的Prepare函数,例如:
StoredProc1.Prepare;
注意:如果应用程序在运行期改变了参数的信息,必须重新调用Prepare函数。要执行存储过程,可以调用TStoredProc构件的ExecProc函数,程序示例如下:
StoredProc1.Params[0].AsString := Edit1.Text;
StoredProc1.Prepare;
StoredProc1.ExecProc;
注意:如果在调用ExecProc之前没有调用Prepare,TStoredProc构件会自动把参数准备好,存储过程执行完毕后,再自动取消准备。 不过,如果一个存储过程要反复执行多次的话,最好显式地调用Prepare,不再需要执行存储过程时调用UnPrepare函数。
执行了存储过程后,它有可能返回这样几种数据:
.一是数据集,可以用标准的数据控件显示其中的数据。
.二是输出参数。
.三是状态信息。
10.4 创建一个存储过程
存储过程一般是用专门的工具编写的。不过,这里要介绍的是怎样用SQL语句在运行期动态地创建存储过程。对于不同的服务器来说,即使是相同功能的存储过程,SQL语句也有可能是不同的,因此,必须事先查阅服务器的文档。
10.4.1 使用SQL语句创建存储过程
要使用SQL语句创建存储过程,就要用到TQuery构件的SQL属性。如果存储过程中要用到参数的话,必须把TQuery构件的ParamCheck属性设为False。
下面的例子演示了怎样用SQL语句创建一个存储过程:
With Query1 Do
Begin
ParamCheck := False;
With SQL Do
Begin
Clear;
Add('CREATE PROCEDURE GET_MAX_EMP_NAME');
Add('RETURNS (Max_Name CHAR(15))');
Add('AS');Add('BEGIN');
Add('SELECT MAX(LAST_NAME)');
Add('FROM EMPLOYEE');
Add('INTO :Max_Name;');
Add('SUSPEND;');
Add('END');End;
ExecSQL;
End;
当然,也可以用SQL Explorer来创建存储过程。
10.4.2 用TQuery构件检索数据集
要用TQuery构件从存储过程中检索数据集,必须正确设置SQL属性。在SELECT语句中,要用存储过程的名称代替表格的名称。如果存储过程需要传 递输入参数的话,要仿照Object Pascal语言的过程那样,在存储过程后面用一对圆括号把参数的值括起来。如果有多个输入参数,彼此之间要用逗号隔开。
例如,InterBase服务器上有一个存储过程叫GET_EMP_PROJ,它需要传递一个输入参数叫EMP_NO,并且通过一个输出参数叫PROJ_ID来传递执行结果。下面是这个存储过程的代码:
CREATE PROCEDURE GET_EMP_PROJ (EMP_NO SMALLINT)
RETURNS (PROJ_ID CHAR(5))
AS
BEGIN
FOR SELECT PROJ_ID
FROM EMPLOYEE_PROJECT
WHERE EMP_NO = :EMP_NO
INTO :PROJ_ID
DO
SUSPEND;
END
相应地,要通过上面这个存储过程检索数据集,SQL语句可以这样写:
SELECT *
FROM GET_EMP_PROJ(52)
10.4.3 用TStoredProc构件检索数据集
要用TStoredProc构件从存储过程中检索数据集,必须设置StoredProcName属性指定一个存储过程的名称。如果存储过程需要传递输入参数的话,可以通过Params属性或ParamByName函数提供参数。
例如,Sybase服务器上有一个存储过程叫GET_EMPLOYEES,它有个输入参数叫@EMP_NO。下面是这个存储过程的代码:
CREATE PROCEDURE GET_EMPLOYEES @EMP_NO SMALLINT
AS SELECT EMP_NAME, EMPLOYEE_NO FROM EMPLOYEE_TABLE
WHERE (EMPLOYEE_NO = @EMP_NO)
相应地,要通过上面这个存储过程检索数据集,程序应当这样写:
With StoredProc1 Do
Begin
Close;
ParamByName('@EMP_NO').AsSmallInt := 52;
Active := True;
End;
10.4.4 用TQuery构件通过参数检索数据
用TQuery构件通过参数返回的数据是一条记录,即使存储过程只有一个输出参数。因此,应用程序需要从返回的数据中检索出每一个字段的值。
首先,要在SELECT语句中用存储过程的名称代替表格的名称。
如果有多个输出参数的话,您可以选择其中部分输出参数,也可以用星号表示选择所有输出参数。
如果存储过程需要传递输入参数的话,在存储过程后面用一对圆括号把参数的值括起来。如果有多个输入参数,彼此之间要用逗号隔开。
例如,InterBase服务器上有一个存储过程叫GET_HIGH_EMP_NAME,通过一个输出参数叫High_Last_Name来返回EMPLOYEE表的LAST_NAME字段。
下面是这个存储过程的代码:
CREATE PROCEDURE GET_HIGH_EMP_NAME
RETURNS (High_Last_Name CHAR(15))
AS
BEGIN
SELECT MAX(LAST_NAME)
FROM EMPLOYEE
INTO :High_Last_Name;
SUSPEND;
END
相应地,SQL语句应当这样写:
SELECT High_Last_Name
FROM GET_HIGH_EMP_NAME
10.4.5 用TStoredProc构件通过参数检索数据
要用TStoredProc构件通过参数检索数据,首先要设置StoredProcName属性指定一个存储过程。如果存储过程需要传递输入参数的话,可以通过Params属性或ParamByName函数提供参数。
调用ExecProc执行了存储过程后,可以通过Params属性或ParamByName函数访问输出参数。
例如,InterBase服务器上有一个存储过程叫GET_HIGH_EMP_NAME,通过一个输出参数叫High_Last_Name返回EMPLOYEE表的LAST_NAME字段。
下面是这个存储过程的代码:
CREATE PROCEDURE GET_HIGH_EMP_NAME
RETURNS (High_Last_Name CHAR(15))
AS 
BEGIN
SELECT MAX(LAST_NAME)FROM EMPLOYEE
INTO :High_Last_Name;
SUSPEND;
END
相应地,要通过上面这个存储过程检索数据,程序应当这样写:
With StoredProc1 Do
Begin
StoredProcName := 'GET_HIGH_EMP_NAME'ExecProc;
Edit1.Text := ParamByName('High_Last_Name').AsString;
End;
10.4.6 用TQuery构件执行一个动作
有的存储过程并不返回数据,它们只是执行一些动作。例如,要删除一条记录,既可以用DELETE语句直接删除记录,也可以执行一个存储过程。
要用TQuery构件执行一个动作,需在SQL语句中包含要执行的存储过程的名称。如果存储过程需要传递输入参数的话,在存储过程后面用一对圆括号把参数的值括起来。如果有多个输入参数,彼此之间要用逗号隔开。
例如,InterBase服务器上有一个存储过程叫ADD_EMP_PROJ,用于向EMPLOYEE_PROJECT表中增加一条记录。
下面是这个存储过程的代码:
CREATE PROCEDURE ADD_EMP_PROJ (EMP_NO SMALLINT, PROJ_ID CHAR(5))
AS
BEGIN
BEGIN
INSERT INTO EMPLOYEE_PROJECT (EMP_NO, PROJ_ID)
VALUES (:EMP_NO, :PROJ_ID);
WHEN SQLCODE -530 DO
EXCEPTION UNKNOWN_EMP_ID;
END
SUSPEND;
END
相应地,SQL语句应当这样写:
EXECUTE PROCEDURE ADD_EMP_PROJ(20, 'GUIDE');
10.4.7 用TStoredProc构件执行一个动作
要用TStoredProc构件执行一个动作,首先要设置StoredProcName属性指定一个存储过程。可以通过Params属性或ParamByName函数提供输入参数(如果需要的话)。
例如,InterBase服务器上有一个存储过程叫ADD_EMP_PROJ,用于向EMPLOYEE_PROJECT表中增加一条记录。它的代码请参见上一小节。
要执行这个存储过程,程序应当这样写:
With StoredProc1 Do
Begin
StoredProcName := 'ADD_EMP_PROJ';
ExecProc;
End;
10.5 存储过程的参数
要执行服务器上的存储过程,往往要传递一些参数。这些参数分为四种类型:
第一种称为输入参数,由客户程序向存储过程传递值。
第二种称为输出参数,由存储过程向客户程序返回结果。
第三种称为输入/输出参数,既可以由客户程序向存储过程传递值,也可以由存储过程向客户程序返回结果。
第四种称为状态参数,由存储过程向客户程序返回错误信息。
要说明的是,并不是所有的服务器都支持上述四种类型的参数,例如,InterBase就不支持状态参数。
可以通过TStoredProc构件的Params属性访问存储过程的参数(TParam对象)。如果在设计期正确设置了StoredProcName属性,Params属性中将自动包含存储过程的参数,否则,需要自己建立参数。
10.5.1 输入参数
输入参数用于由客户程序向存储过程传递值,值实际上是传递给存储过程中的SQL语句。如果一个存储过程有输入参数,一定要在执行该存储过程之前对输入参数赋值。
如果用TQuery构件执行存储过程,可以把输入参数用一对圆括号括起来,彼此之间用逗号隔开,就像调用Object Pascal的过程一样。例如,假设要执行一个存储过程叫GET_EMP_PROJ,它需要传递一个输入参数,其值为52,SQL语句如下:
SELECT PROJ_ID
FROM GET_EMP_PROJ(52)
如果用TStoredProc构件执行存储过程,可以通过Params属性或ParamByName函数来访问每一个输入参数。要在执行存储过程前对输 入参数赋值。例如,假设要执行一个存储过程叫GET_EMP_PROJ,它需要传递一个输入参数叫EMP_NO,其数据类型为SMALLINT,其值为 52,相应地程序代码应当这样写:
With StoredProc1 Do
Begin
ParamByName('EMP_NO').AsSmallInt := 52;
ExecProc;
End;
10.5.2 输出参数
输出参数用于由存储过程向客户程序传递结果。输出参数是由存储过程赋值的,客户程序只能在执行了存储过程以后,才能访问输出参数的值。
要访问输出参数的值,可以通过TStoredProc构件的Params属性或ParamByName函数。例如,下面的代码把输出参数的值显示到一个编辑框中:
With StoredProc1 Do
Begin
ExecProc;
Edit1.Text := Params[0].AsString;
End;
大多数存储过程都有一个或几个输出参数,输出参数既可以返回一个单独的值,也可以返回一个数据集。
注意:有的服务器如InFormix可能不提供参数的信息,只能从存储过程的代码中查看它有无输出参数。
10.5.3 输入/输出参数
输入/输出参数既可以用于由客户程序向存储过程传递值,也可以由存储过程向客户程序返回结果,也就是说,同一个参数兼具两种角色。作为输入参数,必须在执行存储过程之前对它赋值。作为输出参数,只能在执行了存储过程后访问它的值。
例如,Oracle服务器中有一个存储过程,它的IN_OUTVAR参数就是一个输入/输出参数。这个存储过程的代码如下:
CREATE OR REPLACE PROCEDURE UPDATE_THE_TABLE (IN_OUTVAR IN OUT INTEGER)
AS
BEGIN
UPDATE ALLTYPETABLE
SET NUMBER82FLD = IN_OUTVAR
WHERE KEYFIELD = 0;
IN_OUTVAR:=1;
END
UPDATE_THE_TABLE;
相应地,要执行上面这个存储过程,程序代码应当这样写:
With StoredProc1 Do
Begin
ParamByName('IN_OUTVAR').AsInteger := 103;
ExecProc;IntegerVar := ParamByName('IN_OUTVAR').AsInteger;
End;
10.5.4 状态参数
除了返回数据集或输出参数外,有的存储过程还可以返回一个状态参数。状态参数不需要事先赋值,只有在执行了存储过程之后才能访问它的值。
要访问输出参数的值,可以通过TStoredProc构件的Params属性或ParamByName函数。例如,下面的代码访问ByOutputParam参数:
DateVar := StoredProc1.ParamByName('ByOutputParam').AsDate;
10.5.5 怎样在设计期访问参数
如果在设计期正确设置了DatabaseName和StoredProcName属性,就可以在设计期看到这些参数,对于其中的输入参数,可以设置它们 的值。不过,有的数据库服务器不提供存储过程的参数信息,这种情况下,只能使用SQLExplorer去查看存储过程的代码,从中找出参数的名称和类型, 然后在对象观察器中手动建立这些参数。
要在设计期访问参数,可以单击Params属性边上的省略号按钮打开如图10.1所示的编辑器:
图10.1 存储过程的参数
单击工具栏上的按钮可以创建一个新的参数,单击按钮可以删除一个参数,单击按钮可以把参数的顺序上移,单击按钮可以把参数的顺序下移。
选择其中一个参数,对象观察器将同步显示该参数的属性。其中,ParamType属性必须设置,以指定参数的使用类型,可以设为Input、 Output、Input/Output或Result。DataType属性也必须设置,以指定参数的数据类型。注:对于Oracle的存储过程来说, 要返回数据集,必须把DataType属性设为ftCursor。对于输入参数或输入/输出来说,必须设置Value属性给参数赋值。不能对输出参数和状 态参数赋值。
10.5.6 怎样在运行期访问参数
如果服务器没有提供有关参数的信息,就必须自己建立参数。在运行期,可以通过TParam的Create或TParams的AddParam来创建一个参数。
例如,InterBase服务器上有一个存储过程叫GET_EMP_PROJ,这个存储过程有一个输入参数叫EMP_NO和一个输出参数叫PROJ_ID。这个存储过程的代码如下:
CREATE PROCEDURE GET_EMP_PROJ (EMP_NO SMALLINT)
RETURNS (PROJ_ID CHAR(5))
AS
BEGIN
FOR SELECT PROJ_IDFROM EMPLOYEE_PROJECT
WHERE EMP_NO = :EMP_NO
INTO :PROJ_ID
DO
SUSPEND;
END
下面通过编程动态地创建这两个参数:
var
P1, P2: TParam;
Begin
...
With StoredProc1 Do
Begin
StoredProcName := 'GET_EMP_PROJ';
Params.Clear;
P1 := TParam.Create(Params, ptInput);
P2 := TParam.Create(Params, ptOutput);
TryParams[0].Name := 'EMP_NO';Params[1].Name := 'PROJ_ID';
ParamByname('EMP_NO').AsSmallInt := 52;
ExecProc;Edit1.Text := ParamByname('PROJ_ID').AsString;
FinallyP1.Free;
P2.Free;
End;
End;
...
End;
10.5.7 ParamBindMode属性
这个属性用于设置Params属性中的每一个参数与存储过程的参数怎样匹配。
如果ParamBindMode属性设为pbByName(默认),表示Params属性中的参数按名称与存储过程的参数匹配。
如果ParamBindMode设为pbByNumber,表示Params属性中的参数按序号与存储过程的参数匹配。
建议把ParamBindMode属性设为pbByName,因为按名称匹配不需要参数的顺序,而按序号匹配往往容易搞错。不过,有的情况下可能需要按序号匹配,因为有的服务器并没有提供参数的名称。

说明:文章所有内容截选自实验楼教程【MyBatis 框架基础入门】第一节~

1.建立临时表

  为避免上述的麻烦,我们可以在编写网络数据库应用程序时采用结构化查询语言 SQL(Structured Query Language),这样不仅可以更方便地与诸如 SQL Server、Oracle 等各种后台数据库进行动态的数据交换,而且可以使程序的修改和移植更加灵活。我们以数据输入模块为例,说明开发客户/服务器应用程序时如何采用 SQL 语句实现数据处理功能。首先,判断是否已经有事务处理程序在运行,如果有,将其回卷(rollback);如果没有,则启动一个新的事务,为数据的最终处理做准备。其次,是设置 SQL 语句,并将其写入 TQuery 构件中。最后,将事务提交或回卷,至此完成一条记录的数据输入。

1.1 实验内容

本节课程将介绍 MyBaits 框架的整体设计,包括功能架构和框架架构。

数据输入是开发数据库程序的必然环节。在Client/Server结构中,客户端可能要输入一批数据后,再向服务器的后台数据库提交,这就需要在本地(客户端)建立临时数据表来存储用户输入的数据,待提交后,清除本地表数据。这种方法的好处是:提高输入效率,减小网络负担。

  下面是以页面中的 TEdit 类型编辑框内容作为数据源,向数据库输入记录的过程代码:

1.2 实验知识点

  • MyBaits 概念
  • MyBaits 架构

由于用户一次输入的数据量一般情况下较小(不会超过几百条记录),所以临时表可以建立在内存中,这样处理速度较快。

procedure DataInsert(const qName:TQuery;            szDBName:string;iNum:Integer;            iMark:array of Integer;eName:array of TEdit);  var  i : Integer;  szSQL : string;  begin  if DataModule1.DataBase1.InTransaction=true then  DataModule1.DataBase1.RollBack;  DataModule1.DataBase1.StartTransaction;  szSQL := INSERT INTO +szDBName+ VALUES(  for i:=0 to iNum-1 do   begin    if iMark[i]=0 then     szSQL := szSQL+eName[i].Text {非字符方式}    else     szSQL := szSQL+"+eName[i].Text+"; {字符方式}    if i=iNum-1 then     szSQL := szSQL+)    else     szSQL := szSQL+,;    end;    qName.Close; {关闭查询}    qName.SQL.Clear; {清SQL特性内容}    qName.SQL.ADD(szSQL); {添加SQL内容}    szSQL := SELECT * FROM +szDBName;    qName.SQL.ADD(szSQL);    qName.Open; {返回结果集}    DataModule1.DataBase1.Commit;    end;

2.1 什么是MyBatis

首先,我们来了解一下什么是 ORM ?

ORM(Object/Relational Mapping),即对象关系映射,它完成面向对象的编程语言到关系数据库的映射。ORM 工具的唯一作用是:把持久化对象的保存、修改、删除等操作,转换成对数据库的操作。

ORM 基本映射关系:

  • 数据表映射类
  • 数据表的行映射对象
  • 数据表的列映射对象的属性

MyBatis 本是 apache 的一个开源项目 iBatis , 2010年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis 。

MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及对结果集的检索封装。MyBatis 可以对配置和原生 Map 使用简单的 XML 或注解,将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。

MyBatis 的主要思想是将程序中的大量 SQL 语句抽取出来,配置在配置文件中,以实现 SQL 的灵活配置。

MyBatis 并不完全是一种 ORM 框架,它的设计思想和 ORM 相似,只是它允许直接编写 SQL 语句,使得数据库访问更加灵活。因此,准确地说,MyBatis 提供了一种“半自动化”的 ORM 实现,是一种 "SQL Mapping" 框架。

方法1:使用查询控件(TQuery)

以上过程包含五个参数,实现从页面中的一系列编辑框中读取数据,并向指定数据表输入的功能。其中,参数 qName 为页面中所使用的 TQuery 类构件的名称;参数 szDBName 是数据表的名称;参数eName 是 TEdit 类型的数组,列出了页面中包含数据的各编辑框名称;参数 iNum 是数据表中的字段个数,也即编辑框的个数;参数 iMark 是一个整数类型的数组,该参数表明相应字段是以何种方式输入的,如果是字符方式,需要在数据前后两端加上引号。需要注意的是:在调用本过程之前,应将数据库连接打开:

2.2 功能架构

Mybatis的功能架构分为三层:

图片 1此处输入图片的描述

  • API接口层:提供给外部使用的接口 API,开发人员通过这些本地 API 来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

  • 数据处理层:负责具体的 SQL 查找、SQL 解析、SQL 执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

  • 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件,为上层的数据处理层提供最基础的支撑。

第1步:在窗体上放上查询控件(TQuery),设置好所连接的数据表。

DataModule1.DataBase1.Connected := true;
  过程调用完成后,将数据库连接断开:

2.3 框架架构

图片 2此处输入图片的描述

  • 加载配置:MyBatis 应用程序根据XML配置文件加载运行环境,创建 SqlSessionFactory,SqlSessionFactory,配置来源于两个地方,一处是配置文件,一处是 Java 代码的注解,将 SQL 的配置信息加载成为一个个 MappedStatement 对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。

  • SQL 解析:当 API 接口层接收到调用请求时,会接收到传入 SQL 的 ID 和传入对象(可以是 Map、JavaBean 或者基本数据类型),Mybatis 会根据 SQL 的 ID 找到对应的 MappedStatement,然后根据传入参数对象对 MappedStatement 进行解析,解析后可以得到最终要执行的 SQL 语句和参数。

  • SQL 执行:SqlSession 将最终得到的 SQL 和参数拿到数据库进行执行,得到操作数据库的结果。

  • 结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成 HashMap、JavaBean 或者基本数据类型,并将最终结果返回,用完之后关闭 SqlSession。

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 是单个数据库映射关系经过编译后的内存映像。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。SqlSessionFactory 是创建 SqlSession 的工厂。

SqlSession 是执行持久化操作的对象,它完全包含了面向数据库执行 SQL 命令所需的所有方法,可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。在使用完 SqlSession 后我们应该使用 finally 块来确保关闭它。

第2步:使TQuery. CachedUpdates=True;

ataModule1.DataBase1.Connected := false;
另外,开发网络数据库应用程序时,还可以使用存储过程,即:将预先编译过的 SQL 语句存储在服务器上。存储过程提前运行,且不与程序代码一同存储和编译,因此其对应主程序中的代码相对简洁,运行速度也较快。SQL 语句的集中存放,使其修改更容易。

2.4 MyBatis 的优点

  1. 简单小巧易于上手,方便浏览修改 SQL 语句
  2. 解除 SQL 与程序代码的耦合
  3. 提供映射标签,支持对象与数据库的 ORM 字段关系映射
  4. 提供 xml 标签,支持编写动态 SQL

本次课程介绍了 MyBatis 的相关知识,为后续的 MyBatis 深入课程打下了基础。

  • Mybatis原理分析之二:框架整体设计
  • Mybatis简介与原理
  • Mybatis 百度百科
  • mybatis学习笔记-mybatis概述
  • 《Spring+MyBatis 企业应用实战》

以上是MyBatis简介,后面还有多节内容:

图片 3image.png

如果你想查看完整教程,点击【MyBatis 框架基础入门】即可马上查看了~

TQuery. RequestLive=True

  要创建向数据表中输入数据的存储过程,代码编写举例如下:

第3步:在原有的SQL语句后加入一条Where子语句,要求加入这条Where子语句后SQL查询结果为空。

CREATE PROC ProcTest1  @inttest smallint  ,@strtest char(4) output  AS  INSERT INTO TEST_User.TRANS_TEST  VALUES(@inttest,@strtest)  SELECT @strtest,* FROM TEST_User.TRANS_TEST
以上代码向数据表 TEST_User.TRANS_TEST 添加数据,该数据表包括两个字段:第一个字段为 smallint 类型的数据,参数类型定为 Input(在存储过程中可缺省);第二个字段数据为长度为4 的字符类型,参数类型为 Output。

例如:

  其模块程序的编写与 DataInsert 过程相似,区别主要在于模块的中间部分,对应的主要代码如下:

  SELECT Biolife.″Species No″, Category,
            Common_Name, Biolife.″Species Name″, Biolife.″Length (cm)″,
            Length_In, Notes, Graphic
               FROM ″biolife.db″ Biolife
              where Biolife.Category=′A′ and Biolife.Category=′B′

StoredProc1.Close;   {关闭存储过程}  StoredProc1.Params[1].ParamType := ptInput;   {设置存储过程的参数类型}   StoredProc1.Params[1].AsInteger := 1;  {设置存储过程中参数的数据}  StoredProc1.Params[2].ParamType := ptOutput;  toredProc1.Params[2].AsString := abcd;  StoredProc1.Open; {打开存储过程}
其中,StoredProc1 是 TStoredProc 类型的构件名称;Params[1] 是存储过程中的第一个参数,对应存储过程 ProcTest1 可以用ParamByName(@inttest)代替;存储过程的第二个参数与其类似。

这样临时表就建立完成了。

  实际上,编写对网络数据库进行其他数据处理(如:修改、删除和查询等)的模块,与数据的输入模块大体相似,这里就不再赘述了。

方法2:使用代码创建临时表

代码如下:

  function CreateTableInMemory(const AFieldDefs:TFieldDefs):TDataSet;
              var
            TempTable:TClientDataSet;
              begin
               TempTable:=nil;
               Result:=nil;
               if AFieldDefs<>nil then
               begin
               try
               TempTable:=TClientDataSet.Create(Application);
               TempTable.FieldDefs.Assign(AFieldDefs);
               TempTable.CreateDataSet;
               Result:=(TempTable as TDataSet);
               Except
               if TempTable<>nil then
            TempTable.Free;
              Result:=nil;
               raise;
                end
            end
             end;

在程序中按如下方法使用:

  procedure TForm1.Button1Click(Sender: TObject);
              var
            ADataSet:TDataSet;
              begin
               ADataSet:=TDataSet.Create(Self);
               with ADataSet.FieldDefs do
               begin
               Add(′Name′,ftString,30,False);
               Add(′Value′,ftInteger,0,False);
               end;
               with DataSource1 do
               begin
               DataSet:=CreateTableInMemory(ADataSet.FieldDefs);
               DataSet.Open;
               end;
               ADataSet.Free;
              end;

临时表创建完成。

方法1使用简单,但由于利用查询控件,清空数据时需要查询服务器后台数据库,所以速度稍慢,而且不适用于临时表中各个字段由数个数据表的字段拼凑而成的情况。方法2适用范围广、速度快,但需要编写代码。(代码中TFieldDefs的使用方法十分简单,见Delphi的联机帮助)。

2.配置数据引擎(BDE、SQL Link)

有关数据库程序分发时,需要携带数据引擎(BDE、SQL Link),并且在客户端安装完程序后还需要配置数据引擎,如用户名(username)、密码(Password)等等。如果手工配置的话,工作量比较大(根据客户机数量而定)。而InstallShield For Delphi又好像没有这方面的选项,其实InstallShield For Delphi可以做到,在生成安装程序的目录里有一个*.iwz的文本文件,只要在[IDAPI Alias]片段中手工加入即可。 例如:

   [IDAPI Alias]
               usesname=SYSDBA
               password=masterkey

  

安装程序后数据引擎自动配置完毕。

3.在InterBase数据库中使用函数

程序员可能在用InterBase作为后台数据库时,会为其提供的函数过少而感到不方便(只有四个),无法方便地编写出复杂的存储过程。InterBase本身无法编写函数,但它可以使用外部函数(调用DLL中的函数)。下例中说明如何在InterBase 中声明SUBSTR函数。

  DECLARE EXTERNAL FUNCTION SUBSTR
               CSTRING(80), SMALLINT, SMALLINT
               RETURNS CSTRING(80)
               ENTRY_POINT ″IB_UDF_substr″ MODULE_NAME ″ib_udf″

其中:MODULE_NAME为DLL的名称,ENTRY_POINT为函数名。

声明后便可以使用,例如:

  select SUBSTR(country)
               from country

本例使用的是Delphi安装时自带的IBLocal数据库。用户也可以自己编写函数来扩充InterBase

数据输入是开发数据库程序的必然环节。在Client/Server结构中,客户端可能要输入一批数据后,再向服务器的后台数据库提交,...

本文由美高梅网址发布于新闻中心,转载请注明出处:利用Delphi开发网络数据库应用,用Delphi开发数据

上一篇:字符串拼接速度再议,减少垃圾回收压力的字符 下一篇:没有了
猜你喜欢
热门排行
精彩图文