簡體   English   中英

生成DAO類的最佳最快方法

[英]Best and Faster way for generate DAO class

我已經閱讀了很多有關如何使用PDO生成DAO類的頁面,但是我還沒有找到一種更好且更快的方法來獲取它。

假設我們有一個名為Animals的數據庫表,其結構如下

CREATE TABLE animals
(
    idAnimal int PRIMARY KEY NOT NULL AUTO_INCREMENT,
    name varchar(20),
    dateOfBirth DATETIME
);

一個好的發展方式是創建兩個類: AnimalsAnimalsDAO像這樣

class Animals{
    /**
     * @var integer
     */
    public $idAnimal;
    /**
     * @var string
     */
    public $name;
    /**
     * @var DateTime
     */
    public $dateOfBirth;

    /**
     * Animals constructor.
     * @param int $idAnimal
     * @param string $name
     * @param DateTime $dateOfBirth
     */
    public function __construct($idAnimal, $name, DateTime $dateOfBirth) {
        $this->idAnimal = $idAnimal;
        $this->name = $name;
        $this->dateOfBirth = $dateOfBirth;
    }

}

AnimalsDAO通常存在一種用於從數據庫中插入和檢索對象的方法。 在此類中,已經存在一個ORM問題(ORM對象關系映射),因為PDO的獲取方法不能與對象強制轉換一起正常工作。多年來,我一直以這種方式開發DAO

class ClienteDAO {
    /**
     * @param $idAnimal integer
     * @return Cliente
     * @throws Exception
     */
    public static function getClienteById($idAnimal ){

        $q="SELECT * FROM animals WHERE idAnimal =:idanim";
        $sth=PDOConnection::instance()->prepare($q);
        $sth->bindParam(':idanim', $idCliente,PDO::PARAM_INT);
        if($sth->execute()==0)
            throw new PDOException("ERROR EXECUTE");
        if($sth->rowCount()!=1)
            throw new PDOException("ERROR ROW NUMBERS");
        $row=$sth->fetch(PDO::FETCH_NUM);
        $row[2]=new DateTime($row[2]);
        return new Animals(...$row);
    }
}

因此,如果我更改添加或刪除數據庫字段,則只需編輯Animal類中的變量,重新生成構造函數(我使用PhpStorm),並在獲取后最終編輯行

是否存在生成DAO類的最佳且更快的方法? (另一種方法是檢索類屬性名稱並使用fetch Names方法,但dateTime列仍然存在轉換問題)

當通過關聯解決了對數據庫的繼承問題並且該繼承問題在php類中時,問題更加復雜

ER圖

數據庫結構被翻譯成數據庫結構

顯然,在php端有一個父超級類和兩個子類(擴展了更胖的類)

如何為孩子生成DAO方法的更快方法?

根據OP req,來自我的代碼庫的一個示例

設備

namespace DAO;

use common\Context;
use enums\DeviceOStypeEnum;
use NAO\Inbound\IBDeviceSpec;
use NAO\Outbound\OBDevice;
use protocols\IClassInit;
use protocols\ITokenizer;
use traits\ClassInitTrait;

class Device extends AbstractDataObject implements IClassInit , ITokenizer
{

    const APPLE_PERMANENT_DEVICE_GUID    = "f8d55ac7-6e6a-4a0c-a5ec-20df1f384d62";
    const GOOGLE_PERMANENT_DEVICE_GUID   = "788996ff-5da3-47f2-9601-3f9ae79b51aa";

    use ClassInitTrait;

    /** @var  int $id */
    protected $id;
    /** @var  string $deviceGuid */
    var $deviceGuid;
    /** @var  DeviceOStypeEnum $osType */
    var $osType;
    /** @var  Version $osVersion */
    var $osVersion;
    /** @var  string $manufacturer */
    var $manufacturer;
    /** @var  string $modelCode */
    var $modelCode;
    /** @var  \DateTime $createdOn */
    var $createdOn;
    /**@var \DateTime $lastSeen */
    var $lastSeen;
    /** @var  bool $active */
    var $active;
    /** @var $isPhone */
    var $isPhone;
    /** @var  App $app */
    var $app;

    public static function postInit($c , $isTraceEnabled , $isPDOuser)
    {
    }

    /**
     * Device constructor.
     *
     * @param int $id
     * @param string $deviceGuid
     * @param DeviceOStypeEnum $osType
     * @param Version $osVersion
     * @param string $manufacturer
     * @param string $modelCode
     * @param \DateTime $createdOn
     * @param \DateTime $lastSeen
     * @param App $app
     * @param bool $isPhone
     * @param bool $active
     */
    public function __construct($id , $deviceGuid ,
                                $osType , $osVersion , $manufacturer , $modelCode ,
                                \DateTime $createdOn , \DateTime $lastSeen ,
                                $active , $isPhone , $app)
    {
        $this->id           = $id;
        $this->deviceGuid   = $deviceGuid;
        $this->osType       = $osType;
        $this->osVersion    = $osVersion;
        $this->manufacturer = $manufacturer;
        $this->modelCode    = $modelCode;
        $this->createdOn    = $createdOn;
        $this->lastSeen     = $lastSeen;
        $this->active       = $active;
        $this->app          = $app;
        $this->isPhone      = $isPhone;
    }

