Discussion on two floors and three layers

zhaozj2021-02-16  114

The following things are reposted, including that statement, it doesn't matter. Google searched. Before this, I really think that the three layers of the DataSetProvider ClientDataSet and the understanding are a bit different. After reading these discussions, the conclusion is that DataSetProvider ClientDataSet is indeed three floors. But for the first brother, it is easy to write it to the three floors, which is to associate clientDataSet to the specific data table structure. This does not comply with the principles of interface and data separation. The three layers of understanding: the interface layer communicates with the business layer through the object of the object, while the business layer accesses the database in the object's method. Basically, each object corresponds to a table or several related tables. An important issue in this implementation method is how to encapsulate the data set into the properties of the object. ClientDataSet has solved this problem. CLIENTDataSet is much mature than to define data formats yourself. That is, the clientDataSet corresponds to the data set processed by the business layer, which is not the original data sheet. When the database is changed, there is no need to make any changes to ClientDataSet, just modify the processing logic of the business layer. This is the correct usage of the DataSetProvider ClientDataSet. If only the clientDataSet corresponds to the data table, this three-layer is meaningless, but it is only moving all the works of the database to the middle layer.

----------------------------------------- Original address http: // lincosoft. Go.nease.net/originalarticle/twotierotritier.htm

First of all, I declare that I am a three-story loyal assistant. Whether it is in theoretical level or in practice levels, the three-layer structure has an indispensable advantage, and now the three floors, the three floors, we can only Learn three floors, only learn three floors to make Money to feed the wife and children (^ _ ^). I recommend this post to let everyone think that it is good to use two layers. I want everyone to think with DatasetProvider ClientDataSet is not a real three-story, this is the main harvest of this post. My point of view: DataSetProvider ClientDataSet is indeed three layers, but it is a three-layer highly packaged three-layer, which is the fastest technology for the development of three-story structural projects (project is a system constraint, can't pursue the so-called real three-layer Digging period). If you learn the three-story development, it is best to take a look at the J2EE's Dongdong, look back and apply it to the three-story development of Delphi. Ok, don't say nonsense, let's take a look at the group of congress in the next!

------------------------ Yang Zhongke

Win2000 SQL2000 development large system is good or more layers!

I think the current technique is superior to multi-layers. The current database technology has been more qualified than previously, and the technology of ADO has also reached 2.8. I used Delphi to test in the P4 platform, 1.7GCPU, 40G hard drive, 256 megabo, can complete the following steps in the Win and SQL2000: "Connect to the database, open the database, add data , Query several rows, turn off databases, disconnects. Note: It is not completed by one percent, but nearly 100 times. (Use ADO Action SQL2000), the above example illustrates that you can connect the database when you want to use the database, when you use the database, you can disconnect the database when you use the database. Implemented on Microsoft's platform. There is no advantage in the number of plots on the number of connections. In terms of scalability, it is better than three layers, and the two layers can use modular development, one function a module, one of the modules to be responsible, different modules combine into a large system, and the increase or decrease is only increased or decrease. Module. If the three floors will add a new method to the application application server layer, it is necessary to be part of the customer layer design interface, not to be part of a holistic module, just like people. On the dynamic update, the second layer is also better than the multi-layer. If an application logic on the application server is being modified (increased or decreased business logic), it must be turned off, replacing the new version after replacing the new version. In rebooting the application server, all clients cannot work in the time of turning it (even if users do not associate to increase or decrease business logic). If you also increase or decrease the client interface, you have to change the client interface over again. If you are two layers, you use this problem, because all business applications are in the client, we can use Microsoft's dynamic update technology (if you have a new payment, there is a prompt icon in the lower right corner of the desktop), we do Just release a new version, update the movement by the user to determine. Multi-layer is because there is a dynamic update of the application server layer is not as convenient. If the development efficiency is not used, the second layer is definitely better than three layers. The second floor is easy to debug, and the development procedures are easy to read. The SQL2000 in distributed is also a distributed database, and if the system is large enough to construct a large logic SQL2000 by multiple independent SQL2000. Therefore, there is no advantage over the distributed multi-layer. The three-story technology is from the origin of UNIX. The three layers are very good on UNIX. It has also been developed on UNIX. It has a large database to connect to a large database on UNIX. If there is no application server, And use directly, connect once a few seconds, such a product is not used.

Let's talk about so much, just want everyone to discuss, I mean is how good three layers in some books, it is completely copying, it can be said that Zhang Sanli is Dai (UNIX's three-story hat toward Win's head !) From: SmallGhost, Time: 2004-3-1 10:29:36, ID: 2477728 I use two-story development system, multiple layers are too complicated, I don't think it is good! I did a chain POS system 25 stores and did not use multiple layers. The packets were their own format, sent to the store unpacking, which is more secure! From: To be left, time: 2004-3-1 20:12:06, ID: 2479163 I have developed a system with a second floor, there is 160 (at least 100) is about the client, the effect is not bad, but In the LAN, I think if the number of users is not more than 200 in the LAN, and the development of the module is more convenient, the adjustment is convenient, and the logic between the modules does not affect, if you contact the Internet, Three layers still have a certain advantage coming from: zhbj, time: 2004-3-1 20:33:13, ID: 2479207 Yes, the three-layer is more suitable for WAN [Note B / S is also three-story special case], such as cross-border The group or large group system is not suitable for use B / S [integrated business logic is really not appropriate], so it is the most ideal for three-layer, multi-layer but for local area network, SME, whether it is effective, development cycle, easy maintenance, etc. And with the safety mechanism of DBMS, the original security issues also have a quality! Especially in the near future, more and more feelings seem to be replaced by .NET and J2EE from: VB killer, time: 2004-3-1 20:53:31, ID: 2479243 It feels that you can't generally say that it is three or more The two layers are good. Because anything has no passage. As everyone is in the same language every day. No language has its own advantages, VC has the advantage of VC , Delphi also has the strengths of Delphi, in fact, VB is not bad. It is used to do anything. The same truth is that the three layers is good to be two layers. It is not to say that the three layers must be better than two layers. It is necessary to consider a lot of factors. The two layers are simpler than three layers, simple is a large extent, but they can't say that there is two layers than three layers. For example, if a system user is always more than 1,000, then use two layers of structures, it is very difficult to achieve it. The appearance of three layers can solve many problems, more users, maintenance should be three-layer convenient. But for a lot of projects, it is indeed a more occasion of the application of two layers. From: mrzj, Time: 2004-3-2 17:48:04, ID: 2480676 TO: VB killer I think if more than 1,000 large systems are concurrently requested, using multiple layers of realization is very difficult (with WinNT The multi-layer technology implemented by the SQL2000), and it is very convenient to implement the second floor (the dynamic link technology I mentioned earlier). Can think so, the more, the more the advantages of the second layer are more obvious. Example: The current database completely includes the original multi-layer buffer mechanism, such as opening the table, at the table, the table still has a certain time in the memory of the database.

Our software's desk operation is just sending commands. When is the physical desk (clearing the table from the database memory), this is determined by SQL2000. I am here to clarify the misunderstanding of the book. The book is always speaking, and the number of multi-storey execution is high. This is purely misleading the reader. Multi-layer implementation efficiency in more than 95% of SQL2000 is superior to the second layer. That is, it is better to say that ordinary developers should have excellent efficiency of the execution efficiency of the second-layer products developed under circumstances. Some people have been tested in this forum, using BDE, ADO, using the second floor and three layers of tests, I have seen it here, and I can find it here. From: KingPro, Time: 2004-3-12 16:23:46, ID: 2499774 Traditional two-layer database system, essentially separate data access and application, data server executes data access, customers Perform a corresponding application. The user interface and the business logic layer are placed at the client, responsible for requesting and receiving data to the server. When upgrading and maintenance, the task has become particularly heavy, and the software of each client is upgraded and maintained. Multi-layer database systems can solve this problem very well: separated the intermediate layer, enterprise logic processing by specialized servers, such as providing Web Services, Application Serve, making the client become "thin" customers (as long as the browser can ). In terms of efficiency, the two-layer system efficiency is higher. From: VB killer, Time: 2004-3-17 11:10:55, ID: 2506616 to mrzj: Xiongtai said that two layers have realized more convenient than three layers, this I agree. After all, the technical requirements of the three layers are complicated than two layers. Our ultimate system is to make users use, and the system above 1000 users is not small, and the distributed structure should be used, and the system can run normal. If you use two layers, I think the backend database should be paid. (Even if 1000 users can deal with, 1000 users?) There is also a maintenance problem. If the company wants to modify business logic, use two layers, you must update 1000 Client, how large work is. If you use a three-layer, business logic is completely separated from the front interface, and you only need to modify the intermediate layer to OK. Easy to maintain. From: TASSADAR, Time: 2004-3-17 13:28:40, ID: 2506975 I will say a few words, the business logic is only the idealized idea, when the demand or design changes, big Some cases require modification regardless of business logic or interface. The three levels are just a technique for us to choose to use. The key is to look simple from the technical perspective. I think it is very good to use a good three-layer. From: VcandDelphi, Time: 2004-3-17 20:18:53, ID: 2507916 to MRZJ: Don't think that the speed problem can be resolved for the current computer's work ability. Suppose, in the program, there are 48 TTable controls on a customer segment. Other things are not counted, so that every TTable can eat 40K space of your server will be a space that is about 1.5m. . If you use a lot of users, it is a small overhead. Although tQuery will not eat so many space, a lot of clients work together is a small number.

Moreover, the database is not always as good, in reality, its growth is a terrible number, so add a lot of customers, see how fast you can run your database server? If it is three floors, you can use a distributed to solve the pressure of the database server, which is that a fast? There is also a problem, that is, you can't make intelligent judgments on the two layers, and add the work of the server. For example, there is a company's employee to dinner at 12:00 noon at 11: 00-12: 00, you can't handle it every one. I think the two layers, I can only handle this. But the three layers can be judged in the application server, such as how many people to "rice", etc., can be handled once. It belongs to personal opinions, there are differences, please advise. From: CHNPLZH, Time: 2004-3-17 20:55:48, ID: 2507944 I have always used 2 layers of development, 3 layers have concern, don't want to comment too much. The main heart is now in Java. TO KingPro: "When upgrading and maintenance, the task becomes particularly heavy, to perform corresponding upgrades and maintenance of each client's software." I can use the online upgrade function to solve the above problems very easily, I have already implemented. To vcanddelphi: "There are 48 TTable controls on a customer segment", which is not the main problem, and can be resolved by programming skills. From: MRZJ, Time: 2004-3-18 15:08:43, ID: 2509391 VB killer: You mentioned the client upgrade problem, the current two-layer technology is absolutely better than three layers, the second layer can be like Similar to Microsoft's automatic upgrade, the general process is that if you want to upgrade a part of the client, developers can publish files to be upgraded to the web server or FTP server via the Internet, when the client's user performs software, The automatic upgrade module will automatically find a new version on the website. If you ask the customer, do you want to upgrade. This can be upgraded without stopping the work, which is not available in the three-layer. TO: VCANDDELPHI, a logical application corresponds to a programming method of a Table control, whether it is a good design in three layers or two can be said. We build the number of Table controls should be how many concurrent logic applications in the system when designing the system. For example, there are 5 concurrent application logic, then we build 5 Table controls. I am a cumbers of a city, which is not enough for ten concurrent applications, that is, there is no 10 TDataSet in my DataModule. Each TDataSet loads logical app when the module is loaded, and when the module is not released so that the next application module is used. When it comes to the supermarket, I don't believe in three layers (two servers only), one day, the sales data of all the stores is at least 6 million, and there are hundreds of sub-station a qualified query result. Waisher. If you can make it two servers. I have done this supermarket project, with more than 500 people, two-layer application, very fast, website supplier query sales and inventory, one month data, 56K MODEM can see the first thirty in two seconds Result. And launched the test I can support 150 concurrency in one second. Another point is the money of the provincial hardware. The server only uses a HP6000 as a headquarters application, and there is a data backup, of course, there is a good time every branch.

From: People who go to the Internet, Time: 2004-3-18 16:38:18, ID: 2509555 support two-layer structure ... Why don't you say ..... Cross-region use B / Structure offline version ... The effect is much better than the three-layer internet access ... The so-called business logic is a deceptive ....... The third floor must modify business logic and What is the difference between the two layers .. How to modify the law to be modified ... Don't quarrel this problem, give all the points to me ....... From: vcanddelphi, time : 2004-3-18 21:23:42, ID: 2510111 to mrzj and chnplzh: Don't forget, if you have passed the same program, it is better. If the customer segment is not the same program, some is the same, but all call things in the same data, your two layers of methods, don't you write a lot of repetition code, this is not anti-"high quality code programming "? And, the customer segment is to upgrade, isn't it more trouble? From: Shalong Bas, Time: 2004-3-19 11:27:53, ID: 2510975 Looked above the post, I can't believe that the mainstream opinion in the daemon is actually thinking in big, medium 2 layers in development are more advantageous! ! ! ! Perhaps everyone will read Li Wei's book. I feel that the 3rd floor puts a DataSet and Provider in the middle, and the front end uses a client dataset to be three floors. Such a pseudo three layers are probably the most used in the rich. Such three layers are really not as simple as two layers. But the real MT system is not like this. The client does not have any DataSet, without any SQL statement, the client does not know if the database exists. It just provides users with a communication with the business object via the GUI. Application Server identifies different clients, you can determine what to do and do not allow it to do (permissions only in server-side implementation is reliable, only relying on the client through the grayish or hidden menu to ensure the door is not entry The first brother is called. Various things can be made according to the requirements of the client (for example, open an account, client providing user name, phone, etc.), the application server can determine if the account can be opened, and the account will tell the client success, otherwise the notice failed, new open The user object can be cached in the object pool, and the next time you can call, this is much higher than the on the data.). Because all resources, objects are controlled by application server, which can be easily controlled for critical resources, while two layers are difficult to do. The advantages of MT in large applications are more, I really don't want to tell. . . To Shalbasist: In fact, you are too biased too much. For three layers, I think it is a better idea in small procedures, because it is fast, and avoided Didsets of two layers. Don't think that the three layers are coming to do a big project, the small items use three layers, want to develop fast, and have benefits to future extensions. Communication with some database controls, isn't it a good way? Is it possible to use (COM , DCOM, etc.) communication? This will only increase the workload of development in the applet.

From: Shalong Basist, Time: 2004-3-22 10:05:22, ID: 2514642 to vcanddelphi: You said "Logic Layer" should be DO, BO, PO design mode, they are complete Can exist inside the same process. This mode should be derived from SmallTalk's MVC (the category in UML is very close to MVC, which is considered to have 3 classes: entity objects, management objects, boundary objects). It should be said that do, bo, and a PO model is an implementation of MVC in a database class application, while the three-layer system is a implementation of DO, BO, and PO in distribution. As for whether it is not available (COM , DCOM else COBRA, J2EE, SOAP), etc. You can define your own RPC yourself. My classmate has realized my RPC on Socket on Socket in Datsman. But how the effectiveness does it will be considered. From: mrzj, Time: 2004-3-23 9:37:41, ID: 2516722 To Shalbas owner you talk about the middle layer has a threaded pool, buffer pool, more famous intermediate layer software is indeed It is good to provide these. But I think you got these intermediate software vendors, these intermediate software software is good, it is better to use the database directly, as long as your database is not serving a number of applications, you talk about these SQL2000 The database is available. In Win2000, add SQL2000, the two layers do will definitely be better than three layers, save time, effort, save money, efficiency! Most of your concept is used in UNIX or Java, because these products do not have a very good connection to the database (there is no way to connect to the ADO to connect to the database), they want to rely on the intermediate layer long-term database (middle) Layer is initiated by a database connection), this is the main, buffer pool, the concept of this is secondary. It is because there is a reason why there is poor connection database performance! From: CHENGLH, Time: 2004-3-23 14:39:41, ID: 2517446 I also think that Midas is very troublesome. Many people don't write two layers of procedures, start to take a multi-storey. Personally think now is a better two-layer structure (for Delph5 SQL Server2000): 1, write business operations into stored procedures. 2, the client separates the service code with the interface code. Written in different cells or in different classes. 3, use TclientDataSet DataSetProvider. Using its offline buffer mechanism, nested table function (in fact, much ADO.net is all plagiarging TclientDataSet). 4. If most MIS systems are performed, it can be simplified in this structure: i) All physical classes are TclientDataSet, not inherited, such as order class Type Torder = TclientDataSet. TclientDataSet has sufficient ability to perform Torder's attribute read and write, add delete modification, no need to define new classes (this behind it has a TclientDataSet DataSetProvider ADO system support). II) Transaction Treatment requires customization, such as warehouse management classes, cooperation between this class processing entity, entity process. Most stored procedures are called by transaction processing classes. For example, review the entry list. III) Dictionary class and auxiliary class. For example, common data lookups, there are commonly used log management, user management, etc.

