hyperf 二十八 修改器 一

教程:Hyperf

一 修改器和访问器

根据教程,可设置相关函数,如set属性名Attribute()、get属性名Attribute(),设置和获取属性。这在thinkphp中也常见。

修改器:set属性名Attribute();访问器:get属性名Attribute()。

1.1 原理

模型的父类Hyperf\Database\Model\Model,定义__set()、_get()、__isset()、__unset()函数。

设置属性调用__set(),获取属性调用_get()。

__set()调用set属性名Attribute(),和格式化数据。先通过set属性名Attribute()获取值,再判断是否为日期格式化日期数据。若设置字段类型,会根据设定的字段类型匹配对应的类,返回对应类。会判断是否为json数据返回json格式字符换。若调用的对应字符串含有“->”,则将该对应类对象格式化为json字符串返回。

1.2 测试

#App\Controller\Test
public function testmodifier() {
        $result = Article::query()->find(2)->toArray();
        var_dump($result);
        $article = Article::firstOrCreate(
            ['title' => 'test4'],
            ['user_id' => 2]
        );
        $result = Article::query()->where(['title' => '&test4'])->first()->toArray();
        var_dump($result);
    }
#App1\Model\Article
class Article extends Model implements CacheableInterface {
    use Cacheable;
    use SoftDeletes;
    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'articles';
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['title', 'user_id']; //允许批量赋值
    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = ['id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];

    public function setTitleAttribute($value) {
        $this->attributes['title'] = "&" . $value;
    }
    public function getTitleAttribute($value) {
        return "标题:" . $value;
    }
}