    /**
     * @param array $row
     *
     * @return Device
     */
    public static function fromAssociativeArray($row)
    {
        $OStype     = new DeviceOStypeEnum($row['os_type']);
        $osVersion  = Version::fromString($row['os_version']);
        $createdOn  = dateTimeFromSQLquery($row['created_on']);
        $lastSeen   = dateTimeFromSQLquery($row['last_seen']);
        $active     = (bool) $row['active'];
        $deviceGuid = binaryGuidAsStringGuid($row['device_guid_bin']);
        $isPhone    = (bool) $row['is_phone'];
        $app        = AppDAO::applicationWithId($row['app_id']);
        return new Device(
            $row['id'] ,
            $deviceGuid ,
            $OStype ,
            $osVersion ,
            $row['manufacturer'] ,
            $row['model_code'] ,
            $createdOn ,
            $lastSeen ,
            $active ,
            $isPhone ,
            $app
        );

    }

// plus a whole bunch of business logic after

DeviceDAO(partiel)

namespace DAO;

use enums\DeviceOStypeEnum;
use NAO\Inbound\IBDeviceSpec;
use protocols\IClassInit;
use traits\ClassInitTrait;

class DeviceDAO implements IClassInit
{

    use ClassInitTrait;

    /**
     * @param string $guid
     * @param DeviceOStypeEnum $osType
     * @param Version $osVersion
     * @param string $manufacturer
     * @param string $modelCode
     * @param boolean $isPhone
     * @param App $app
     *
     * @return Device|null
     */
    public static function insert($guid ,
                                  DeviceOStypeEnum $osType , Version $osVersion ,
                                  $manufacturer , $modelCode ,
                                  $isPhone , App $app)
    {
        $pdo       = self::getClassPDO();
        $q         = $e = null;
        $createdOn = now();
        $lastSeen  = now();
        $sql       = <<<SQL
INSERT INTO Device SET device_guid_bin = :guid, 
os_type = :ost, 
os_version = :version ,
manufacturer=:manufacturer,model_code=:model,
created_on=:co, last_seen = :lastseen ,  active=1, `is_phone`=:phone, `app_id` = :appid

SQL;
        $device    = null;
        try {
            $q = $pdo->prepare($sql);
            $q->bindValue('guid' , stringGuidAsBinaryGuid($guid) , \PDO::PARAM_STR);
            $q->bindValue('ost' , $osType->stringValue , \PDO::PARAM_STR);
            $q->bindValue('version' , $osVersion->__toString() , \PDO::PARAM_STR);
            $q->bindValue('manufacturer' , $manufacturer , \PDO::PARAM_STR);
            $q->bindValue('model' , $modelCode , \PDO::PARAM_STR);
            $q->bindValue('co' , dateTimeAsSQLstring($createdOn) , \PDO::PARAM_STR);
            $q->bindValue('lastseen' , dateTimeAsSQLstring($lastSeen) , \PDO::PARAM_STR);
            $q->bindValue('phone' , $isPhone , \PDO::PARAM_BOOL);
            $q->bindValue('appid' , $app->getId() , \PDO::PARAM_INT);
            if ($q->execute()) {
                $id     = $pdo->lastInsertId();
                $device = new Device(
                    $id , $guid ,
                    $osType , $osVersion ,
                    $manufacturer , $modelCode ,
                    $createdOn , $lastSeen , true , $isPhone ,
                    $app
                );
            } else {
                self::logQueryFail("Unknown error while inserting a device" , $q , $e);
            }

        } catch (\Exception $e) {
            self::logQueryFail("Error while inserting a Device" , $q , $e);
        }
        return $device;

    }

    /**
     * @param IBDeviceSpec $spec
     *
     * @return Device|null
     */
    public static function insertWithDeviceSpec(IBDeviceSpec $spec)
    {
        $app = AppDAO::applicationWithGuid($spec->appGuid);
        return self::insert(
            $spec->deviceGuid , $spec->osType , $spec->osVersion , $spec->manufacturer , $spec->modelCode ,
            $spec->isPhone , $app
        );

    }

