数据库模型

介绍

传统关系型数据库的模型,日常增删改查完全够用,支持复合主键、联合主键。

模型定义

喜闻乐见的对命名空间、类名无要求,只要按照规定写注解即可!

@Entity 注解为定义实体类

@Table 注解为定义数据表

@Column 注解为定义字段

具体定义看下面代码:

  1. namespace Test;
  2. use Imi\Model\Model;
  3. use Imi\Model\Annotation\Table;
  4. use Imi\Model\Annotation\Column;
  5. use Imi\Model\Annotation\Entity;
  6. /**
  7. * 定义为实体
  8. * @Entity
  9. * 指定实体为test,复合主键id和a
  10. * @Table(name="test", id={"id", "a"})
  11. */
  12. class Test extends Model
  13. {
  14. /**
  15. * ID
  16. * 字段id,类型int,长度10,是主键,第0个主键,是自增字段
  17. * @Column(name="id", type="int", length=10, isPrimaryKey=true, primaryKeyIndex=0, isAutoIncrement=true)
  18. * @var int
  19. */
  20. protected $id;
  21. /**
  22. * aaa
  23. * @Column(name="a", type="string", length=255, isPrimaryKey=true, primaryKeyIndex=1)
  24. * @var string
  25. */
  26. protected $a;
  27. /**
  28. * bbb
  29. * @Column(name="b", type="string", length=255)
  30. * @var string
  31. */
  32. protected $b;
  33. /**
  34. * ccc
  35. * @Column(name="c", type="string", length=255)
  36. * @var string
  37. */
  38. protected $c;
  39. /**
  40. * Get iD
  41. *
  42. * @return int
  43. */
  44. public function getId()
  45. {
  46. return $this->id;
  47. }
  48. /**
  49. * Set iD
  50. *
  51. * @param int $id ID
  52. *
  53. * @return self
  54. */
  55. public function setId(int $id)
  56. {
  57. $this->id = $id;
  58. return $this;
  59. }
  60. /**
  61. * Get aaa
  62. *
  63. * @return string
  64. */
  65. public function getA()
  66. {
  67. return $this->a;
  68. }
  69. /**
  70. * Set aaa
  71. *
  72. * @param string $a aaa
  73. *
  74. * @return self
  75. */
  76. public function setA(string $a)
  77. {
  78. $this->a = $a;
  79. return $this;
  80. }
  81. /**
  82. * Get bbb
  83. *
  84. * @return string
  85. */
  86. public function getB()
  87. {
  88. return $this->b;
  89. }
  90. /**
  91. * Set bbb
  92. *
  93. * @param string $b bbb
  94. *
  95. * @return self
  96. */
  97. public function setB(string $b)
  98. {
  99. $this->b = $b;
  100. return $this;
  101. }
  102. /**
  103. * Get ccc
  104. *
  105. * @return string
  106. */
  107. public function getC()
  108. {
  109. return $this->c;
  110. }
  111. /**
  112. * Set ccc
  113. *
  114. * @param string $c ccc
  115. *
  116. * @return self
  117. */
  118. public function setC(string $c)
  119. {
  120. $this->c = $c;
  121. return $this;
  122. }
  123. }

需要使用注解将表、字段属性全部标注。并且写上getset方法,可以使用模型生成工具生成。

模型中可以加入虚拟字段,通过注解@Column(virtual=true),虚拟字段不参与数据库操作。

模型注解

@Entity

写在类上,定义类为实体模型类

用法:

@Entity

序列化时不使用驼峰命名,使用原本的字段名:

@Entity(false)

@Table

写在类上,定义数据表

用法:

@Table('tb_user')

指定数据库连接池:

@Table(name='tb_user', dbPoolName='指定数据库连接池名')

指定主键:

@Table(name='tb_user', id='id')

指定多个主键

@Table(name='tb_user', id={'id1', 'id2'})

@Column

写在属性上,定义字段列

