I divided the model into several parts, A, B, C, D, E, F. what do these parts represent? First, A. This Base represents the Base class of the entire framework. all model files must inherit from this Base class. because the content of B depends on D, let's first talk about D, D first, there is... "> <LINKhref =" http://www.php100.com//statics/sty
I divided the model into several parts, A, B, C, D, E, F. what do these parts represent?
First, A. This Base represents the Base class of the entire framework. all model files must inherit from this Base class;
Because the content of B depends on D, let's first talk about D. D has a ConnectionManager, which is responsible for managing database connections and disabling and database driver selection. this name is not very good, let's do it first. since it is responsible for database connection and shutdown, it certainly has the following methods:
| 2 |
Public class ConnectionManager { |
| 3 |
Public static function getConnection (){} |
| 4 |
Public static function releaseConnection (){} |
Since database connections are shared for all models, we set ConnnectionManager as a singleton.
D has PDO and MYSQL _ * on the right. what does this mean? in fact, it represents various drivers. maybe you are using advanced PDO, it is also possible that you are using the old MYSQL _ * type, or mysqli, ADO, and so on. it is precisely because of the chaos of the PHP database, we need to define a contract in the framework. all the driver classes are written and implemented according to this contract. in this way, no matter what the underlying implementation of the driver class is, the content displayed on the upper layer is consistent.
Now let's define this contract:
| 03 |
Function execute ($ SQL ); |
| 06 |
Function getAllByObject (); |
| 07 |
Function getAllByAssocArray (); |
| 08 |
Function getAllByArray (); |
| 09 |
Function beginTrans (); |
Connect is to connect to the database, execute is to execute an SQL statement. if this SQL statement is a query, getAllByObject indicates that the query result is returned through the object. getAllByAssocArray indicates that the query result is returned according to the associated array, getAllByArray indicates that the results are returned according to the normal array. beginTrans indicates that a transaction is started, that is, autoCommit is enabled, commit is committed, rollback is to roll back the transaction, and close is to close the Db.
In fact, you can encapsulate the returned results into an iterator.
Well, let's take a look at B. let's first look at ModelBase, which is actually provided for table models and relational models. it encapsulates various externally visible functions, such as query, insert, update, delete, execute, fetchAll, and so on. that is to say, all drive classes in B cannot be accessed directly from outside. who can access it? it is ModelBase, but it cannot be accessed directly, it is accessed through ConnectionManager.
Because ConnectionManager automatically selects a driver according to the configuration file, ModelBase does not know which driver class it calls. However, because the driver classes follow the contract, therefore, ModelBase does not need to care about the driver, so the above method of the contract can be called.
| 02 |
Class ModelBase extends Base { |
| 03 |
Protected $ _ db = null; |
| 04 |
Public function _ construct (){ |
| 05 |
$ This-> _ db = ConnectionManager: getConnection (); |
| 07 |
Public function execute ($ SQL ){ |
| 08 |
$ This-> _ db-> execute ($ SQL ); |
Just like the above code, when instantiating ModelBase, it will call getConnection of ConnectionManager to obtain the database connection. of course, since ConnectionManager is a singleton, therefore, even if 10 ModelBase classes are instantiated at the same time, only one database connection operation is performed.
With the above contract, it is very easy to execute an SQL statement at this layer. you only need to call the execute method of the driver class, that is, $ this-> _ db-> execute ($ SQL );
Speaking of ModelBase, let's talk about SQL Parse. its main function is to complete SQL parsing. When does it need SQL parsing to implement database ORM.
This layer is also called by ModelBase. suppose there is a query operation outside of the system. the method of calling this layer is $ this-> where ()-> order ()-> select (). of course, I didn't write any parameters for each function. this function chain is very friendly. SQL Parse will Parse the actual meanings of these functions and return them to ModelBase. ModelBase will get the parsed SQL, then execute $ this-> _ db-> execute ($ SQL), so no matter what the pattern is, the execute method of the driver class is finally called to execute an SQL statement.
The following C is actually easy to understand, that is, the table model and the link model. because some operations have been completed in ModelBase, you only need to inherit the ModelBase from the table model and the link model. The table model processes the content of a single table, so it has additional content. for example, when we execute a $ this-> select (), we do not specify the query content, the system should be able to identify what the table is to be queried, and the final parsed SQL statement may be: select * from XXX, and the relational model is the same.
After C and E are completed, it is easy to understand. The model layer actually calls the methods of the relational model or table model to implement specific services.
F is used to process content other than common databases, such as Cache. because this is just about the idea, this part of content will not be written for the moment. if there is time, I will talk about it later. if not, that's all.