    /**
     * @param Device $device
     *
     * @return bool
     */
    public static function update(Device $device)
    {

        if (!$device) {
            self::getClassLogger()->error("Attemptempt to update null Device");
            return false;
        }
        $pdo = self::getClassPDO();
        $q   = $e = null;

        $sql = <<<SQL
UPDATE  Device 
SET device_guid_bin = :guid, 
os_type = :ost, 
os_version = :version ,
manufacturer=:manufacturer,
model_code=:model,
created_on=:co, 
last_seen = :lastseen,  
active=:ac,   
`is_phone`=:phone, 
`app_id`=:appid
WHERE 
id=:id

SQL;
        try {
            $q = $pdo->prepare($sql);
            $q->bindValue('id' , $device->getId() , \PDO::PARAM_STR);
            $q->bindValue('guid' , stringGuidAsBinaryGuid($device->deviceGuid) , \PDO::PARAM_STR);
            $q->bindValue('ost' , $device->osType->stringValue , \PDO::PARAM_STR);
            $q->bindValue('version' , $device->osVersion->__toString() , \PDO::PARAM_STR);
            $q->bindValue('manufacturer' , $device->manufacturer , \PDO::PARAM_STR);
            $q->bindValue('model' , $device->modelCode , \PDO::PARAM_STR);
            $q->bindValue('co' , dateTimeAsSQLstring($device->createdOn) , \PDO::PARAM_STR);
            $q->bindValue('lastseen' , dateTimeAsSQLstring($device->lastSeen) , \PDO::PARAM_STR);
            $q->bindValue('ac' , $device->active , \PDO::PARAM_BOOL);
            $q->bindValue('phone' , $device->isPhone , \PDO::PARAM_BOOL);
            $q->bindValue('appid' , $device->app->getId() , \PDO::PARAM_INT);
            if ($q->execute()) {
                return true;
            } else {
                self::logQueryFail("Unknown error while updating a device" , $q , $e);
            }

        } catch (\Exception $e) {
            self::logQueryFail("Error while inserting a Device" , $q , $e);
        }
        return false;

    }

    /**
     * @param string $guid
     *
     * @return Device|null
     */

    public static function deviceWithDeviceGuid($guid)
    {
        if (!$guid) return null;
        $pdo    = self::getClassPDO();
        $q      = $e = null;
        $device = null;

        $sql = <<<SQL
SELECT * FROM Device WHERE device_guid_bin=:gu  
SQL;
        try {

            $q = $pdo->prepare($sql);
            $q->bindValue(':gu' , stringGuidAsBinaryGuid($guid) , \PDO::PARAM_STR);
            if ($q->execute()) {
                $rows = $q->fetchAll();
                if (count($rows) == 0) {
                    self::getClassLogger()->trace(__FUNCTION__ . " Query for device [$guid] returned no device");
                } else if (count($rows) > 1) {
                    self::logQueryFail(__FUNCTION__ . " : Query for device returned multiple rows ! [$guid]" , $q , $e);
                } else {
                    $row    = $rows[0];
                    $device = Device::fromAssociativeArray($row);
                }
            } else {
                self::logQueryFail(__FUNCTION__ . " : Error while fetching device with guid[$guid]" , $q , $e);
            }
        } catch (\Exception $e) {
            self::logQueryFail(__FUNCTION__ . " : Error while fetching device with guid[$guid]" , $q , $e);
        }

        return $device;
    }

}
// etc ...

SQL

--
-- Table structure for table `Device` 
--

DROP TABLE IF EXISTS `Device`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `Device`
(
`id`              bigint(20)                               NOT NULL AUTO_INCREMENT,
`app_id`          bigint(20)                               NOT NULL,
`os_type`         enum ('android','iPhone OS','iOS','nix') NOT NULL,
`os_version`      varchar(11)                                       DEFAULT NULL,
`manufacturer`    varchar(50)                                       DEFAULT NULL,
`model_code`      varchar(50)                                       DEFAULT NULL,
`created_on`      datetime                                 NOT NULL,
`last_seen`       datetime                                 NOT NULL,
`active`          tinyint(4)                               NOT NULL DEFAULT '1',
`is_phone`        tinyint(4)                               NOT NULL DEFAULT '1',
`device_guid_bin` varbinary(16)                                     DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_device_guid` (`device_guid_bin`),
KEY `idx_app` (`app_id`),
KEY `idx_active` (`active`),
CONSTRAINT `fk_device_app` FOREIGN KEY (`app_id`) REFERENCES `App` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB
  AUTO_INCREMENT = 68
  DEFAULT CHARSET = utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;

筆記

  • 在我的全局函數中沒有顯示出諸如dateTimeFromSQLquery等的函數。 我用這樣來規范化數據庫。 時間始終是UTC靜止(DB)和飛行(API)
  • 對於關系,我系統地傾向於使用惰性加載方法(不在所示代碼中)
  • SomeObjectDAO封裝(或不封裝)完全緩存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM