DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: laidabin
今日帖子: 1
在线用户: 1
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 seven_14 (seven_14) ★☆☆☆☆ -
普通会员
2017/3/15 11:06:15
标题:
真三层?假三层? 浏览:2740
加入我的收藏
楼主: 请教各位大侠:
这么多年我写的桌面程序一直都是C/S的,偶尔有些用的是WebService,有个问题一直不是非常明白,就是看到很多人实现的三层架构,都是把SQL语句作为参数从客户端直接传给中间层的函数。然而我理解的三层架构,是客户端不需要知道、也不能知道具体的SQL语句要怎么写,而是直接调用中间层的函数(API、接口等)即可。也就是说,由中间层提供和数据库的连接池、拼接SQL语句并取得结果集然后返回给客户端等等。如果客户端直接传SQL给中间层,那要中间层还有什么实际意义(除了数据库连接池和控制客户端连接以外)?因为这样的话相当于客户端还是了解后台数据库结构的。我认为这属于假的三层架构。
现在流行的网页API(就像微信、支付宝等提供的API),客户端调用的话肯定不需要直接传SQL。我认为这才是真正意义上的三层。

另外,如果是“真”三层的话,自定义查询如何实现比较好呢?

请各位不吝赐教。
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/3/15 11:13:05
1楼: 你的理解是对的。
传 SQL 的 不能算 假的,但也是一种不好的习惯。

这都是 datasnap 给惯出来的毛病。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 delphiilove (乌羽玉) ★☆☆☆☆ -
普通会员
2017/3/15 11:32:13
2楼: 把 SQL 的执行 封装在 中间层,这样才更好,DataSnap 也能这么做。
----------------------------------------------
-
作者:
男 vmao (毛小毛) ★☆☆☆☆ -
盒子活跃会员
2017/3/15 11:36:51
3楼: SQL本身就是String,传String有什么不好的?特别是有些复杂的SQL查询,需要前台拼接好,甚至有关联子查询什么的。后台写更困难。
----------------------------------------------
-
作者:
男 luckyrandom (luckyrandom) ★☆☆☆☆ -
普通会员
2017/3/15 11:37:59
3楼: 有些概念是逻辑上的,实现不一定要完全一板一眼
有些地方要讲开发效率及项目工期,有些灵活性需要平衡
----------------------------------------------
SQL SERVER DBA QQ:315054403 曾经的Delphier  缘在上海
作者:
男 142857 (142857) ★☆☆☆☆ -
禁用账号
2017/3/15 14:07:48
4楼: ……
被禁用帐号,帖子内容自动屏蔽!
……

----------------------------------------------
发布广告,禁用帐号!
作者:
男 pankangkang (aaaa) ★☆☆☆☆ -
普通会员
2017/3/15 15:25:56
5楼: 这种直接访问数据库的三层 其实没什么意思  要么自己再封装一层,每一个表写一个操作类  但这样就比较费时

好一点的方法是 webservice 可以看看phprpc
----------------------------------------------
-
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2017/3/15 15:53:17
6楼: 需要从两方面来说:

一方面,需要稳定、强大、开发简便、维护方便的“服务端业务容器”,有的又称“软总线”、“插件框架”、“插件容器”等等;

另一方面,客户端,则需要对应封装到位、适用面广、使用简单的调用手段——Delphi VCL控件/FireMonkey控件/JsonRPC/XmlRPC/AJAX等。


在这方面,QuickBurro自然也是走在前列,若干年前就已经很强大,如今更是:

一、服务端支持C/S三层插件、Web插件、移动服务插件、WebSocket服务插件等多种类型的插件;支持单线程/多线程调用方式;支持同步/异步调用模式;支持计划任务形式的主动激发;支持立即返回/驻留模式;支持预加载/延迟卸载机制;支持插件API入口注册与横向调用;支持调用大量的主服务API函数;支持热插拔/远程插拔;支持HTTP/HTTPS/TCP/WebSocket多种通信协议...