(Pure private experience) However, these and upcoming .NET platform programming may be behind. From: Shalbasist, Time: 2004-3-23 14:24:19, ID: 2517494 to MRZJ: Migrate DBMS does provide buffer pools, reduce disk access, thereby improving performance. But what you have to pay attention to is the buffer pool provided by DBMS and which level is provided in what particle size. Is DBMS to provide record or object? As for the low-end database connection mechanism in the non-MS platform, I only smiled, this is nothing to do. I never thought that the multi-layer is out, two dead lights. There is low threshold, there is a vital force. From: chenglh, time: 2004-3-23 16:29:14, ID: 2517595 With Layer 2 mode, when there is 1000 clients connected to the server at the same time, there are 1,000 concurrent threads in the database server! ------------------------------------ Use multiple layers, 1000 concurrent threads will not disappear. Where will it appear? Intermediate server. This intermediate server will also cralyken (or if you return a server for the client. Who is busy? I, the intermediate server, not a database server, busy. Or busy no time to return information.). Multiple intermediate servers can be configured. of course can. But SQL Server can also use server cluster technology, highly scalable, do not understand SQL Server, if SQL Server can queue the queue, or return a server busy, the intermediate layer is really unneed. Think carefully, 2-storey multi-layer central theme is still scalable and security. From: yu_ting, time: 2004-3-24 11:03:55, ID: 2518913 But the big trend is obvious, but I have doubtful to the C / S structure. I have done a agricultural tax collection software last year, using the C / S structure, connect with the DCOM plus SocketConnection, and the server uses the Interbase database. Cancer is very obvious. It is the three layers of the above "Li Wei" mode. From: Youngyxy, Time: 2004-3-24 11:43:36, ID: 2519072 Our topics should be clear, 'delphi programming, SQL2000 as the background DBMS situation, program structure problem, what is more than 2 Layer of layers'. First, the interface logic is mixed with business logic in a traditional 2-story, not convenient for system maintenance and evolution. Therefore, the interface logic is clearly separated from the business logic, as for the data access section, two processing, one is like Java practice, makes a data access layer, the business layer only only access the data layer, rather than directly accessing DBMS. Another practice is to omit the data access layer, and the business layer directly accesses DBMS. There are two kinds of practices above each other. Personally feel that the business layer directly accesses DBMS seems to be better in Delphi. Note that there is no so-called MIDAS here.