@Column(name="字段名", type="字段类型", length="长度", nullable="是否允许为空true/false", accuracy="精度,小数位后几位", default="默认值", isPrimaryKey="是否为主键true/false", primaryKeyIndex="联合主键中的第几个,从0开始", isAutoIncrement="是否为自增字段true/false", virtual="虚拟字段,不参与数据库操作true/false", $updateTime=true)

当你指定type=json时,写入数据库时自动json_encode,从数据实例化到对象时自动json_decode

$updateTime:save/update 模型时是否将当前时间写入该字段。支持 date/time/datetime/timestamp/year/int/bigint。当字段为 int 类型,写入秒级时间戳。当字段为 bigint 类型,写入毫秒级时间戳。

@Serializable

写在属性上,序列化注解

用法:

禁止参与序列化(toArray()json_encode()不包含该字段):

@Serializable(false)

@Serializables

写在类上,批量设置序列化注解,优先级低于针对属性单独设置的@Serializable注解

用法:

白名单(序列化后只显示id、name字段):

@Serializables(mode="allow", fields={"id", "name"})

黑名单(序列化后,排除id、name字段)

@Serializables(mode="deny", fields={"id", "name"})

@ExtractProperty

写在属性上,提取字段中的属性到当前模型

用法:

提取该属性中的userId值到当前模型中的userId

@ExtractProperty("userId")

提取该属性中的userId值到当前模型中的userId2

@ExtractProperty(fieldName="userId", alias="userId2")

支持多级提取到当前模型中的userId2

  1. /**
  2. * @ExtractProperty(fieldName="ex.userId", alias="userId2")
  3. */
  4. protected $xxx = [
  5. 'ex' => [
  6. 'userId' => 123,
  7. ],
  8. ];

模型操作

查询记录

查询记录并返回一个模型实例。

  1. // where id = 1
  2. $testModel = TestModel::find(1);
  3. // 复合主键 where a = 1 and a = 'abc'
  4. $testModel = TestModel::find(1, 'abc');
  5. echo $testModel->getId();

批量查询记录

  1. // 查询所有记录
  2. $list = TestModel::select();
  3. // 带 where 条件的查询,id = 1
  4. $list = TestModel::select([
  5. 'id' => 1
  6. ]);
  7. // where 回调条件
  8. $list = TestModel::select(function(IQuery $query){
  9. $query->where('id', '=', 1);
  10. });
  11. // 查询器查询
  12. $list = TestModel::query()->where('id', '=', 1)->select()->getArray();
  13. // 以上所有 $list 都是 TestModel[] 类型

聚合函数

  1. TestModel::count();
  2. TestModel::sum('id');

插入

  1. $testModel = TestModel::newInstance();
  2. $testModel->setA('1');
  3. $testModel->setB('1');
  4. $testModel->setC('1');
  5. $result = $testModel->insert();
  6. // $result 用法同数据库中的 insert() 返回值用法
  7. echo '插入的自增ID:', $testModel->getId();

更新

  1. $testModel = TestModel::find(1, 'abc');
  2. $result = $testModel->update();
  3. // $result 用法同数据库中的 update() 返回值用法

批量更新

  1. // update tb_test set a = 'abc' where id > 5
  2. TestModel::updateBatch([
  3. 'a' => 'abc',
  4. ], 'id > 5');

保存

  1. // 自动判断是插入还是更新
  2. $testModel->save();

删除

  1. $testModel = TestModel::find(1, 'abc');
  2. $result = $testModel->delete();
  3. // $result 用法同数据库中的 delete() 返回值用法

批量删除

  1. // delete tb_test set a = 'abc' where id > 5
  2. TestModel::deleteBatch([
  3. 'a' => 'abc',
  4. ], 'id > 5');

查询器

  1. $testModel = TestModel::query()->where()->join()->select()->get();
  2. // $testModel 依然是 TestModel 类型

初始化模型

  1. $testModel = TestModel::newInstance([
  2. 'a' => 'abc',
  3. 'b' => 'def',
  4. ]);

第二种方法:

  1. $testModel = TestModel::newInstance();
  2. $testModel->set([
  3. 'a' => 'abc',
  4. 'b' => 'def',
  5. ]);