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\Modeluse Hyperf\Database\Model\Model as BaseModel;class Model extends BaseModel
{use HasContainer;use HasRepository;
}
#Hyperf\Database\Model\Modelabstract 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=67127if (!str_contains((string) .1, '.')) {$locale = setlocale(LC_NUMERIC, '0'); // @codeCoverageIgnoresetlocale(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.mzph.cn/news/763309.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始手写RPC框架(番外) Netty基础知识点及常见面试题汇总

目录 Netty 的核心组件Bytebuf(字节容器)Bootstrap 和 ServerBootstrap(启动引导类)Channel(网络操作抽象类)SelectorEventLoop(事件循环)NioEventLoopGroup 默认的构造函数会起多少线程?ChannelHandler(消息处理器) 、 ChannelPipeline(ChannelHandler 对象链表)…

进程控制 | 认识fork函数 | 进程终止 | 进程等待

进程创建 初始fork函数 fork函数是为了创建子进程而生的,通过fork函数之后,我们的父进程的代码和数据是共享的,我们这里是可以通过man手册进行查询的,查询之后是可以发现fork函数是会返回两个值的至于为什么会返回两个值&#x…

牛,The O-one ——通过语音交互控制电脑的开源语言模型

模型介绍 The O-one :一个创新的开源语言模型计算机 可以让你通过语音交互来和你的计算机进行对话,完成询问、指令下达等任务。灵感居然来自Andrej Karpathy 的 LLM 操作系统。O1运行一个代码解释语言模型,并在计算机内核发生特定事件时调用…

社科赛斯考研:二十二载岁月铸辉煌,穿越周期的生命力之源

在考研培训行业的浩瀚海洋中,社科赛斯考研犹如一艘稳健的巨轮,历经二十二载风礼,依然破浪前行。在考研市场竞争白热化与学生对于考研机构要求越来越高的双重影响下,社科赛斯考研却以一种分蘖成长的姿态,扎根、壮大&…

六、C#快速排序算法

简介 快速排序是一种常用的排序算法,它基于分治的思想,通过将一个无序的序列分割成两个子序列,并递归地对子序列进行排序,最终完成整个序列的排序。 其基本思路如下: 选择数组中的一个元素作为基准(pivot…

基于python+vue共享单车信息系统的设计与实现flask-django-php-nodejs

课题主要分为二大模块:即管理员模块和用户模块,主要功能包括:用户、区域、共享单车、单车租赁、租赁归还、报修信息、检修信息等;快速发展的社会中,人们的生活水平都在提高,生活节奏也在逐渐加快。为了节省…

实在智能受邀参加中国人工智能产业发展联盟大会(AIIA)主题分享,共筑智能体机遇新篇章

近日,中国人工智能产业发展联盟(AIIA)在海口召开第十一次全体会议,作为该联盟成员单位,实在智能合伙人&核心算法负责人欧阳小刚受邀出席大会,并以《从RPA到智能体,数字员工的发展及在金融行…

《逆水寒》“公费追星”被骂上热搜,玩家为何如此抗拒剧游联动?

游戏行业最近真是风波不断。 《逆水寒》手游因为和武侠剧《莲花楼》深入联动而遭到玩家抵制,网易游戏测评总监被质疑“公费追星”,还波及到了成毅、陈都灵等多位演员。 尤其是《莲花楼》的男主角成毅,遭到大量《逆水寒》手游玩家的吐槽调侃…

微信向量检索分析一体化数仓探索:OLAP For Embedding

作者:WeOLAP 团队 数据挖掘团队 擅长 OLAP 分析的 ClickHouse 不仅可以用于 vector search,还可承担起整条 embedding 的加工处理工作,All in one Pipeline 也让速度远超传统批处理框架数倍;检索性能虽无法与专业 sim 检索服务相媲美&#xf…

Docker 【安装MongoDB】

文章目录 前言一、安装二、使用三、mongodb常用指令总结 前言 MongoDB是一个非关系型数据库,它主要的应用场景有这些 显示 相比mysql,MongoDB没有事务,索引之类的东西。最小单位是文档。 可能有人说,为什么这个场景我要用mongo…

MO尺度(大气边界层)

在大气表面层( atmospheric surface layer)中,MO参数是用来决定流动是中性或者非中性的一个重要参数。其定义是 z / L z/L z/L,其中 L L L为Obukhov长度,其含义是浮力产生的湍动能和剪切产生的湍动能之比(Hj h AIP 2023)(Monin IAS,1954),具体…

文件怎么做扫码预览?创建文件活码的步骤有哪些?

现在文件可以通过扫描二维码的方式来获取,与传统的通过聊天软件来传输相比,二维码方式的应用更加的方便,其他人只需要通过扫描一张二维码就可以在手机上浏览或者下载文件,通过手机就可以预览、存储。 文件二维码的制作方法也很简…

“龙腾九洲———孙文佳师生书画作品国际交流展”首展成功举行

应美国纽约罗切斯特大学、美国满煜国际文化艺术交流公司的邀请,“龙腾九洲———孙文佳师生书画作品国际交流展”首展开幕式于2024年1月23日上午12时在美国纽约罗切斯特大学西蒙商学院会展中心举行。 开幕式上,罗切斯特大学负责人Priya和美国满煜文化公司…

第1讲-introduction(4)ALU

ALU(Arithmetic and logic unit) ALU的核心部件是加法器。 算术逻辑单元(Arithmetic Logic Unit,简称 ALU)是中央处理器(CPU)的执行单元,是所有中央处理器的核心组成部分。它负责执行所有的算术和逻辑运算,例如加减乘除、与或非等操作。 ALU的主要功能包括: 1. 执…

重学SpringBoot3-Profiles介绍

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-Profiles介绍 Profiles简介如何在Spring Boot中使用Profiles定义Profiles激活ProfilesIDEA设置active profile使用Profile-specific配置文件 条件化Bean…

Unity-UGUI系统

UGUI是什么 UGUI是Unity引擎内自带的UI系统官方称之为:Unity Ul 是目前Unity商业游戏开发中使用最广泛的UI系统开发解决方案 它是基于Unity游戏对象的UI系统,只能用来做游戏UI功能 不能用于开发Unity编辑器中内置的用户界面 六大基础组件 概述 Canvas EventS…

想做【数据分析师】?需要什么条件?

进入数据时代,数据分析师成为各大企业争先抢夺的主要人才之一。数据分析师是在不同行业中,专门从事行业数据收集、整理、分析并且依据相关的数据做出行业研究、评估和预测的专业人员。那做数据分析师需要满足什么条件呢? 首先我们要看一下数据…

性能测试如何定位分析性能瓶颈?

对于一般公司普通测试工程师来说,可能性能测试做的并不是很复杂,可能只是编写下脚本,做个压测,然后输出报告结果,瓶颈分析和调优的事都丢给开发去做。 在一些大厂都有专门的性能测试团队去定位分析系统性能瓶颈&#…

流畅切换Linux的应用程序

流畅切换Linux的应用程序 流畅切换Linux的应用程序一.Linux启动一个程序在后台执行1. 使用nohup和&:2. 使用ctrlZ:3.使用screen:3.1 创建会话3.2 要重新连接到此会话:3.3 中途退出会话,但程序继续运行:3.4 结束一个…

第十节HarmonyOS 常用容器组件3-GridRow

1、描述 栅格容器组件,仅可以和栅格子组件(GridCol)在栅格布局场景中使用。 2、子组件 可以包含GridCol子组件。 3、接口 GridRow(options:{columns: number | GridRowColumnOption, gutter?: Length | GutterOption, Breakpoints?: B…