二、客户端控件:VCL下提供专门的基于TCP协议和HTTP协议的RPC控件TDllPlugin、提供基于HTTPS实现的Web插件调用控件TQBHttps,只要给出服务端部署的插件名、设定好控件属性、准备好调用参数,就可以方便调用,调用结果也可以方便进行反序列化处理;  FireMonkey下,提供TMBRpc/TMBHttps两个专门进行远过程调用的控件,也一样能轻松进行BinaryRPC/JsonRPC/XmlRPC等调用;  而Web前端,通过AJAX进行RPC调用,一样简单方便。


仔细地了解、试用一下,你就能喜欢上: http://www.quickburro.org
----------------------------------------------
樵夫的大马甲
作者:
男 zyp1984 (小李他妈的飞刀) ★☆☆☆☆ -
普通会员
2017/3/15 16:37:51
7楼: @wang_80919  datasnap的功能还需要强化...
----------------------------------------------
山外青山楼外楼,能人背后有能人弄..
作者:
男 luxiaoan (luxiaoan) ★☆☆☆☆ -
普通会员
2017/3/15 20:20:41
8楼: RO+DA 就很好用, 防注入的话 AES 加密就好了。
有时候为了开发效率读取一些数据 ,SQL还是效率更高,只要不全是就好了吧,
个人观点,不喜勿喷
----------------------------------------------
-
作者:
男 tianpanhaha (tianpanhaha) ▲▲▲▲△ -
普通会员
2017/3/15 21:31:16
9楼: 6楼打的一手好广告
----------------------------------------------
 QQ群:325010556 欢迎加入。
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2017/3/15 22:51:41
10楼: 六楼是个说实话的人!
一是一,二是二,每句都经得起考验
----------------------------------------------
樵夫的大马甲
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/3/16 8:39:43
11楼: 设 10 楼 和 6 楼 一个说真话,一个说谎话。
求 樵夫 的 心里阴影面积。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 joesyuan (joes) ★☆☆☆☆ -
盒子活跃会员
2017/3/16 9:08:28
12楼: 三层的概念一直有争议。我个人的看法是从负载均衡,数据库隔离来说,三层有它
的价值。至于传SQL也未尝不可,只是要防止sql注入的问题。
曾有一个时期,言必称三层,把一些简单的局域网应用也硬生生抽一个三层出来,我觉得还不如直接传sql呢。
倒是web程序就是天然的三层,你不会在客户端直接传sql吧。
我觉得要考虑的是用三层解决什么问题。而不是为三层而三层。
----------------------------------------------
-我爱Delphi6
作者:
男 seven_14 (seven_14) ★☆☆☆☆ -
普通会员
2017/3/16 9:26:01
13楼: 看各位的讨论确实受益匪浅。
之所以有这疑问,其实相当一部分原因就是让clientdataSet的commandtext给搞晕的。。。

樵夫的快驴早就知道了,不过从来没有深入了解过。

“ 防注入的话 AES 加密就好了”:这句话如何理解?加密拼接后的SQL然后在中间层解密?没用的啊,拼接后的就是已经被注入的SQL的话,加密某用啊。

“我觉得要考虑的是用三层解决什么问题。而不是为三层而三层。”
非常赞同这句话
----------------------------------------------
-
作者:
男 nihaongy (nihao) ★☆☆☆☆ -
普通会员
2017/3/16 9:30:01
13楼: 好帖子,作个记号
----------------------------------------------
-相互学习,共同进步! 努力每一天,不能望山跑死马
发上等愿,结中等缘,享下等福;择高处立,寻平处住,向宽处行
作者:
男 mprjcf (mprjcf) ★☆☆☆☆ -
普通会员
2017/3/16 9:53:15
14楼:
“ 防注入的话 AES 加密就好了”:我理解是客户端拼接好SQL语句,然后加密传中间层,中间层解码出SQL语句,交给数据库。还是非常实用的方法。
----------------------------------------------
他们总是取笑失败者,以酷似智者;他们也总是为成功者喝采,以取得赏金。
作者:
男 runsheng (srs) ★☆☆☆☆ -
普通会员
2017/3/16 10:13:59
15楼: 我觉得要考虑的是用三层解决什么问题?我认为主要是解决数据库连接池和网络安全域两方面的考虑,兼顾两层、三层语法尽量一直(两层易于改为三层),中间层只转发sql而不进行逻辑编程(降低程序复杂度、避免总改中间层而出现bug),没有上真三层、假三层之分。
http://download.csdn.net/detail/runsheng678/4812549 以前的例子,已改到Delphi 10 seattle下了。
----------------------------------------------
-
作者:
男 luxiaoan (luxiaoan) ★☆☆☆☆ -
普通会员
2017/3/16 10:25:27
15楼: @ seven_14  AES  加密 你前端 后端又统一的 加密密码,你没有加密密码根本过不去,密码不对 到后台解密不可能得到可执行的 SQL 。
如果你要说拿前台的程序用editplus 打开找到 AES 密码, 那就没办法防注入了。
@mprjcf 正解
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/3/16 11:14:17
16楼: 防注入,要检查所有输入框
1 使用 QuatedStr 包裹,不要 '''' + Str + '''';
2 有了上面的 1 ,就不需要 2 了。但是如果你没有1 ,那么请 检查输入的内容是不是 有 单引号 and or 等 sql 关键词。 
3 如果能没有空格,就不让输入空格。