 测试结果

array(7) {
  ["id"]=>
  int(2)
  ["user_id"]=>
  int(1)
  ["title"]=>
  string(14) "标题:test2"
  ["created_at"]=>
  string(19) "2024-01-13 10:06:04"
  ["updated_at"]=>
  string(19) "2024-01-13 10:06:06"
  ["deleted_at"]=>
  NULL
  ["pv_num"]=>
  int(0)
}

array(7) {
  ["id"]=>
  int(10)
  ["user_id"]=>
  int(2)
  ["title"]=>
  string(15) "标题:&test4"
  ["created_at"]=>
  string(19) "2024-03-19 08:07:24"
  ["updated_at"]=>
  string(19) "2024-03-19 08:07:24"
  ["deleted_at"]=>
  NULL
  ["pv_num"]=>
  int(0)
}

数据保存使用Hyperf\Database\Model\Builder::firstOrCreate()。firstOrNew()仅在对象中增加数据,未保存进数据库,这是和firstOrCreate()的区别。

过程中创建Hyperf\Database\Model\Model类对象是__construct(),会调用Model::fill()。Model::fill()使用Model::isFillable()调用Model::fillable属性,结果为true,才能设置属性,否则报错。

因为在Article::setTitleAttribute()对传入的属性增加数据。根据测试代码,查询的使用也应该加上“&”。

也是因为使用Builder::firstOrCreate()和Article::setTitleAttribute()修改传入属性,设置查询数据时不会查询到相应数据,因为查询值有差异。

tp中也遇到过相似情况。解决方法,对查询条件中数据也进行数据的换装,保证修改方式和保存之前的数据方式一样。

1.3 源码

#App1\Model\Article 

use Hyperf\DbConnection\Model\Model;

class Article extends Model implements CacheableInterface {
    use Cacheable;
    use SoftDeletes;
}


#Hyperf\DbConnection\Model\Model

use Hyperf\Database\Model\Model as BaseModel;

class Model extends BaseModel
{
    use HasContainer;
    use HasRepository;
}
#Hyperf\Database\Model\Model

abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, 
CompressInterface {
    use Concerns\HasAttributes;
    use Concerns\HasEvents;
    use Concerns\HasGlobalScopes;
    use Concerns\HasRelationships;
    use Concerns\HasTimestamps;
    use Concerns\HidesAttributes;
    use Concerns\GuardsAttributes;

    /**
     * Dynamically retrieve attributes on the model.
     *
     * @param string $key
     */
    public function __get($key) {
        return $this->getAttribute($key);
    }

    /**
     * Dynamically set attributes on the model.
     *
     * @param string $key
     * @param mixed $value
     */
    public function __set($key, $value) {
        $this->setAttribute($key, $value);
    }

    /**
     * Determine if an attribute or relation exists on the model.
     *
     * @param string $key
     * @return bool
     */
    public function __isset($key) {
        return $this->offsetExists($key);
    }

    /**
     * Unset an attribute on the model.
     *
     * @param string $key
     */
    public function __unset($key) {
        $this->offsetUnset($key);
    }
   
}
# Hyperf\Database\Model\Concerns\HasAttributes
 /**
     * Set a given attribute on the model.
     *
     * @param string $key
     * @param mixed $value
     */
    public function setAttribute($key, $value)
    {
        // First we will check for the presence of a mutator for the set operation
        // which simply lets the developers tweak the attribute as it is set on
        // the model, such as "json_encoding" an listing of data for storage.
        if ($this->hasSetMutator($key)) {
            return $this->setMutatedAttributeValue($key, $value);
        }

        // If an attribute is listed as a "date", we'll convert it from a DateTime
        // instance into a form proper for storage on the database tables using
        // the connection grammar's date format. We will auto set the values.
        if ($value && $this->isDateAttribute($key)) {
            $value = $this->fromDateTime($value);
        }

        if ($this->isClassCastable($key)) {
            $this->setClassCastableAttribute($key, $value);

            return $this;
        }

        if ($this->isJsonCastable($key) && !is_null($value)) {
            $value = $this->castAttributeAsJson($key, $value);
        }

        // If this attribute contains a JSON ->, we'll set the proper value in the
        // attribute's underlying array. This takes care of properly nesting an
        // attribute in the array's value in the case of deeply nested items.
        if (Str::contains($key, '->')) {
            return $this->fillJsonAttribute($key, $value);
        }

        $this->attributes[$key] = $value;

        return $this;
    }
    /**
     * Set the value of an attribute using its mutator.
     *
     * @param string $key
     * @param mixed $value
     */
    protected function setMutatedAttributeValue($key, $value)
    {
        return $this->{'set' . Str::studly($key) . 'Attribute'}($value);
    }
     /**
     * Convert a DateTime to a storable string.
     *
     * @param mixed $value
     * @return null|string
     */
    public function fromDateTime($value)
    {
        return empty($value) ? $value : $this->asDateTime($value)->format(
            $this->getDateFormat()
        );
    }
     /**
     * Get the format for database stored dates.
     *
     * @return string
     */
    public function getDateFormat()
    {
        return $this->dateFormat ?: $this->getConnection()->getQueryGrammar()->getDateFormat();
    }
/**
     * Set the value of a class castable attribute.
     *
     * @param string $key
     * @param mixed $value
     */
    protected function setClassCastableAttribute($key, $value)
    {
        $caster = $this->resolveCasterClass($key);

        if (is_null($value)) {
            $this->attributes = array_merge($this->attributes, array_map(
                function () {
                },
                $this->normalizeCastClassResponse($key, $caster->set(
                    $this,
                    $key,
                    $this->{$key},
                    $this->attributes
                ))
            ));
        } else {
            $this->attributes = array_merge(
                $this->attributes,
                $this->normalizeCastClassResponse($key, $caster->set(
                    $this,
                    $key,
                    $value,
                    $this->attributes
                ))
            );
        }

        if ($caster instanceof CastsInboundAttributes || !is_object($value)) {
            unset($this->classCastCache[$key]);
        } else {
            $this->classCastCache[$key] = $value;
        }
    }
 /**
     * Cast the given attribute to JSON.
     *
     * @param string $key
     * @param mixed $value
     * @return string
     */
    protected function castAttributeAsJson($key, $value)
    {
        $value = $this->asJson($value);

        if ($value === false) {
            throw JsonEncodingException::forAttribute(
                $this,
                $key,
                json_last_error_msg()
            );
        }

        return $value;
    }
 /**
     * Set a given JSON attribute on the model.
     *
     * @param string $key
     * @param mixed $value
     * @return $this
     */
    public function fillJsonAttribute($key, $value)
    {
        [$key, $path] = explode('->', $key, 2);

        $this->attributes[$key] = $this->asJson($this->getArrayAttributeWithValue(
            $path,
            $key,
            $value
        ));

        return $this;
    }

二 日期转化及时间格式化

模型会将 created_atupdated_at 字段转换为 Carbon\Carbon 实例,它继承了 PHP 原生的 DateTime 类并提供了各种有用的方法。可以通过设置模型的 $dates 属性来添加其他日期属性。

2.1 原理

调用Model::_get()、Model::_set()时,会判断字段类型,为日期则转换为Carbon\Carbon类对象。可以设置日期格式。

$date为日期类型字段,$dateFormat为日期格式字符串,都在Hyperf\Database\Model\Concerns\HasAttributes中设置,也是由其转换数据类型。

HasAttributes::castAttribute()处理各种字段类型,HasAttributes::asDate()执行日期类型转换,HasAttributes::getDateFormat()获取日期格式。

日期类型默认包括created_at 、updated_at。日期默认格式"Y-m-d H:i:s"。

2.2 测试

