设计Entity

2020-11-05  by  

架构定义

  1. Entity定义了数据库结构,定义数据库的时候需要选择合适的类型,长度,约束,索引。

  2. Entity作为数据库表的实体类,承担着将数据库资源可编程化的任务,要多用面向对象思维,便捷灵活的操作数据。

  3. Entity结合Symfony-Validate,可以为字段添加注释,完成表最基础的,最普遍的验证规则。

  4. 我们既要将Entity看作表,看到其物理属性。也应当将其看作类,将物理层抽象出来,大胆的在编程中使用。这种融合统一的方式将决定你的开发水准。

创建Entity

  1. 命令

    php bin/console make:entity {entityClassName}
    

    {entityClassName} 选填 未指定的话则对话式询问,询问不指定则对所有实体生效

  2. 通常不建议使用命令行创建实体,直接创建类文件会比较便捷

    下面提供了两组模版可以用于实体的创建。 使用时请将模版中user和User部分替换。并且修改表的描述。

    UUID 代码模版(推荐方式)

    <?php        
    namespace App\Entity;
       
    use App\Repository\UserRepository;
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\Validator\Constraints as Assert;
       
    /**
     * @ORM\Entity(repositoryClass=UserRepository::class)
     * @ORM\Table(name="user", options={"comment":"用户表"})
     */
    class User
    {
        /**
         * @var string
         *
         * @ORM\Column(name="id", type="string")
         * @ORM\Id()
         * @ORM\GeneratedValue(strategy="CUSTOM")
         * @ORM\CustomIdGenerator(class="PHPZlc\PHPZlc\Doctrine\SortIdGenerator")
         */
        private $id;
    }
    

    UUID更加方便系统向分布式系统转化。

    PHPZlc对UUID进行了改造,其在保持唯一性的同时,增加了如自增ID一样的排序性,缺点在于最终生成的ID较长,(如果有更好的算法,希望与我们联系)。

    自增ID代码模版

     <?php        
     namespace App\Entity;
        
     use App\Repository\UserRepository;
     use Doctrine\ORM\Mapping as ORM;
     use Symfony\Component\Validator\Constraints as Assert;
        
     /**
      * @ORM\Entity(repositoryClass=UserRepository::class)
      * @ORM\Table(name="user", options={"comment":"用户表"})
      */
     class User
     {
         /**
          * @ORM\Id
          * @ORM\GeneratedValue
          * @ORM\Column(type="integer")
          */
         private $id;
     }
    

生成GetSet方法,生成RepositoryClass类

使用命令创建Entity的时候,会自动生成这些。但如果是自己手动建立或者修改的话,就需要执行命令手动生成了。

生成get-set,RepositoryClass

php bin/console make:entity {entityClassName} --regenerate

覆盖get-set,RepositoryClass

php bin/console make:entity {entityClassName} --regenerate --overwrite

{entityClassName} 选填 未指定的话则对话式询问,询问不指定则对所有实体生效