接口允许传 SQL,用 加密的方法就行了。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 snakegao (snakegao) ★☆☆☆☆ -
盒子活跃会员
2017/3/16 11:30:35
17楼: 虚心楼上大虾们学习!!!
----------------------------------------------
-
作者:
男 chonghai (DBlue) ★☆☆☆☆ -
盒子活跃会员
2017/3/16 12:02:04
18楼: 赞同15楼的看法。(有两个15楼?我指的是第一个15楼 @runsheng)
我做过datasnap的三层,有些固定的业务逻辑就做成API进行调用,有些经常变化的业务就直接使用sql调用了。
做三层主要还是数据的连接方式很方便,不需要直连数据库,只要连接中间服务器,而且还可以无状态连接。另外,也间接防止了数据库连接数过多的限制。

感想是:小型项目可以这么做,大型的项目还是老老实实地用中间件模型来写。
----------------------------------------------
喜欢Delphi,关注Delphi,愿和广大爱好者交朋友。
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2017/3/16 12:44:25
19楼: 1、业务逻辑经常变而接口形式不变的、或后续可能有新的替代方案的处理过程
2、需要与大量数据打交道、不适合客户端进行的处理过程(比如汇总、报表生成等)
3、需要加强安全性控制、保护知识产权等权益的处理过程
4、需要排队处理的业务逻辑
5、需要与服务端数据库之外的其他资源有交互的过程
6、相对通用、适合服务端封装为可复用模块的
7、涉及服务端系统集成、与周边系统有接口的业务
8、需要服务端主动处理并反向推送信息给客户端的任务
9、服务端实现对提高系统性能、减少消耗、提高可靠性有利的业务逻辑
...
----------
类似这些,我都会做服务端业务逻辑模块,客户端来调用。

至于是否客户端写SQL语句,感觉没必要纠结,非常简单明确的业务处理,没必要迂腐地要弄个专用的服务端模块再来调用实现,毕竟研发成本也是重要的考虑因素。

而注入什么的,对于编译型开发工具Delphi来说,感觉不是个很严重的问题。
----------------------------------------------
樵夫的大马甲
作者:
男 jopher3 (樵夫的马六甲) ▲▲▲▲▲ -
普通会员
2017/3/16 12:58:38
20楼: 当然,还有重要原因:

分工协作、不同层不同开发单位来实现时,做成“业务逻辑模块+客户端RPC”形式,是首选的;人手多、能更艺术地实现多层应用、以便以后升级维护简单的——大概也会选这样的模式
----------------------------------------------
樵夫的大马甲
作者:
男 abencat (远离delphi的人) ★☆☆☆☆ -
盒子活跃会员
2017/3/17 9:39:56
21楼: 尽信书不如无书    书呆子
----------------------------------------------
delphi爱好者
作者:
男 inbreak (入侵) ★☆☆☆☆ -
盒子活跃会员
2017/3/17 10:01:32
22楼: 我的做法,是把 SQL语句写在 服务器端(其实是保存到数据库中);

客户端只需要 传递一个 序号(对应某SQL语句在数据表的序号),和一些参数传到服务器端就好。其它的交给服务器处理了,然后再把结果返回来;