 #App1\Model\Article  
 protected $dateFormat = 'Y-m-d H:i';
 public function setTitleAttribute($value) {
        $this->attributes['title'] = $value;
    }
    public function getTitleAttribute($value) {
        return $value;
    }
#App\Controller\TestController
public function testmodifier() {
        $article = Article::firstOrCreate(
            ['title' => 'test4'],
            ['user_id' => 2]
        );
        var_dump($article->toArray());
    }

 测试结果

array(7) {
  ["id"]=>
  int(11)
  ["user_id"]=>
  int(2)
  ["title"]=>
  string(5) "test4"
  ["created_at"]=>
  string(16) "2024-03-22 09:04"
  ["updated_at"]=>
  string(16) "2024-03-22 09:04"
  ["deleted_at"]=>
  NULL
  ["pv_num"]=>
  int(0)
}

 

测试可见 数据库中时间格式还是h:i:s,仅获取的时候是h:i格式。

Model::CREATED_AT、Model::UPDATED_AT使用Carbon::now()获取时间,并没有使用$dateFormat属性。

2.3 源码

#Hyperf\Database\Model\Model
public function __get($key) {
        return $this->getAttribute($key);
    }
public function __set($key, $value) {
        $this->setAttribute($key, $value);
    }
 /**
     * 新增时使用
     *
     * @param \Hyperf\Database\Model\Builder $query
     * @return bool
     */
    protected function performInsert(Builder $query) {
        if ($event = $this->fireModelEvent('creating')) {
            if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
                return false;
            }
        }

        // First we'll need to create a fresh query instance and touch the creation and
        // update timestamps on this model, which are maintained by us for developer
        // convenience. After, we will just continue saving these model instances.
        if ($this->usesTimestamps()) {
            $this->updateTimestamps();
        }

        // If the model has an incrementing key, we can use the "insertGetId" method on
        // the query builder, which will give us back the final inserted ID for this
        // table from the database. Not all tables have to be incrementing though.
        $attributes = $this->getAttributes();

        if ($this->getIncrementing()) {
            $this->insertAndSetId($query, $attributes);
        }

        // If the table isn't incrementing we'll simply insert these attributes as they
        // are. These attribute arrays must contain an "id" column previously placed
        // there by the developer as the manually determined key for these models.
        else {
            if (empty($attributes)) {
                return true;
            }

            $query->insert($attributes);
        }

        // We will go ahead and set the exists property to true, so that it is set when
        // the created event is fired, just in case the developer tries to update it
        // during the event. This will allow them to do so and run an update here.
        $this->exists = true;

        $this->wasRecentlyCreated = true;

        $this->fireModelEvent('created');

        return true;
    }
