php模型映射接口,M 模型实现 (数据映射 + 原型 模式)

## 创建core/database/model/Model.php

```

namespace core\database\model;

class Model

{

// 绑定的数据库连接

protected $connection;

protected $table; // 表

protected $paimaryKey; // 主键

protected $timestamps = true; // 是否自动维护时间字段

/*

为什么要分开两个属性?

$orginal 原的数据

$attriubte 原数据的复制版 用户只能修改这个 !

然后跟$original相比较 得出用户修改的数据字段

*/

protected $original;

protected $attribute;

public function __construct()

{

// 给当前模型绑定一个数据库连接

$this->connection = \App::getContainer()->get('db')->connection(

$this->connection

);

}

// 获取表名称 没有表名称 就返回 模型(小写)+s

public function getTable()

{

if( $this->table)

return $this->table;

$class_name = get_class($this);

$class_arr = explode('\\',$class_name);

$table = lcfirst(end(

$class_arr

));

return $table .'s';

}

public function setOriginalValue($key, $val)

{

if(! $this->original)

$this->original = new \stdClass();

$this->original->$key = $val;

}

public function setAttribute($key, $val)

{

if(! $this->attribute)

$this->attribute = new \stdClass();

$this->attribute->$key = $val;

}

// 见最上面的说明

public function __set($key, $value)

{

$this->setAttribute($key, $value);

}

// 属性 同步 original

public function syncOriginal()

{

$this->attribute = $this->original;

}

/**

* 返回用户改过的数据

* @return array

* @example ['id' => 3,'user_id' => '3']

*/

public function diff()

{

$diff = [];

if( $this->attribute == $this->original) // 没改变

return $diff;

foreach ($this->original as $origin_key => $origin_val)

if( $this->attribute->$origin_key != $origin_val) // 改变了

$diff[$origin_key] = $this->attribute->$origin_key;

return $diff;

}

public function __get($name)

{

return $this->attribute->$name;

}

// 托管到 __call

//因此: User::where() 与 (new User)->where() 是一样的

public static function __callStatic($method, $args)

{

return (new static())->$method(...$args);

}

public function __call($method, $args)

{

return (new Builder(

$this->connection->newBuilder()

))

->setModel($this)

->$method(...$args);

}

}

````

## 创建core/database/model/Builder.php

```

namespace core\database\model;

class Builder

{

protected $query;

protected $model;

public function __construct($query)

{

$this->query = $query;

}

public function setModel(Model $model)

{

$this->model = $model;

return $this;

}

public function __call($method, $args)

{

$this->query->$method(...$args);

return $this;

}

public function get($columns = ['*'])

{

if(! is_array($columns))

$columns = func_get_args();

$this->query->columns = $columns;

$this->query->table( $this->model->getTable());

$sql = $this->query->toSql();

return $this->bindModel(

$this->query->runSql($sql)

);

}

// 数据映射模式 把数据映射到模型

//模型的本质: 每条数据都是一个模型(对象)

protected function bindModel($datas)

{

if(! is_array($datas))

$datas[] = $datas;

$models = [];

foreach ($datas as $data){ // 多少条数据就多少个模型

$model = clone $this->model; // 原型模式

foreach ($data as $key => $val)

$model->setOriginalValue($key, $val);

$model->syncOriginal(); // 把attriubtes = orginal

$models[] = $model;

}

return $models;

}

}

```

## 编辑app/User.php 继承模型基础类

![](https://img.kancloud.cn/a4/69/a469507e60982a6a0754d7e25682e78a_1311x630.png)

## 运行

由于每条数据都是一个类,所以可以调用方法。

![](https://img.kancloud.cn/8c/ed/8cedf0e02c378211d95918bf102adc13_553x156.png)

![](https://img.kancloud.cn/29/b3/29b33c1d7d2d2eec98d116a89372dd80_595x268.png)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果数据模型希望通过前端表单设置字段映射关系来获取,可以考虑使用动态数据模型或者基于元数据数据模型。 1. 动态数据模型:动态数据模型是指在运行时动态生成数据模型,可以根据用户输入的字段映射关系来生成相应的数据模型。在实现上,可以使用Java的反射机制或者动态代理来实现动态数据模型。具体实现过程如下: ```java public class DynamicModel { private Map<String, String> properties = new HashMap<>(); public void addProperty(String name, String type) { properties.put(name, type); } public Map<String, String> getProperties() { return properties; } public void setProperties(Map<String, String> properties) { this.properties = properties; } } ``` 2. 基于元数据数据模型:基于元数据数据模型是指在数据模型中添加元数据信息,用于描述数据模型中包含的字段、类型和约束等信息。在实现上,可以使用Java的注解或者XML配置文件来实现基于元数据数据模型。具体实现过程如下: ```java public class User { @Column(name = "id", type = "int", primaryKey = true) private int id; @Column(name = "name", type = "varchar(50)", nullable = false) private String name; @Column(name = "age", type = "int") private int age; //getter and setter } public @interface Column { String name() default ""; String type() default ""; boolean primaryKey() default false; boolean nullable() default true; } ``` 在以上两种方式中,都可以根据用户输入的字段映射关系来生成相应的数据模型,并将数据存储到数据库中。需要注意的是,动态数据模型和基于元数据数据模型都需要进行合理的数据类型转换和数据校验,以保证数据的准确性和一致性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值