例从服务器获取数据:

function dm_sys.GetData(const SQL_XH: Integer ;Param:array of string): _Recordset;
var
   V,SendV:OLEVariant;
   i,n : Integer;
   AR:_Recordset;
   AStream:_Stream;
   MS1:TMemoryStream;
   P:Pointer;
begin 
  n := Length(Param);
  SendV := VarArrayCreate([0,n],varOleStr);
  for I := Low(Param) to High(Param) do SendV[i] := Param[i];
  try
    V:=Disp_Fun.ProF_ReadAdoData2(SQL_XH,n,SendV);
    MS1:=TMemoryStream.Create;
    try
      MS1.Size:=VarArrayHighBound(V,1)+1;
      P:=VarArrayLock(V);
      try
        Move(P^,MS1.Memory^,MS1.Size);
      finally
        VarArrayUnLock(V);
      end;
      V:=VarArrayCreate([0,MS1.Size-1],varByte);
      P:=VarArrayLock(V);
      try
        Move(MS1.Memory^,P^,MS1.Size);
      finally
        VarArrayUnLock(V);
      end;
    finally
     FreeAndNil(MS1);
    end;
    AStream:=CoStream.Create;
    AStream.Open(EmptyParam,adModeUnknown,adOpenStreamUnspecified, '', '');
    AStream.Type_:=adTypeBinary;
    AStream.Write(V);

    AR:=_Recordset(CoRecordset.Create);
    AStream.Position:=0;
    AR.Open(AStream,EmptyParam,adOpenUnspecified, adLockUnspecified, -1);
    Result:=ADOInt._Recordset(AR);
  except
   on E:Exception do begin
     ShowErrorMessage(E.Message);
   end;
  end; 
 

end;

如果有那种特殊情况在要客户端传递SQL语句的,就加密传去就好。
----------------------------------------------
我是菜鸟,己经搞了十多年了,但是我仍然很菜。
作者:
男 gaoyong_gy (gaoyong_gy) ★☆☆☆☆ -
盒子活跃会员
2017/3/22 21:02:25
23楼: 建议2种模式混合使用。数据库管理员负责写服务端,界面设计者负责填写数据,如果sql语句很短的话,发时需要时(如服务端忘记写了),也可以直接传sql语句,以后在服务端再补上就行。

这样一个程序一般3个人配合,大家一起分析需求,一个负责美工实现,一个负责界面设计并填写数据,一个负责数据库设计并写好服务端。

当然,一般小程序都是一个人完成这所有的事情。

  http://blog.163.com/you888@188/blog/static/6723961920159271412582/
----------------------------------------------
Delphi 的移动程序开发,是您不可再错失的机遇:http://blog.163.com/you888@188/blog/static/6723961920169319529515/
作者:
男 bigboy2050 (bigboy2050) ★☆☆☆☆ -
普通会员
2017/5/22 14:38:01
24楼: 厉害了!
----------------------------------------------
kittyapp
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2017/5/22 15:59:16
25楼: 传 SQL 的纯粹设计者习惯,跟C/S与三层没关的.科学与统计应用就会由客户端传SQL,所以是说不定的.三层也不过是粗略的概念,每一层内可以复杂得很,也可以每层只有单机.在那些上市级的网络服务商,他们的服务层还会分上三层,数据层也可分两层.别管这些啦.三层的起始理念,就是分工合作,方便扩展,负载平衡,监察除错,进而就是保安.最常见客户要求三层式,却只付出单机的价码.三层就以为是三部电脑.这三层就没什么意义.

为何听到新闻上的IT专案,动辄上亿元成本.数据端用上RAID 6是基本的,用上SAN的一套最少也要两千万.多地存放(数据中心),及时备电供应,做到个别挂机不死,个别网段断线不死,这才是三层的原始意义.因此不是说笑的,很多码奴一世没有这种机遇做一套真三层.能当的都是一整个团队,整个工作生涯去服务一套三层而已,那何必苦苦追求这种定义呢.