From: Sun River, Time: 2004-3-24 11:46:31, ID: 2519083 I'm in SME The layer, and partial calculations are carried out in the client, the reason is this: 1, more powerful scalability. C / S and B / S mixed, the program is reduced. 2. Practice shows that a large number of data processing is in that machine, and others are queries or a small number of updates. 3, the current customer capacity is very strong and fully used the client's ability. 4, the final purpose of the distribution: use all resources, a server handles a lot of things will be slow, we have few large servers, calculated by multiple clients, which may also be a better way. Strictly speaking, which is based on the project, but I thought: To be stabilized, the project will be put into projects, reasonable use of resources, less hardware investment, play a greater role. From: VcandDelphi, time: 2004-3-25 8:25:23, ID: 2520530 to mrzj: I have forgotten what to say, is "money" problem. Now a lot of database software (such as SQL Server) is a lot of contacts, and how many hundred pieces of each additional contacts are added. If it is a 5-point SQL Server and 25 contact SQL Server seem to be more than 10,000 pieces (the specific RMB is not clear, to be based on the agent), so if you make it, a two floors The database service software, as you said, the database can complete the processing of data, but this is more than buying more than a very general (P4 application server), you have to come out more money. If you use an application server to manage, then you don't have to spend so much money to the database's manufacturer. Further, if the customer segment, more than 25 contacts, you still use two floors, then you can only use the SQL Server to register the CPU version, about 200,000, as if this fee is too much, Let it be. ------ Maybe your current customer segment doesn't have so much, but one day, really so much, is there a set of SQL Server? Isn't there any money? God, this way, but a big project. (Note: Don't use D version in a big project, so my friend has encountered, I haven't debugged, the database server is gone! Oh] From: VcandDelphi, Time: 2004 -3-24 22:56:38, ID: 2520575 To Shanda Basist: Your point of view I agree, I see that I am placing and you still have a certain distance, I hope you can speak Say more, don't point it, I have to think about a long time can I agree. /// Tell you said before: /// "Maybe everyone looked at Li Wei's book, I think the 3rd floor put a Dataset and Provider in the middle, the front end with a client dataset is three floors. This pseudo-three floors are probably the most used in the daeino. Such three layers are really not as simple as two layers. But the real MT system is not like this. The client does not have any Dataset, no SQL The statement, the client does not know if the database exists.