常用字段写法示例

  1. string

     /**
      * @var string
      * 
      * @ORM\Column(name="name", type="string", length=30 options={"comment":"名称"})
      */
     private $name;
       
    /**
     * @var string
     * 
     * @ORM\Column(name="content", type="text", options={"comment":"长文本"})
     */
    private $content;
    
  2. boolean

    /**
      * @var boolean
      *
      * @ORM\Column(name="is_disable", type="boolean", options={"comment":"是否禁用", "default":"0"})
      */
    private $isDisable = false;
       
    /**
     * @var boolean
     *
     * @ORM\Column(name="is_del", type="boolean", options={"comment":"是否删除", "default":"0"})
     */
    private $isDel = 0;
       
       
    /**
     * @var boolean
     *
     * @ORM\Column(name="is_built", type="boolean", options={"comment":"是否内置", "default":"0"})
     */
    private $isBuilt = false;
    
  3. datetime

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="create_at", type="datetime", options={"comment":"创建时间"})
     */
    private $createAt;
    
  4. date

     /**
      * @var \DateTime
      *
      * @ORM\Column(name="date", type="date", options={"comment":"日期"})
      */
     private $date; 
    
  5. time

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="date", type="time", options={"comment":"时间"})
     */
    private $date; 
    
  6. int

     /**
      * @var integer
      *
      * @ORM\Column(name="sort_value", type="integer", options={"comment":"排序值"})
      */
     private $sortValue = 0;
    
     /**
      * @var integer
      *
      * @ORM\Column(name="show_num", type="integer", options={"comment":"展现数"})
      */
     private $showNum = 0;
    
  7. smallint

       
     const STATUS_COMPLETE = 1;
    
     const STATUS_CANCEL = 2;
    
     const STATUS_REFUND = 3;
    
     const STATUS_PAYMENT = 4;
    
    
     public static function getStatusArray()
     {
         return [
             self::STATUS_COMPLETE => '已完成',
             self::STATUS_CANCEL => '已取消',
             self::STATUS_REFUND => '已退款',
             self::STATUS_PAYMENT => '已支付'
         ];
     }
       
     /**
      * @var integer
      *
      * @ORM\Column(name="status", type="smallint", options={"comment":"订单状态"})
      */
     private $status;
    

    简单选项在表的头部定义成常量,并且设置读取全部的静态方法。

  8. simple_array(简单数组)

     /**
      * @var array
      *
      * @ORM\Column(name="tags", type="simple_array", options={"comment":"标签"})
      */
     private $tags;
    

    存储格式为:123,123,123

  9. array

     /**
      * @var array
      *
      * @ORM\Column(name="files", type="array", options={"comment":"文件集合"})
      */
     private $files;
    

    储存格式为对象序列化之后的结果,检索能力较差

  10. double

    /**
     * @var string
     *
     * @ORM\Column(name="lon", type="decimal", precision=10, scale=6, options={"comment":"经度"})
     */
    private $lon;
    
    /**
     * @var string
     *
     * @ORM\Column(name="lat", type="decimal", precision=10, scale=6, options={"comment":"纬度"})
     */
    private $lat;
        
    /**
     * @var string
     *
     * @ORM\Column(name="amount", type="decimal", precision=10, scale=2, nullable=true, options={"comment":"价格"})
     */
    private $amount;
    
  11. 外键

    多对一

    /**
     * @var User
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $user;
    

    一对一

    /**
     * @var User
     *
     * @ORM\OneToOne(targetEntity="App\Entity\User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $user;
    

新特性-表外字段

这是PHPZlc独有的特性,可以将子查询Sql定义为字段,使其可以具有编程性,实现了Sql集中管理,提高了使用效率。

该字段在数据库中不对应具体的实际字段,所以称为表外字段。在实际使用中,除了不能进行写相关的操作,其他部分和表内其他字段基本无差别。

   /**
    * @OuterColumn(name="site_domains", type="simple_array", sql="(SELECT GROUP_CONCAT(sd.site_domain) FROM site_domain sd WHERE sd.site_id = sql_pre.id),  options={"comment":"站点域名"}")
    */
   public $siteDomains;
  1. 语法注解

    type: 字段类型。支持原生的大多数类型,未来会考虑支持对象类型,但目前不支持。

    options: 选项。

    comment: "描述"
    

    sql: 子查询sql。

  2. 高级用法

    支持@AddRule注释,利用规则注释可以为其成功执行提供必要的保证。

    @AddRule(name="id", value="1")
    

    具体更多的知识,可以通过学习高级查询-规则章节来了解。

    Sql重写

    正常情况下,子查询的sql是固定不变的。但是有些情况下,子查询的Sql需要传入变量才可以正常的工作。这时候我们可以通过Sql重写解决。

    /**
     * @OuterColumn(name="distance", type="string", sql="repository内重写", options={"comment":"距离"})
     */
    public $distance;
    

    具体更多的知识,可以通过学习规则-高级用法来了解。

表加索引

@ORM\Table(name="sms_record", options={"comment"="短信动态码"}, indexes={@ORM\Index(name="phone", columns={"phone"})})

找到错别字了?本文档有什么问题么?分叉并编辑 它 !

CJayhe

谢谢您的赞赏~

使用微信扫描二维码完成支付

抱歉弹框打扰,系统检测到您今日累计浏览时长已达120秒。如果我们的项目对您有帮助,在 关闭窗口之前,希望能够阅读弹框内容,帮助我们变得更好。

一个成功的项目,实现功能只是基础,合理的架构,对资源的调度能力才是灵魂。 PHPZlc, 致力于在Symfony的基础上提供“知行合一”的项目开发方案。

如果您有关切问题和好的想法:

提交

如果您想帮助我们,可以为我们点亮星星,也可以提供资金支持。

您还可以通过以下渠道,关注我们,获取最新的框架动态,帮助项目获取人气,扩大影响力。

开源伙伴招募:https://phpzlc.com/blog/11.html

由于我们无法获取您是否已经是我们的会员了,所以此弹框每日都会弹出一次,关闭