23楼说的就是外间的现实.码奴不是一个身分,码奴是需要分别 Application programmer; System programmer; Database administrator; System Analysis 背后还有 Data librarian; Art Designer; Documentation Writer; System operator; Network Engineer; Sales Technician; Project manager. 大家各施己职.如果连团队的基本结构都不会分辨分工,三层的定义又何需执着.
----------------------------------------------
-
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2017/5/22 16:20:28
26楼: 多说一点,大家平常会以服务层作数据分析操控.但其实真正的三层,所有数据分析操控都由后端SQL处理.服务层只负责叫后台很复杂的SQL procedure,加减数尽量都不由服务层做.因此Database administrator不是真的管理工作,而是SQL programmer,能写非常复杂的SQL.其工资可以是Application programmer 的1.5倍至4倍.
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/5/22 17:04:14
27楼: 很多公司都是希望请一个 DELPHI 开发来代替 数据库工程师 代替前端 代替美工 代替网管 代替清洁工 。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2017/5/22 19:22:21
28楼: 中国人嘛,大家懂的.刻毒凉薄无限权利不付代价.以前有学会做过调查,一般中国人当老板的,都应为公司多大也顶多用一两个IT人就够,IT人的工作不是你我所知的那么多且复杂,而相当数量中国老板认为,要他付钱请人回来玩电脑,还经常要求金钱开支,IT人的薪资就是过高,甚至根本不该收取工资.当然他们平常不会说出这心声.而调查也指,中国人当老板,对IT人的愿付薪酬水平,比大门的接待小姐还要低.中国人一般认为IT人就是一种职业,任何与科技有关的都应该是IT人的责任.与其他国家的认知差很远.
----------------------------------------------
-
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2017/5/22 19:27:56
29楼: 在中国,一间软件开发公司能有四成是开发人员,已经非常难得.在其他地区,少于八成是开发人员肯定会被股东/投资者/银行/财务评级机构等所责难,公司的领导可能连饭碗都不保.
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/5/22 19:30:25
30楼: 不知道,微软苹果这种大公司,做销售和管理等非开发工作的比例是多少。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 pp0123 (pp0123) ★☆☆☆☆ -
普通会员
2017/5/23 1:09:24
31楼: 苹果不是软件公司。微软基本是分配与子公司的,以华盛顿的总部,超过九成半都是技术人员。各地的销售分公司,最少三分二员工都要IT资格认证。
----------------------------------------------
-
作者:
男 lsz100 (lsz) ★☆☆☆☆ -
盒子活跃会员
2017/5/23 9:39:13
32楼: 微信、支付宝这种有多少业务量。 (最多就是扣钱 查个钱什么的)他主要是高并发和安全性。在中间应用层拼接SQL,用接口给客户端调用完全可行。但是企业ERP开发和这个完全不同 你开发过就知道了。 这个业务需求量太大了,如果把SQL写在中间层 ,维护和开发都很麻烦的 。
----------------------------------------------
我为人人为我
作者:
男 lsh341999 (虫子) ★☆☆☆☆ -
普通会员
2017/5/23 13:54:03
33楼: 又来纠结这东西了
----------------------------------------------
就怕想不到,没有做不到的
作者:
男 wuxi15 (似水·流年) ▲▲▲▲▲ -
普通会员
2017/5/23 14:05:00
34楼: 这两种三层,datasnap都是可以做的。有些简单的业务,直接由客户端传SQL相对于在服务端写SQL很简单的多,开发人员自然就在客户端写的。
----------------------------------------------
-
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2017/5/23 17:30:51
33楼: Delphi也可以做所谓的真三层,但那样一来就没办法快速开发了,也就失去了Delphi的最大优势:快速开发。 ^o^
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 博客挂了……
作者:
男 lps (lps) ★☆☆☆☆ -
盒子活跃会员
2017/5/23 18:27:39
35楼: 同意21、34和两个33楼!
三层是一种思想,就和数据库的范式一样,非要追求真的,就失去了本意
----------------------------------------------
-
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/5/23 18:29:25
36楼: 同意楼上。
这就叫观点复用。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 sczhyq (旺财) ★☆☆☆☆ -
普通会员
2017/5/23 21:16:48
37楼: 这个就是“屁股决定思维”

在什么情况下使用怎样的最佳解决方案才是王道
----------------------------------------------
我84砖家
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行88.86719毫秒 RSS