It just provides users with a communication with the business object via the GUI. "/// You have a certain reason, I look at the way to get the introduction of the three-layer data structure, but when realizing fast, developing three floors, this pseudo The three-story development method also has his advantages, such as: good design, fast, and it is to solve the "money" of "money" mentioned above. The shortcomings are of course, the biggest shortcoming should be: transplantability And repeatability, bar. --- Personal view, please advise. Your second point of view I feel, justice his advantages and disadvantages are the opposite of the first one. I have developed a client now The program of the database component is just a small program that the client and the server are on a computer. If you don't need to communicate, you can connect it. But in my opinion, I still don't meet the theory you put forward. It seems that there is still a gap. If I put the Client / AppServer / DBServer on three computers, I have no good understanding of communication with them, please advise. From: Sharon Bath's owner, Time: 2004-3-25 11:59:49, ID: 2521346 to vcanddelphi: About your second question, I assume that your application needs: Some user locations are more concentrated, need to perform complex operations , Known as Class A users; some users are dispersed, relatively simple, called Class B users. You provide custom client programs for Class A users (general Delphi program); provide browsers for Class B users Program. Suppose you design according to the three layers, then you usually need a database, an application server program (such as COM ), a web server .a user access application server; Class B user access to the web server. Application Server Program Access Database The problem is: Web server access database? Or access the application server? Both methods, but the web server access the application server is a better way (of course, such a system is more complex) .Web server A client of the application server, from the perspective of the application server, it doesn't have any difference with the client's client. This way, the business logic exists only in the application server, the web server only needs to focus on the form of expression. From : Vcanddelphi, Time: 2004-3-26 21:17:52, ID: 2524436 To Shanda Basist Hello Hello 理 理 理 错 我 我 错,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, I was solved. I asked. If you don't put any database controls on the client, he is communicating with the server. As you said, if the application server uses COM , the client (you said A The kind of class) how to establish a pass with it Letter? 1. If the client uses DCOM or and his equivalent control, you can create a communication with the application server, but how should the extraction data be set? 2. If you don't have to use DCOM and its same level control, what should communicate be implemented? Thank you! ! ! ! I don't know, do you have a QQ number, I want to learn more with you.

From: Hygsxy, Time: 2004-3-28 0:47:38, ID: 2526074 Two layers is still three-story discussion so much, still there is still a name. I feel 2 layers, or 3 layers, then you have to see your application's goals. Different demand, two layers and three layers of course are of course different. Take a bit. You have to develop POS, ERP, MIS system for small and medium-sized companies that have the number of clients, distributed concentrated, naturally preferred two flies of C / S structure, but if they are some big companies, their clients are more, Distributed, and commercial logic is complicated, out of easy maintenance, easy to expand, easy to distribute, you must choose three layers. Even if some time the three-layer C / S structure is slow, but weigh the pros and cons of distribution, maintenance, expansion, money, etc., I sometimes choose three floors. The two-story database program is more, technology is relatively mature, but our Chinese, especially some software companies, and customers, there are new technologies, what technology is popular, what technology is And whether her advantages and disadvantages, in fact, the two layers can solve the problem, but in order to meet their comes: MRZJ, Time: 2004-3-29 9:42:04, ID: 2527275 The larger amount, the number of users The more, the faster the second floor, think that the three layers will be fast! Careful use of COM or DCOM, the key to instability is here, the number of users will often crash often when the amount of data is large! COM and DCOM Microsoft have been eliminated, changed to .NET, it's too much shortcomings, you still think it is good? If you talk about this in the middle of the 1990s, after so many years of practice, COM and DCOM's way is too unstable, careful use! Small applications are OK, large-scale absolute don't engage in COM, unless your intermediate layer server can restart every day! The larger the data, the more users, the faster the second floor! To MRZJ: If we do a test: Compare the software developed by two-story technology and the software developed using the three-story technology from the database from the database. Number of data. speed. So what is the result of this comparison? It is fixed to use software developed with two technology. This conclusion is that it is theoretically, it is true (increasing intermediate links will inevitably have a negative impact). However, inference according to this, the software that uses two-story technology developed more than software developed by three-layer technology is lacking in the actual application. Because in the second floor, to access the data to access the database; in the third floor, the design reasonable application server can provide buffer pools to significantly reduce access to the database. At this time, the second floor was offset because of the advantages of accessing the database speed of the structure of the structure. In this way, the ultimate performance is related to a series of factors such as the characteristics and scale of the application. However, as a general conclusion, with the size of the scale, the three layers have advantages in performance. The discussion with MRZJ brothers is limited to performance (speed), in fact, this is only a series of flexibility, scalability, robust, and economical, etc. When these factors take into account, as the application scale increases, the advantages of the three-layer system will be greater. Regarding the problem of crashing frequently in the intermediate layer, the symptoms are unreasonable in programming.