/**
     * 修改时使用
     *
     * @param \Hyperf\Database\Model\Builder $query
     * @return bool
     */
    protected function performUpdate(Builder $query) {
        // If the updating event returns false, we will cancel the update operation so
        // developers can hook Validation systems into their models and cancel this
        // operation if the model does not pass validation. Otherwise, we update.
        if ($event = $this->fireModelEvent('updating')) {
            if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
                return false;
            }
        }

        // First we need to create a fresh query instance and touch the creation and
        // update timestamp on the model which are maintained by us for developer
        // convenience. Then we will just continue saving the model instances.
        if ($this->usesTimestamps()) {
            $this->updateTimestamps();
        }

        // Once we have run the update operation, we will fire the "updated" event for
        // this model instance. This will allow developers to hook into these after
        // models are updated, giving them a chance to do any special processing.
        $dirty = $this->getDirty();

        if (count($dirty) > 0) {
            $this->setKeysForSaveQuery($query)->update($dirty);

            $this->syncChanges();

            $this->fireModelEvent('updated');
        }

        return true;
    }
 public function save(array $options = []): bool {
        $this->mergeAttributesFromClassCasts();

        $query = $this->newModelQuery();

        // If the "saving" event returns false we'll bail out of the save and return
        // false, indicating that the save failed. This provides a chance for any
        // listeners to cancel save operations if validations fail or whatever.
        if ($saving = $this->fireModelEvent('saving')) {
            if ($saving instanceof StoppableEventInterface && $saving->isPropagationStopped()) {
                return false;
            }
        }

        // If the model already exists in the database we can just update our record
        // that is already in this database using the current IDs in this "where"
        // clause to only update this model. Otherwise, we'll just insert them.
        if ($this->exists) {
            $saved = $this->isDirty() ? $this->performUpdate($query) : true;
        } else {
            // If the model is brand new, we'll insert it into our database and set the
            // ID attribute on the model to the value of the newly inserted row's ID
            // which is typically an auto-increment value managed by the database.
            $saved = $this->performInsert($query);

            if (!$this->getConnectionName() && $connection = $query->getConnection()) {
                $this->setConnection($connection->getName());
            }
        }

        // If the model is successfully saved, we need to do a few more things once
        // that is done. We will call the "saved" method here to run any actions
        // we need to happen after a model gets successfully saved right here.
        if ($saved) {
            $this->finishSave($options);
        }

        return $saved;
    }
#Hyperf\Database\Model\Concerns\HasAttributes
 /**
     * Set a given attribute on the model.
     *
     * @param string $key
     * @param mixed $value
     */
public function setAttribute($key, $value)
    {
        // First we will check for the presence of a mutator for the set operation
        // which simply lets the developers tweak the attribute as it is set on
        // the model, such as "json_encoding" an listing of data for storage.
        if ($this->hasSetMutator($key)) {
            return $this->setMutatedAttributeValue($key, $value);
        }

        // If an attribute is listed as a "date", we'll convert it from a DateTime
        // instance into a form proper for storage on the database tables using
        // the connection grammar's date format. We will auto set the values.
        if ($value && $this->isDateAttribute($key)) {
            $value = $this->fromDateTime($value);
        }

        if ($this->isClassCastable($key)) {
            $this->setClassCastableAttribute($key, $value);

            return $this;
        }

        if ($this->isJsonCastable($key) && !is_null($value)) {
            $value = $this->castAttributeAsJson($key, $value);
        }

        // If this attribute contains a JSON ->, we'll set the proper value in the
        // attribute's underlying array. This takes care of properly nesting an
        // attribute in the array's value in the case of deeply nested items.
        if (Str::contains($key, '->')) {
            return $this->fillJsonAttribute($key, $value);
        }

        $this->attributes[$key] = $value;

        return $this;
    }
 public function fromDateTime($value)
    {
        return empty($value) ? $value : $this->asDateTime($value)->format(
            $this->getDateFormat()
        );
    }
/**
     * Get an attribute from the model.
     *
     * @param string $key
     */
    public function getAttribute($key)
    {
        if (!$key) {
            return;
        }

        // If the attribute exists in the attribute array or has a "get" mutator we will
        // get the attribute's value. Otherwise, we will proceed as if the developers
        // are asking for a relationship's value. This covers both types of values.
        if (array_key_exists($key, $this->getAttributes())
            || $this->hasGetMutator($key)
            || $this->isClassCastable($key)) {
            return $this->getAttributeValue($key);
        }
        // Here we will determine if the model base class itself contains this given key
        // since we don't want to treat any of those methods as relationships because
        // they are all intended as helper methods and none of these are relations.
        if (method_exists(self::class, $key)) {
            return;
        }
        return $this->getRelationValue($key);
    }
