生成 DAO 的最佳和更快的方法 class
Best and Faster way for generate DAO class
我查阅了很多关于如何使用 PDO 生成 DAO class 的页面,但我还没有找到一种更好更快的方法来获取它。
假设我们有一个名为 Animals 的数据库 table 具有这种结构
CREATE TABLE animals
(
idAnimal int PRIMARY KEY NOT NULL AUTO_INCREMENT,
name varchar(20),
dateOfBirth DATETIME
);
一个好的开发方式是创建两个 class:Animals
和 AnimalsDAO
像这样
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
中一般有从数据库中插入和检索object的方法。
并且在这个 class 中已经存在一个 ORM 问题(ORM Object 关系映射),因为 PDO 的获取方法不能与 object 转换一起正常工作
多年来我一直以这种方式开发 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
class 中的变量,重新生成构造函数(我使用 PhpStorm)并最终编辑行获取后
是否存在生成 DAO 的最佳且更快的方法class?
(另一种方法是检索 class 属性名称并使用 fetch Names 方法,但 dateTime 列再次出现转换问题)
当通过关联解决了对数据库的继承并且继承位于 php class
中时,问题会更加复杂
ER DIAGRAM
数据库结构翻译成
DATABASE STRUCTURE
显然,在php这边有一个父亲超级class和两个child class(扩展了父亲class)
如何更快地为 child 生成 DAO 方法?
根据 OP 要求,我的代码库中的示例
设备
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(部分)
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
等函数。我用它来标准化数据库。静止时间 (DB) 和飞行时间 (API) 始终为 UTC
- 对于关系,我系统地更喜欢延迟加载方法(不在显示的代码中)
- SomeObjectDAO 完全封装了缓存(或不封装)。
我查阅了很多关于如何使用 PDO 生成 DAO class 的页面,但我还没有找到一种更好更快的方法来获取它。
假设我们有一个名为 Animals 的数据库 table 具有这种结构
CREATE TABLE animals
(
idAnimal int PRIMARY KEY NOT NULL AUTO_INCREMENT,
name varchar(20),
dateOfBirth DATETIME
);
一个好的开发方式是创建两个 class:Animals
和 AnimalsDAO
像这样
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
中一般有从数据库中插入和检索object的方法。
并且在这个 class 中已经存在一个 ORM 问题(ORM Object 关系映射),因为 PDO 的获取方法不能与 object 转换一起正常工作
多年来我一直以这种方式开发 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
class 中的变量,重新生成构造函数(我使用 PhpStorm)并最终编辑行获取后
是否存在生成 DAO 的最佳且更快的方法class? (另一种方法是检索 class 属性名称并使用 fetch Names 方法,但 dateTime 列再次出现转换问题)
当通过关联解决了对数据库的继承并且继承位于 php class
中时,问题会更加复杂ER DIAGRAM
数据库结构翻译成 DATABASE STRUCTURE
显然,在php这边有一个父亲超级class和两个child class(扩展了父亲class)
如何更快地为 child 生成 DAO 方法?
根据 OP 要求,我的代码库中的示例
设备
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(部分)
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
等函数。我用它来标准化数据库。静止时间 (DB) 和飞行时间 (API) 始终为 UTC
- 对于关系,我系统地更喜欢延迟加载方法(不在显示的代码中)
- SomeObjectDAO 完全封装了缓存(或不封装)。