Mrzj brother's favorite example: SQL_Server2000 database itself (this is a more classic thing in MS products, MS has opened the source code to some countries in order to be anti-monopoly pressure, and my teacher is in Tsinghua 2002 Database representatives visited the MS Database Office, so I also understand the details of some SQL2000). The entire SQL2000 development team has 500 people, and they divide the team in accordance with the development content, for example, a group is responsible for the development of the grammar analyzer, and another group is responsible for the querier. What is the combination of grammar analyzer and querier? How is the interface between them defined? The boundary of each component is divided by the system architect of SQL2000, and the interface definition is in accordance with COM's format. That is, the SQL2000 itself is a whole consisting of a plurality of COM components. I don't know if the mrzj brother feels that it is unstable and often crashes. In fact, MS's things are almost all provided in accordance with the COM specification, such as Office Series (so we can create their automation objects in Delphi), IE (what browser in QQ is added outside IE), etc. and many more. People who have learned VC know that MFC is something, it is a commercial product launched by MS, but according to what I learned, the inside of MS does not need MFC at all (MFC is a spare structure for the outside), they The program is written in C according to COM specification (some MS source code is now spread, everyone can see if it is!). That's right, now the MS main push .Net, what is the relationship between .NET and COM (COM , etc.)? Where is the fundamental change? That is, "self-description"! ! ! This is the most revolutionary progress of the .NET. (But there are many java late, Java has achieved self-description early morning, this is the biggest progress of Java on C . Self-description is considered to be the biggest achievement in software industrialization in the past 10 years, it is an important part of component technology A ring, compared to OO technology is not important) therefore, it can be seen that .NET is not overthrowing COM, but a more step by step, the applicable to COM is still suitable for .NET. From: mrzj, Time: 2004-3-29 17:50:01, ID: 2528452 To Shanda Baste people you mentioned COM development, Microsoft is indeed very stable, I refer to development tools The intermediate layer product developed by Delphi developed COM components to operate the database is unstable. You mention the intermediate layer pool, buffer pool, etc. I think the data of the thread pool and buffer pool is better than the intermediate layer! What you mentioned "Design reasonable application server can provide buffer pool" This intermediate layer product developed by MTS provided by Delphi is not available at all! The intermediate layer of WebLogic, Webshare has these functions, but uses these intermediate layers, people who develop clients with Delphi are less and less. Multi-layer techniques are not suitable for use on Microsoft platforms. Multi-level is used for UNIX platforms! The three floors are used in Microsoft platforms, just like the second floor in the UNIX platform! From: Shanda Bas, Time: 2004-3-29 22:29:16, ID: 2528839 to MRZJ: "" I refer to the intermediate layer product developed by developing tool Delphi developed COM components The database is unstable.

"For this sentence, there are two understandings: 1. Borland's product Delphi is not good for COM. It is a software product that cannot be developed. 2. Developers can't develop Delphi to develop based The technology of the software of the database. I want two other statements, Borland will not agree to the first; the vast number of Delphi developers will not agree to the second. "" I think the data of the thread pool and buffer pool than the intermediate layer "" DBMS provides buffer technical support, and now the manufacturers' products are doing very well. But this support is provided at the database level, which is fine-grained (in this case, most of the DBMS is a relational, so the buffer it provides is also a relational tuple - record this level; Oracle8i although supports the object-type database, it is not considered due to the immature of the object-type database. In the object-oriented software, we operate objects. To this end, each middleware vendor provides various containers in its products to provide object buffer support. From the above discussion, Mrzj brothers should be able to understand that even if there is a buffering support of DBMS, if the buffer technology is continued in the intermediate layer, it is still possible to make a huge increase in system performance. From the real effect, this performance is highly effective than the negative impact of the increase in intermediate links (of course, this is related to the size of the scale and the application). "" "Design reasonable application server can provide buffer pool" This intermediate layer product issued by MTS provided by Delphi is not available at all! "" This is strange, how is the software in my own? What is the buffer pool? If you are interested, you can see: http://www.delphibbs.com/delphibbs/dispq.asp?lid=2463683 "" Multi-layer technology, not suitable for use on Microsoft platform "" "I didn't know if you have this conclusion What is the basis? If it is true, MS's .NET project should be aborted immediately, no need to do it again; COM should also be removed from NT5.x. Or just examples of SQL2000, Mrzj brothers should know that SQL2000 can be distributed to distributed database clusters by publishing / subscribe mode, then, do you know what technology is used by its release / subscription? That is COM ! ! ! ! From: Shalong Basist, Time: 2004-3-30 14:28:03, ID: 2529767 to zhousi: 1, DataModel or removete Datamodel is irrelevant, all DATAMODEL is just a container (Help It is very clear that it is very clear). 2, my design is only one DATAMODEL. 3, there is a CONNECTION pool and a query pool in DataModel. About these two pools can be seen in the following posts.

(The cleaning algorithm of the pool is relatively simple, I hope that the peers will be given to improve the recommendations) ************************ CONNECTION pool ******* ********************************* * Unit UDataConnpool; Interface Uses Sysutils, Classes, DB, AdoDB, Contntrs, Windows , ExtCtrls, UBase; type TDataConnectionPool = class (TComponent) // database connection pool private fConnParameter: RConnParameter; fConnList: TComponentList; fCleanTimer: TTimer; procedure fCleanOnTime (sender: TObject); function fMakeConnStr: String; function fCreateADOConn: TADOConnection; / / Create a new idle connection procedure fclean; // Clean up (dead) connection (dead) connection (dead) connection (dead) connection) {private declarations}}}} {public declarations} {public}} {public declarations} protecty conncount: integer} getConnCount; constructor Create (owner: TComponent; connParam: RConnParameter); overload; function getConn: TADOConnection; // get free connection procedure returnConn (conn: TADOConnection); // return the connection end; implementation constructor TDataConnectionPool.Create (owner: TComponent; Connparam: rconnparameter); VAR INDEX: Integer; Begin Inherit ed Create (owner); fConnParameter.ConnMin: = connParam.ConnMin; fConnParameter.ConnMax: = connParam.ConnMax; fConnParameter.RefreshTime: = connParam.RefreshTime; fConnParameter.dbUser: = connParam.dbUser; fConnParameter.dbPass: = connParam.dbPass fconnparameter.dbsource: = connParam.dbsource; if fconnlist = nil the beginning, creative database connection list try for index: = 1 to fconnparameter.Connmin do // Creative minimum connection Database Connect Begin Fconnlist.Add (FcreateAdoconn); End; Except end; end; if fcleantimer = nil dam fcleantimer: = TTIMER.CREATE (Self); fcleantimer.name: = 'mycleantimer1'; fcleantimer 1.Interval: =

fConnParameter.RefreshTime * 1000; // cleanup program start time interval fCleanTimer.OnTimer: = fCleanOnTime; fCleanTimer.Enabled: = True; end; end; procedure TDataConnectionPool.fClean; var iNow: Integer; iCount: Integer; index: Integer; begin iNow: = GetTickCount; iCount: = fConnList.Count; for index:. = iCount - 1 downto 0 do begin if TADOConnection (fConnList [index]) Tag> 0 then begin if fConnList.Count> fConnParameter.ConnMin then begin if iNow - tadoconnection (fconnlist [index]). Tag> 600000 THEN / / More than 10 minutes are not used, the idle connection greater than the connecting pool minimum number of idle connections will be released (index); end; end; Else if tadoconnection FConnlist [index]). Tag <0 The begin if INOW TADOCONNECTION (FConnlist [index]). Tag> 3600000 THEN / / Continuous use for more than 1 hour connection (very likely to be dead connection will be released) (INDEX); if fconnlist.count

0 TO FCONNLIST.COUNT - 1 Do Begin if Tadoconnection (fconnlist [index]). Tag> 0 THEN Begin Result: = tadoconnection (fconnlist [index]); result.tag: = - gettickcount; // Use Start Timing (Negative Number Representation Using) End; End; if (Result = nil) and (index

TComponentList.Create (False); for index: = 1 to fAdoQueryMin do begin fAdoQueryList.Add (fCreateADOQuery); end; if fCleanTimer = nil then begin fCleanTimer: = TTimer.Create (Self); fCleanTimer.Name: = 'MyCleanTimer1'; Fcleantimer.interval: = 600 * 1000; // Cleanup program started time interval (10 minutes) fcleantimer.ontimer: = fcleanontime; fcleantimer.enabled: = true; end; end; procedure tadoquerypool.fclean; var inow: integer; / / Current time ICOUNT: ICOUNT: INTEGER; // List size index: integer; begin iNOw: = gettickcount; iCount: = fadoquerylist.count; for index: = iCount - 1 Downto 0 do begin if tadouery (FadoQueryList [index]). Tag> 0 THEN / FADOQUERYMIN THEN// If the number of adoQuery is larger than the minimum becom tadoquery (fadoquerylist [index]). Free; end; end else if tadoQuery (fadoquerylist [index]). Tag <0 THEN BEGIN if INOW TADOQUERY (FadoQueryList [Index]). Tag> 10800000 THEN / / Continuous Use more than 3 hours of AdoQuery (very likely to die), release Begin TadoQuery (FadoQueryList [index]). free; if fadoquerylist. Count 0 THEN Begin Result: = TadoQuery (FadoQueryList [index]); result.tag: = - gettickcount; // Use Start Timing (Negative Number Representation) End; End ; if (Result =

NIL) and (index -1 then begin qry.Tag: = GetTickCount; // Start free timing End; end; end. From: VcandDelphi, Time: 2004-3-31 23:38:31, ID: 2532544 To Shanda Basist: For COM, I don't call the comment. However, the ADO written database programs under Delphi have some problems. After the ADO control encapsulates the ADO, some functions are older. I don't know if the Delphi package is not good, or the MS did not release the ADO true core function? For the DELETE function of TadoQuery control, it is not possible to use the SQL statement in D5 to implement the delete function. This issue is in D6, D7. Yes, there is also a childish problem, COM is built on OLE? I know that ADO is built on OLE. If "COM is built on OLE", then what is the relationship? From: Proman, Time: 2004-4-1 22:24:09, ID: 2534602 TO: Sharon Bas's owner In multi-threaded case, how do you guarantee that when you read TAG, other threads have not been revised. What? The result is very likely to have a connection at the same time. Your read action is not in synchronous protection, I look at it always problem, maybe it is difficult to find it, but It is indeed a problem. From: Shalbasist, Time: 2004-4-2 0:29:36, ID: 2534699 to Proman: You said that it is probably a hidden danger. Delphi does not provide synchronous settings for methods, I don't know if there is any way to make a method can not be re-entered (if you set mutex at the beginning of the method, there are still multi-threads to access this mutex at the same time), please also Proman brother gave a high trick. From: Proman, Time: 2004-4-2 8:13:02, ID: 2534775 You can do it with TCRITicalSECTION. Below is the code of my connection pool, I am more simple, I have not yet been released.

constructor TConnectionPools.Create; begin FConnList: = TList.Create; FCriticalSection: = TCriticalSection.Create; FTimeout: = 5000; FMaxCount: = 15; FSemaphore: = CreateSemaphore (nil, FMaxCount, FMaxCount, nil); end; function TConnectionPools.CreateNewInstance : TADOConnection; var p: PRemoteConnection; begin Result: = nil; FCriticalSection.Enter; try New (p); p.Connection: = TADOConnection.Create (nil); p.Connection.ConnectionString: = ConnectionString; p.Connection.LoginPrompt : = False; try p.connection.open (Databaseuser, DatabasePass); Except P.connection.Free; Dispose (p); exit; end; p.inuse: = true; fconnlist.add (p); result: = P .Connection; finally FCriticalSection.Leave; end; end; destructor TConnectionPools.Destroy; var i: Integer; begin FCriticalSection.Free; for i: = 0 to FConnList.Count - 1 do begin PRemoteConnection (FConnList [i]) Connection.. Free; Dispose (FConnlist [I]); end; fconnlist.free; closehandle; inherited destroy; end; function tconnectionpools.getlock (India) ex: Integer): Boolean; begin FCriticalSection.Enter; try Result:. = not PRemoteConnection (FConnList [Index]) InUse; if Result then PRemoteConnection (FConnList [Index]) InUse:. = True; finally FCriticalSection.Leave; end; end; function TConnectionPools.LockConnection: TADOConnection; var i: Integer; begin Result: = nil; if WaitForSingleObject (FSemaphore, Timeout) = WAIT_FAILED then raise Exception.Create ( 'server is busy, please try again later'); for i: = 0 to FConnList.Count - 1 do begin if GetLock (i) then begin Result:. = PRemoteConnection (FConnList [i]) Connection; Exit; end; end; if FConnList.Count

nil then {This should not happen because of the sempahore locks} raise Exception.Create ( 'Unable to lock Connection'); end; procedure TConnectionPools.ReleaseLock (Index: Integer; var Value: TADOConnection); begin FCriticalSection.Enter; try PRemoteConnection (FConnList [Index]) InUse: = False; // Value:. = nil; ReleaseSemaphore (FSemaphore, 1, nil); finally FCriticalSection.Leave; end; end; procedure TConnectionPools.SetConnectionString (const Value: string); begin FConnectionString: = Value; end; procedure TConnectionPools.SetDataBasePass (const Value: string); begin FDataBasePass: = Value; end; procedure TConnectionPools.SetDataBaseUser (const Value: string); begin FDataBaseUser: = Value; end; procedure TConnectionPools.UnlockConnection ( Var value: tadoconnection; var i: integer; begin for i: = 0 to fconnlist.count - 1 do begin if value = premoteconnection (fconnlist [i]). Connection Then Begin ReleaseLock (i, value); Break; end; End; End; Initialization ConnectionPools: = tConnectionPool S.Create; Finalization ConnectionPools.Free; End. From: Dirk, Time: 2004-4-2: 2535173 Oh, I like to use API to do critical regions: cs: trrtlcritics; initializecriticalsection (cs) ENTERCRITICALSECTION (CS); LeaveCriticalSECTION (CS); DeletecriticalSection (CS); actually TCRITICALSECTION also encapsulates these functions. Also I want to ask upstairs, why should I use WaitforsingleObject? It seems to be a critical state, how is WaitForsingleObject how I still don't quite understand, I hope to advise. From: Shandelbasist, Time: 2004-4-3 10:45:29, ID: 2537506 to vcanddelphi: Originally using ADO encountered something BOF, EOF error, but D6 did not encounter. Copy the article to you. ADO: Active Data Objects: ADO is actually a connection mechanism that provides access to various data types. ADO is designed as a very simple format, with the database interface with the ODBC method.

Any ODBC data source can be used, ie, is not only suitable for database applications such as SQL Server, Oracle, Access, and is also suitable for Excel forms, text files, graphics files, and formatted data files. ADO is a technique based on OLE-DB, so ADO provides a unified data access interface method through its internal properties and methods. From: Shatongbasist, Time: 2004-4-15 8:21:53, ID: 2559846 The technology is developed by Cache technology, which is a very extensive way to improve performance (one level in your CPU) Secondary Cache, Cache ... on the hard disk is a typical spatial change time strategy. From: LiuxiangSoft, Time: 2004-4-15 9:58:27, ID: 2560136 Param: I am Sorry !!!!!!!!!!!!!!! Really sorry, I made a day in the day The head is big, and finally I found the stuff in Demo, I am so long! But I don't understand again: After I use the pool, the things and properties defined in Type Library cannot be compiled, and this object is not defined in the pool (Pool). I would like to ask: Is it attribute or matter defined in Type libaray? If so, how do you declare? From: ZHANGGEYE, Time: 2004-4-23 10:25:55, ID: 2576167 What is a fake three-layer? The so-called real MT only uses the interface, why do you know what is the essence of DataSetProvider data processing? It is still an interface! Data is only available in the DataSet mode that the client is accustomed to. This kind of technique that is hosted is obvious. Do you have your own interface packaging and transfer data and what it is? At this level, can the CLIENTDATASET and the second floor can compare parallelism? Everyone seems to use ClientDataSet deep and evil to the three-story client, but I think that criticizing a technology, at least based on understanding, not a cloud cloud. Just as you see the wolf seen in the zoo, please don't review it with the dog's standard, because you have never seen a real wolf in the wilderness. From: ZHANGGEYE, Time: 2004-4-26 12:08:51, ID: 2581036 To Shanduvider and ClientDataSet is developing to surround the database? I suggest you look at Li Wei's ADO / MTS / COM Advanced Program Design. In the business object, DataSetProvider provides a data operation interface that fully meets the design of the three-layer system. DataSetProvider is just a part of the data interface in the business object, and a complete business object also includes other interfaces and business logic. It is completely unreasonable to oppose them. ClientDataSet only acquires and submits data to the interface of the business object, and the client is encapsulated in the client mode, so that the client can still use the number of sensitive controls to develop, which can be directly developed directly for a large number of existing resources. The application, and the original two layers of advantages are also maintained. This is the advantage of delphi efficient development three layers. (Of course, you can only use the Delphi to develop clients with this advantage.) Said that Li Wei's three floors is a three-layer, because the data processing of the CLIENTDATASET is the interface, which is the business object of the intermediate layer, not the original Dataset which is scheduled to operate the database.