public function getAttributeValue($key)
    {
        return $this->transformModelValue($key, $this->getAttributeFromArray($key));
    }
 protected function transformModelValue($key, $value)
    {
        // If the attribute has a get mutator, we will call that then return what
        // it returns as the value, which is useful for transforming values on
        // retrieval from the model to a form that is more useful for usage.
        if ($this->hasGetMutator($key)) {
            return $this->mutateAttribute($key, $value);
        }

        // If the attribute exists within the cast array, we will convert it to
        // an appropriate native PHP type dependent upon the associated value
        // given with the key in the pair. Dayle made this comment line up.
        if ($this->hasCast($key)) {
            return $this->castAttribute($key, $value);
        }

        // If the attribute is listed as a date, we will convert it to a DateTime
        // instance on retrieval, which makes it quite convenient to work with
        // date fields without having to create a mutator for each property.
        if ($value !== null
            && \in_array($key, $this->getDates(), false)) {
            return $this->asDateTime($value);
        }

        return $value;
    }
 protected function castAttribute($key, $value)
    {
        $castType = $this->getCastType($key);

        if (is_null($value) && in_array($castType, static::$primitiveCastTypes)) {
            return $value;
        }

        switch ($castType) {
            case 'int':
            case 'integer':
                return (int) $value;
            case 'real':
            case 'float':
            case 'double':
                return $this->fromFloat($value);
            case 'decimal':
                return $this->asDecimal($value, explode(':', $this->getCasts()[$key], 2)[1]);
            case 'string':
                return (string) $value;
            case 'bool':
            case 'boolean':
                return (bool) $value;
            case 'object':
                return $this->fromJson($value, true);
            case 'array':
            case 'json':
                return $this->fromJson($value);
            case 'collection':
                return new BaseCollection($this->fromJson($value));
            case 'date':
                return $this->asDate($value);
            case 'datetime':
            case 'custom_datetime':
                return $this->asDateTime($value);
            case 'timestamp':
                return $this->asTimestamp($value);
        }

        if ($this->isClassCastable($key)) {
            return $this->getClassCastableAttributeValue($key, $value);
        }

        return $value;
    }
protected function asDate($value)
    {
        return $this->asDateTime($value)->startOfDay();
    }
protected function asDateTime($value)
    {
        // If this value is already a Carbon instance, we shall just return it as is.
        // This prevents us having to re-instantiate a Carbon instance when we know
        // it already is one, which wouldn't be fulfilled by the DateTime check.
        if ($value instanceof Carbon || $value instanceof CarbonInterface) {
            return Carbon::instance($value);
        }

        // If the value is already a DateTime instance, we will just skip the rest of
        // these checks since they will be a waste of time, and hinder performance
        // when checking the field. We will just return the DateTime right away.
        if ($value instanceof DateTimeInterface) {
            return Carbon::parse(
                $value->format('Y-m-d H:i:s.u'),
                $value->getTimezone()
            );
        }

        // If this value is an integer, we will assume it is a UNIX timestamp's value
        // and format a Carbon object from this timestamp. This allows flexibility
        // when defining your date fields as they might be UNIX timestamps here.
        if (is_numeric($value)) {
            return Carbon::createFromTimestamp($value);
        }

        // If the value is in simply year, month, day format, we will instantiate the
        // Carbon instances from that format. Again, this provides for simple date
        // fields on the database, while still supporting Carbonized conversion.
        if ($this->isStandardDateFormat($value)) {
            return Carbon::instance(Carbon::createFromFormat('Y-m-d', $value)->startOfDay());
        }

        $format = $this->getDateFormat();

        // Finally, we will just assume this date is in the format used by default on
        // the database connection and use that format to create the Carbon object
        // that is returned back out to the developers after we convert it here.
        if (Carbon::hasFormat($value, $format)) {
            return Carbon::createFromFormat($format, $value);
        }

        return Carbon::parse($value);
    }
public function getDateFormat()
    {
        return $this->dateFormat ?: $this->getConnection()->getQueryGrammar()->getDateFormat();
    }
#Hyperf\Database\Grammar
public function getDateFormat()
    {
        return 'Y-m-d H:i:s';
    }
#Hyperf\Database\Model\Concerns\HasTimestamps
protected function updateTimestamps()
    {
        $time = $this->freshTimestamp();

        if (! is_null(static::UPDATED_AT) && ! $this->isDirty(static::UPDATED_AT)) {
            $this->setUpdatedAt($time);
        }

        if (! $this->exists && ! is_null(static::CREATED_AT)
            && ! $this->isDirty(static::CREATED_AT)) {
            $this->setCreatedAt($time);
        }
    }