From: Proman, Time: 2004-4-26 19:41:45, ID: 2582202 to: zhanggeye, so-called multi-storey, according to numerous statements, it is nothing more than the performance layer, business layer. Data drive layers, databases, etc., which can also be added to N-layer according to the actual situation of the system. In the ideal case, we hope the multi-layer structure of the multi-layer structure, that is, the client, whether this client is in a smart client or in IE, we want it to deal with the business layer or other layer behind it. It cannot involve the structure in the database. Once the structure of the database is involved, the ideal multi-layer will weaken. If ClientDataSet is transmitted by a table in the database, or a query, there is no doubt that such a multi-layer is to discount. However, in the actual system, we have problems, we have enough people to develop a true multi-layered system, and each layer is used to join. Actually, many systems don't have enough people to make such a development, so that the table in which the replacement is directly transmitted in the database, it is not surprising. Although this is different from the thinking of multiple layers. But in the case of sufficient resources, I still recommend that you use the interface to divide each layer, this does develop a solid foundation for the direction of development, but also lay a solid foundation for the program. Li Wei's book is not a problem. He proposed a method using less resources to quickly develop a three-layer structure, which is indeed a three-layer. But maybe he is not a pure three-story concept. However, his development cost is very small, I think Li Wei uses such a simple way to introduce everyone into multi-level concept. But if you stay here just here, it is obviously only what you know, but I don't know why. I also look at Li Wei's book to learn three layers. But in my three-story system, I have not used DataProvider at all, of course, because of the limited resources, I also use the ClientDataSet to pass some data. So everyone don't waste too much time on the top of the provider, and you don't need Provider to still pass data. I recommend not use Provider, Provider is purely packaged data. Without provider, you can more focus on packaging business features, which may be better. I have seen everyone for a long time. I think the debate is a bit meaningless. The truly mastering of multi-storey systems is the most important. At this point, I think we can learn from each other. From: ZHANGGEYE, Time: 2004-4-26 20:59:32, ID: 2582313 to Proman: I agree with you, and I think that since it is a delphi programmer, it is necessary to make full use of Delphi's advantage. One of the simplest situations, a sales bill object provides a single package to the client, and its efficiency of the array package is far better than using DataSet. Midas is a high-level development mechanism in the third floor. It does not have to write three layers, but it can be easily written. DataSetProvider is not just a pure package data, you can pack your business rules on it. The concept of pure three layers is sometimes only an ideal state, the demand changes and changes in business rules often lead to changes in the database structure. These changes are finally reflected by the interface to the room, and will not use their own interface customers Needless to change. This change is more direct to the client with DataSetProvider / ClientDataSet. Take a step by step, you can use your own interface to encapsulate data with the CLIENTDATASET mode to facilitate the development of the client.

The three-story development model is flexible, more is to start from demand, the theory of things don't die hard, just as you said: "The real master of multi-layer systems is the most important." I also think that this argument doesn't make sense, it has not been involved, but it is difficult to recognize the later comments, just say a few words. You can talk to a smile. From: Proman, Time: 2004-4-26 21:52:55, ID: 2582404 Supplementary That is, how to encapsulate a data set through network, and its packaged data structure is not disclosed, which is also the core technology of MIDAS. Whether the Midas charge is determined based on whether the data is transmitted on the network. To infowain: The code I published is just two basic classes of code, in fact, there is an operator class (TOPERPOOL); user (tuser); price (tprice) and price pool ( TPRicePool, etc. Because it is related to the specific business, it is not very convenient. I am in the development of Delphi, it is resolutely unwindly, but I still use the clientDataSet, which is to report the report, very helpless - I really don't want to design a recordset; then, the report itself is in the nature of the report itself The general business object is also very different.

From: yangying_2000, Time: 2004-4-26 23:21:03, ID: 2582497 I didn't expect to have noisy this, first said my position, I support three layers, and some people want to say 1. Some people It is considered that the two layers are higher than the three-layer efficiency. This is not the same. It is indeed a middle layer. It seems to have a lot of things for the client. In fact, the Client is put on the application server, In general, the application server performance should be good, and therefore, for a single query response time should be similar. In fact, the efficiency is mainly at the processing mode of the server, suppose 100 clients simultaneously online, for C / S, database will open 100 sessions, for multiple layers, the database will only open the dialogue requested by the application server, generally not more than 10, and 100 clients hand over their request to the application server, the application server queues After processing in your 10 sessions, then returned to the client, that is, in C / S, when the client does not request any request, these sessions are stopped there, they must wait for the client. Sending a request for the database will be utilized, and the actual situation is that most of the client data request is not frequent, so it has caused waste, so it is better to see three layers from this perspective. 2. Some people think the so-called pseudo-three floors Not good, I just feel very good, because it is used to replace the two-story structure, with the current Delphi, if you do two-layer structure, it is really better to use pseudo-three layers, very simple, development process There is almost no difference, but the maintenance of the pseudo-three-layer Client is much smaller. Two layers need to load the database client, you need to define the database client, if you use BDE, you have to install BDE. If you use ODBC, you will also define ODBC alias. Once there is a problem, the entire client cannot be used, and the pseudo-three floors will have execution files and midas.dll, if you use ASTA to do a pseudo-three floors, even the dynamic library Midas.dll is saved, It can be used to copy the pass. Therefore, the pseudo-three floors can be said to replace the two-layer structure of the weapon. By the three-layer structure, the two layers can almost no advantage. From: zhanggeye, Time: 2004-4-27 0 : 37: 23, ID: 2582573 Li Wei's book is good, I don't want to comment, but only if you use DatasetProvider / ClientDataSet to break the three-layer leaflet of Li Wei is unacceptable. DataSetProvider / ClientDataSet is a unique advantage of delphi. If you do not take advantage of it, it is basically no different from Delphi to develop three-layer and other languages. CLIENTDATASET uses the background database transparentization. It is actually a misunderstanding. ClientDataSet is only obtained from an interface. The source inside the interface is not known. It may be a table or a view, more reasonable is to encapsulate business. One result data set after logic. Because everyone often develops clients and intermediate layers, it is reasonable to know which DataSetProvider comes from what business logic. If the intermediate layer is not you developed, just tell you what functions and data on the interface, which use the ClientDataSet format package, which you can also know what type of the background database, what is the table name, it is directly from the database It is still synthesized by the intermediate layer. These are impossible to know. The client can implement the interface logic as long as the client is handled. Different, you can use a tensitive control to visualize using a cylinder. How many development tools can be done? Or which sentence said: "The real master of multi-layer system is the most important." Theory is dead, can't move unrealistic. For example, in the granular control of the business object, the so-called "true three layers" is required to be detained, divided into clear. If it is a multi-user application. This is very advantageous. But for small and medium-sized applications, these advantages are far from expenses such as development and maintenance costs. A fat intermediate layer may be a better choice.

转载请注明原文地址:https://www.9cbs.com/read-10216.html

New Post(0)