public function setCreatedAt($value)
    {
        $this->{static::CREATED_AT} = $value;

        return $this;
    }

public function setUpdatedAt($value)
    {
        $this->{static::UPDATED_AT} = $value;

        return $this;
    }
public function freshTimestamp()
    {
        return Carbon::now();
    }

 

#Carbon\Traits\Creator
public function __construct($time = null, $tz = null)
    {
        if ($time instanceof DateTimeInterface) {
            $time = $this->constructTimezoneFromDateTime($time, $tz)->format('Y-m-d H:i:s.u');
        }

        if (is_numeric($time) && (!\is_string($time) || !preg_match('/^\d{1,14}$/', $time))) {
            $time = static::createFromTimestampUTC($time)->format('Y-m-d\TH:i:s.uP');
        }

        // If the class has a test now set and we are trying to create a now()
        // instance then override as required
        $isNow = empty($time) || $time === 'now';

        if (method_exists(static::class, 'hasTestNow') &&
            method_exists(static::class, 'getTestNow') &&
            static::hasTestNow() &&
            ($isNow || static::hasRelativeKeywords($time))
        ) {
            static::mockConstructorParameters($time, $tz);
        }

        // Work-around for PHP bug https://bugs.php.net/bug.php?id=67127
        if (!str_contains((string) .1, '.')) {
            $locale = setlocale(LC_NUMERIC, '0'); // @codeCoverageIgnore
            setlocale(LC_NUMERIC, 'C'); // @codeCoverageIgnore
        }

        try {
            parent::__construct($time ?: 'now', static::safeCreateDateTimeZone($tz) ?: null);
        } catch (Exception $exception) {
            throw new InvalidFormatException($exception->getMessage(), 0, $exception);
        }

        $this->constructedObjectId = spl_object_hash($this);

        if (isset($locale)) {
            setlocale(LC_NUMERIC, $locale); // @codeCoverageIgnore
        }

        self::setLastErrors(parent::getLastErrors());
    }
 public static function now($tz = null)
    {
        return new static(null, $tz);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/486944.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【mysql基础知识】

mysql数据类型 MySQL数据类型定义了数据的大小范围,因此使用时选择合适的类型,不仅会降低表占用的磁盘空间, 间接减少了磁盘I/O的次数,提高了表的访问效率,而且索引的效率也和数据的类型息息相关。 数值类型 比如说…

某蓝队面试经验

背景 据小道消息说今年的国护疑似提前到了五月份,所以最近也是HW面试的一个高峰期啊,这里分享一下上次长亭的蓝队面试问题(附本人的回答,仅供参考) 面试问答 1、谈谈作为蓝队护网过程使用过厂商的设备 这里我回答的…

1424:喷水装置——1425:加工生产调度【贪心之区间问题和流水调度问题】

1424:【例题3】喷水装置 时间限制: 1000 ms 内存限制: 65536 KB 【题目描述】 长 L 米,宽 W 米的草坪里装有 n 个浇灌喷头。每个喷头都装在草坪中心线上(离两边各 W2 米)。我们知道每个喷头的位置(离草坪中心线左端的距离),以及它能覆盖到的浇灌范围。 请问:如…

车道线检测中的IPM变换

车道线检测中的IPM变换 车道线检测(Lane Detection)是 ADAS 系统中重要的功能模块,而对于 L4 自动驾驶系统来说,在不完全依赖高精度地图的情况下,车道线检测结果也是车辆运动规划的重要输入信息。由于俯视图(BEV, Bird’s Eye View)下做车道…

【Tanshtech】生物膜/细胞膜包裹纳米颗粒CMNs递送药物定制

细胞膜包裹的纳米颗粒(Cell membrane-coated nanoparticles,CNPs)是一类新兴的纳米载体,其通过天然细胞膜将纳米颗粒包裹在核心位置,使得它们能够在复杂的生物体环境中逃逸免疫清除,并在靶定肿瘤部位积累。…

城市内涝水文水动力模型:慧天【HTWATER】

查看详情>>> 城市内涝水文水动力模型:慧天【HTWATER】 【城市内涝水文水动力模型介绍】 慧天排水数字化分析平台针对城市排水系统基础设施数据管理的需求,以及水文、水力及水质模拟对数据的需求,实现了以数据库方式对相应数据的存…

python笔记(2)基础语法

python 保留字 import keyword print(keyword.kwlist)运行 "Import-Module PSReadLine"。PS F:\学习\python\测试> & C:/Users/Python/Python311/python.exe f:/学习/python/测试/test.py [False, None, True, and, as, assert, async, await, break, class,…

九泰智库 | 医械周刊- Vol.17

⚖️ 法规动态 器审中心公示新一期医疗器械优先审批申请审核结果 3月22日,依据原国家食品药品监督管理总局《医疗器械优先审批程序》(总局公告2016年168号),器审中心对申请优先审批的医疗器械注册申请进行了审核,对相关…

优化登录页面

作业: 完善对话框,点击登录对话框, 如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个0k按钮,用户点击Ok后,关闭登录界面,跳转到其他界面如果账号和密…

java常用应用程序编程接口(API)——IO流概述及字节流的使用

前言: IO流和File是用于把数据存放在硬盘里的工具。File可以把文件存至硬盘,但不能更改里面的数据。通过IO流可以改写硬盘里的数据。整理下学习笔记,打好基础,daydayup!!! IO流 I指Input,称为输入流:负责把…

1_88. 合并两个有序数组

1_88. 合并两个有序数组 难度: 简单 提示: 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意…

Qt登录页面

#include "mywidget.h" #include "ui_mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent), ui(new Ui::MyWidget) {ui->setupUi(this);//接收动图QMovie *mv new QMovie(":/pictrue/luori.gif");ui->loglab->setMovie(…

MD5加密

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

蓝桥杯小白月赛第八场第三题

题目描述: 思路: 根据上面的次方数,我们可以看出来从1次方到4次方 和 5 - 8次方,中间有什么规律? 是不是可以看出来1次方和5次方的尾数相同 2次方和6次方的尾数相同 3次方和7次方的尾数相同 4次方和8次方的尾数相同 …

浏览器缓存知识梳理

在前端性能优化的方式中,最重要的当然是缓存了,使用好了缓存,对项目有很大的帮助。比如我们访问网页时,使用网页后退功能,会发现加载的非常快,体验感很好,这就是缓存的力量。 什么是缓存呢&…

RSTP环路避免实验(华为)

思科设备参考:RSTP环路避免实验(思科) 一,技术简介 RSTP (Rapid Spanning Tree Protocol) 是从STP发展而来 • RSTP标准版本为IEEE802.1w • RSTP具备STP的所有功能,可以兼容STP运行 • RSTP和STP有所不同 减少了…

英特尔生态的深度学习科研环境配置-A770为例

之前发过在Intel A770 GPU安装oneAPI的教程,但那个方法是用于WSL上。总所周知,在WSL使用显卡会有性能损失的。而当初买这台机器的时候我不在场,所以我这几天刚好有空把机器给重装成Ubuntu了。本篇不限于安装oneAPI,因为在英特尔的…

2024大一同学进入ACM实验室选拔(东北林业大学)

前言&#xff1a; 15号比赛的6道题&#xff0c;有一道题估计是为了防止有人ak设的&#xff0c;我看题解都没完全看懂&#xff0c;是现在的我的知识盲区了&#xff0c;之后再补吧。 正文&#xff1a; Problem:A股神&#xff1a; #include <bits/stdc.h> using namespace…

AVA企业服务呼叫中心管理后台源码

项目中实现用户管理&#xff0c;包括用户的录入、编辑、查看、修改、用户角色的分配 &#xff0c;支持一个用户拥有多个权限&#xff0c;角色管理&#xff0c;可以自由定义角色、并可以给角色分配不同的权限。

利用Jmeter做接口测试(功能测试)全流程分析

利用Jmeter做接口测试怎么做呢&#xff1f;过程真的是超级简单。 明白了原理以后&#xff0c;把零碎的知识点填充进去就可以了。所以在学习的过程中&#xff0c;不管学什么&#xff0c;我一直都强调的是要循序渐进&#xff0c;和明白原理和逻辑。这篇文章就来介绍一下如何利用…
最新文章