hyperf 二十六 数据迁移 二

2024-03-12 14:36
文章标签 数据 二十六 迁移 hyperf

本文主要是介绍hyperf 二十六 数据迁移 二,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

教程:Hyperf

参考文章hyperf 二十五 数据迁移 一-CSDN博客

根据之前写的数据迁移的文章,已经说明Hyperf\Database\Schema\Schema::create()实际运行Hyperf\Database\Schema\Grammars\MySqlGrammar::compileCreate()生成的sql字符串。

文档所谓"在迁移文件中主要通过 Hyperf\Database\Schema\Schema 类来定义数据表和管理迁移流程。",就是使用Schema来执行具体的迁移sql。生成迁移sql的内容由回调设置。

一 数据表

1.1 创建数据表

使用Hyperf\Database\Schema\Blueprint类对象设置表结构。

属性解释类型

engine

指定表存储引擎string

charset

指定表默认字符集string

collation

指定表默认排序规则string

temporary

指定是否为临时表boolen

after

在该列之后添加新列string

Blueprint::temporary()设置temporary为true,设置为临时表。

1.2 重命名数据表

可以使用 $table->rename($to),或者Schema::rename($from,$to)。

 1.2.1 $table->rename($to)

Blueprint::rename($to)重命名表名,$to为重新定义的表名。

执行的是Blueprint::rename(),其将执行内容设置为Hyperf\Utils\Fluent类的name属性,并将其放到数组commands中,之后获取sql时调用Blueprint::toSql()。

Blueprint::toSql()遍历数组commands,执行以compile开头的Hyperf\Database\Schema\Grammars\Grammar或其子类的对应方法。

1.2.2 Schema::rename($from, $to)

Hyperf\Database\Schema\Schema::__callStatic()获取对应驱动的Connection子类,再获取Builder或其子类执行对应方法。

以musql驱动为例,$table->rename($to)执行Hyperf\Database\Schema\Blueprint::rename($to),Schema::rename($from,$to)通过子类Hyperf\Database\Schema\MySqlBuilder执行Hyperf\Database\Schema\Builder::rename($from,$to)。

Builder::rename($from,$to)中调用Builder::createBlueprint(),返回Hyperf\Database\Schema\Blueprint类对象。即Schema::rename($from,$to)其实最后也是执行Blueprint类方法。

使用Blueprint需要在回调当中使用。根据源码Schema::table()中可以设置回调。

注:在重命名表之前,应判断该表是否为其他表外键。

1.3 删除数据表

在删除表之前应判断表是否存在。

1.3.1 删除表

使用Schema::drop($table),或者$table::drop()。

根据以上逻辑,$table::drop()执行Hyperf\Database\Schema\Blueprint::drop(),Schema::drop($table)执行Hyperf\Database\Schema\Builder::drop($table)。

Builder::drop($table)中也调用Builder::createBlueprint()。

1.3.2 判断表是否存在

使用Schema::dropIfExists($table),或者$table::dropIfExists()。

根据以上逻辑,$table::drop()执行Hyperf\Database\Schema\Blueprint::dropIfExists(),Schema::drop($table)执行Hyperf\Database\Schema\Builder::dropIfExists($table)。

Builder::dropIfExists($table)中也调用Builder::createBlueprint()。

1.3.3 检查表是否存在

使用Schema::hasTable($table),执行Hyperf\Database\Schema\Builder::hasTable($table)。

Schema\Builder::hasTable($table)直接执行Hyperf\Database\Schema\Grammars\Grammar或其子类compileTableExists()返回的sql字符串。

1.3.4 检查字段是否存在

使用Schema::hasColumn($table, $column),执行Hyperf\Database\Schema\Builder::hasColumn($table, $column)。也是直接执行查询出列名,再用in_array()做判断。

1.4 数据库链接选项

设置connection属性,其值为数据库配置文件中数组最外层key值。

为多个数据库连接设置对应配置……这样根据之前文章的修改内容就不用改了……

这里的内容,若迁移使用不同数据库配置,而且不修改源码的情况下,需要在前文件中设置连接。

这样确实安全点……但是执行迁移时,参数中--database会无效而且还不能回滚,除非设置成和命令一样的表。

/(ㄒoㄒ)/~~ 还是一次性看完比较好,当时就想到会有这样的设计,但是感觉不太合理。

二 字段

2.1 创建字段

可用字段定义方法

$table->bigIncrements('id');递增 ID(主键),相当于「UNSIGNED BIG INTEGER」
$table->bigInteger('votes');相当于 BIGINT
$table->binary('data');相当于 BLOB
$table->boolean('confirmed');相当于 BOOLEAN
$table->char('name', 100);相当于带有长度的 CHAR
$table->date('created_at');相当于 DATE
$table->dateTime('created_at');相当于 DATETIME
$table->dateTimeTz('created_at');相当于带时区 DATETIME
$table->decimal('amount', 8, 2);相当于带有精度与基数 DECIMAL
$table->double('amount', 8, 2);相当于带有精度与基数 DOUBLE
$table->enum('level', ['easy', 'hard']);相当于 ENUM
$table->float('amount', 8, 2);相当于带有精度与基数 FLOAT
$table->geometry('positions');相当于 GEOMETRY
$table->geometryCollection('positions');相当于 GEOMETRYCOLLECTION
$table->increments('id');递增的 ID (主键),相当于「UNSIGNED INTEGER」
$table->integer('votes');相当于 INTEGER
$table->ipAddress('visitor');相当于 IP 地址
$table->json('options');相当于 JSON
$table->jsonb('options');相当于 JSONB
$table->lineString('positions');相当于 LINESTRING
$table->longText('description');相当于 LONGTEXT
$table->macAddress('device');相当于 MAC 地址
$table->mediumIncrements('id');递增 ID (主键) ,相当于「UNSIGNED MEDIUM INTEGER」
$table->mediumInteger('votes');相当于 MEDIUMINT
$table->mediumText('description');相当于 MEDIUMTEXT
$table->morphs('taggable');相当于加入递增的 taggable_id 与字符串 taggable_type
$table->multiLineString('positions');相当于 MULTILINESTRING
$table->multiPoint('positions');相当于 MULTIPOINT
$table->multiPolygon('positions');相当于 MULTIPOLYGON
$table->nullableMorphs('taggable');相当于可空版本的 morphs() 字段
$table->nullableTimestamps();相当于可空版本的 timestamps() 字段
$table->point('position');相当于 POINT
$table->polygon('positions');相当于 POLYGON
$table->rememberToken();相当于可空版本的 VARCHAR (100) 的 remember_token 字段
$table->smallIncrements('id');递增 ID (主键) ,相当于「UNSIGNED SMALL INTEGER」
$table->smallInteger('votes');相当于 SMALLINT
$table->softDeletes();相当于为软删除添加一个可空的 deleted_at 字段
$table->softDeletesTz();相当于为软删除添加一个可空的 带时区的 deleted_at 字段
$table->string('name', 100);相当于带长度的 VARCHAR
$table->text('description');相当于 TEXT
$table->time('sunrise');相当于 TIME
$table->timeTz('sunrise');相当于带时区的 TIME
$table->timestamp('added_on');相当于 TIMESTAMP
$table->timestampTz('added_on');相当于带时区的 TIMESTAMP
$table->timestamps();相当于可空的 created_at 和 updated_at TIMESTAMP
$table->timestampsTz();相当于可空且带时区的 created_at 和 updated_at TIMESTAMP
$table->tinyIncrements('id');相当于自动递增 UNSIGNED TINYINT
$table->tinyInteger('votes');相当于 TINYINT
$table->unsignedBigInteger('votes');相当于 Unsigned BIGINT
$table->unsignedDecimal('amount', 8, 2);相当于带有精度和基数的 UNSIGNED DECIMAL
$table->unsignedInteger('votes');相当于 Unsigned INT
$table->unsignedMediumInteger('votes');相当于 Unsigned MEDIUMINT
$table->unsignedSmallInteger('votes');相当于 Unsigned SMALLINT
$table->unsignedTinyInteger('votes');相当于 Unsigned TINYINT
$table->uuid('id');相当于 UUID
$table->year('birth_year');相当于 YEAR
$table->comment('Table Comment');设置表注释,相当于 COMMENT

 大概运行都是Grammar或其子类,简称为Grammar类。运行Grammar类方法compileAdd(),Grammar::compileAdd()中运行Grammar::getType(),调用以type开头的Grammar类对应方法,用于返回sql字符串。

2.2 修改字段

composer require "doctrine/dbal:^3.0"

 根据文档

Schema::table('users', function (Blueprint $table) {// 将字段的长度修改为 50 并允许为空$table->string('name', 50)->nullable()->change();
});

$table->string()返回\Hyperf\Database\Schema\ColumnDefinition类对象。ColumnDefinition父类Hyperf\Utils\Fluent::__call()实际执行nullable()和change()。

Fluent::__call()返回$this,所以用“->”继续调用。其仅设置以方法名设置的属性值。

Hyperf\Database\Schema\Blueprint::toSql()时使用对应属性,具体执行Hyperf\Database\Schema\Grammars\Grammar::compileChange(),最终执行Doctrine\DBAL\Platforms\AbstractMySQLPlatform::getAlterTableSQL()。

所以必须安装doctrine/dbal。

只有下面的字段类型能被 "修改": bigInteger、 binary、 boolean、date、dateTime、dateTimeTz、decimal、integer、json、 longText、mediumText、smallInteger、string、text、time、 unsignedBigInteger、unsignedInteger and unsignedSmallInteger。

2.3 重命名字段

$table->renameColumn('from', 'to')->change();

执行Hyperf\Database\Schema\Grammars\Grammar::compileRenameColumn(),然后执行Hyperf\Database\Schema\Grammars\RenameColumn::compile(),最后也是执行Doctrine\DBAL\Platforms\AbstractMySQLPlatform::getAlterTableSQL()。

2.4 删除字段

$table->dropColumn('name');$table->dropColumn(['name', 'age']);

根据以上逻辑执行Hyperf\Database\Schema\Grammars\Grammar:compileDropColumn(),直接生成sql字符串。

三 测试

3.1 表

测试流程

  1. 创建表
  2. 重命名表
  3. 删除表

3.1.1 创建表

use test1;
show tables;

 

php bin/hyperf gen:migration create_test_table
#migrations\2024_03_06_082623_create_userinfo_table.php
class CreateUserinfoTable extends Migration {protected $connection = 'default2';/*** Run the migrations.*/public function up(): void {Schema::create('userinfo', function (Blueprint $table) {$table->bigIncrements('id');$table->timestamps();});}/*** Reverse the migrations.*/public function down(): void {Schema::dropIfExists('userinfo');}
}
#migrations\2024_03_11_070103_create_test_table.php
class CreateTestTable extends Migration {protected $connection = 'default2';/*** Run the migrations.*/public function up(): void {Schema::create('test', function (Blueprint $table) {$table->bigIncrements('id');$table->timestamps();$table->engine = 'MyISAM';// 指定数据表的默认字符集$table->charset = 'utf8mb4';// 指定数据表默认的排序规则$table->collation = 'utf8mb4_unicode_ci';// 创建临时表$table->temporary();});}/*** Reverse the migrations.*/public function down(): void {Schema::dropIfExists('test');}
}
php bin/hyperf.php   migrate --database=default2
Migrating: 2024_03_06_082623_create_userinfo_table
Migrated:  2024_03_06_082623_create_userinfo_table
Migrating: 2024_03_11_070103_create_test_table
Migrated:  2024_03_11_070103_create_test_table

 

 migration中有test表的记录,但是实际库中没有test表。可能和设置为临时表有关。

经查询mysql临时表仅在当前会话(session)中有效,会话结束时自动消失。

所以把临时表去掉再试下,但是记录未删除的话不会执行。

再次执行,从数据库表看,执行正常。

 3.1.2 重命名表

php bin/hyperf.php gen:migration update_test_table --table=test[INFO] Created Migration: 2024_03_11_074311_update_test_table
#migrations\2024_03_11_074311_update_test_table.php
class UpdateTestTable extends Migration {protected $connection = 'default2';/*** Run the migrations.*/public function up(): void {Schema::table('test', function (Blueprint $table) {$table->rename("test1");});}/*** Reverse the migrations.*/public function down(): void {Schema::table('test', function (Blueprint $table) {//});}
}
php bin/hyperf.php   migrate --database=default2Migrating: 2024_03_11_074311_update_test_table
Migrated:  2024_03_11_074311_update_test_table

  3.1.3 删除表

php bin/hyperf.php gen:migration update_test2_table --table=test[INFO] Created Migration:2024_03_11_075322_update_test2_table.php

因为down函数仅在回滚时执行,所以在up()中设置表删除。

#migrations\2024_03_11_075322_update_test2_table.php
class UpdateTest2Table extends Migration {protected $connection = 'default2';/*** Run the migrations.*/public function up(): void {Schema::table('test1', function (Blueprint $table) {$table->dropIfExists();});}/*** Reverse the migrations.*/public function down(): void {Schema::table('test1', function (Blueprint $table) {//});}
}
php bin/hyperf.php   migrate --database=default2Migrating: 2024_03_11_075322_update_test2_table
Migrated:  2024_03_11_075322_update_test2_table

3.2 字段

测试流程

  1. 设置字段
  2. 修改字段
  3. 删除字段

3.2.1 设置字段

php bin/hyperf.php gen:migration update_userinfo_table --table=userinfo[INFO] Created Migration: 2024_03_11_080602_update_userinfo_table
#migrations\2024_03_11_080602_update_userinfo_table.php
class UpdateUserinfoTable extends Migration {protected $connection = 'default2';/*** Run the migrations.*/public function up(): void {Schema::table('userinfo', function (Blueprint $table) {$table->string('name', 255);$table->tinyInteger('age');});}/*** Reverse the migrations.*/public function down(): void {Schema::table('userinfo', function (Blueprint $table) {//});}
}
php bin/hyperf.php   migrate --database=default2Migrating: 2024_03_11_080602_update_userinfo_table
Migrated:  2024_03_11_080602_update_userinfo_table
DESCRIBE userinfo;

3.2.2 修改字段

php bin/hyperf.php gen:migration update_userinfo2_table --table=userinfo[INFO] Created Migration: 2024_03_11_081819_update_userinfo2_table
#migrations\2024_03_11_081819_update_userinfo2_table.php
class UpdateUserinfo2Table extends Migration {protected $connection = 'default2';/*** Run the migrations.*/public function up(): void {Schema::table('userinfo', function (Blueprint $table) {$table->string("name")->nullable()->change();$table->renameColumn('age', 'age1')->nullable()->change();});}/*** Reverse the migrations.*/public function down(): void {Schema::table('userinfo', function (Blueprint $table) {//});}
}
php bin/hyperf.php   migrate --database=default2Migrating: 2024_03_11_081819_update_userinfo2_table
Migrated:  2024_03_11_081819_update_userinfo2_table
DESCRIBE userinfo;

执行回滚,然会修改文件再次执行。

php bin/hyperf.php migrate:rollback --database=default2Rolling back: 2024_03_11_081819_update_userinfo2_table
Rolled back:  2024_03_11_081819_update_userinfo2_table

但是数据库字段没变……因为down里没设置语句……

#migrations\2024_03_11_081819_update_userinfo2_table.php
class UpdateUserinfo2Table extends Migration {protected $connection = 'default2';/*** Run the migrations.*/public function up(): void {Schema::table('userinfo', function (Blueprint $table) {$table->string("name")->nullable()->change();//$table->tinyInteger('age')->nullable()->change();});}/*** Reverse the migrations.*/public function down(): void {Schema::table('userinfo', function (Blueprint $table) {$table->string("name")->change();$table->tinyInteger('age')->change();});}
}

经过手动改动后,此时数据表结构:

 测试时用$table->tinyInteger('age')测试修改,确实报错PHP Fatal error:  Uncaught Doctrine\DBAL\Exception: Unknown column type "tinyinteger" requested. Any Doctrine type that you use has to be registered with \Doctrine\DBAL\Types\Type::addType().

因为这种字段类型不能修改。所以将代码改为上面图中内容,再次执行。

php bin/hyperf.php   migrate --database=default2Migrating: 2024_03_11_081819_update_userinfo2_table
Migrated:  2024_03_11_081819_update_userinfo2_table

 测试发现写notnull无效,因为改前和改后表差异对比时返回false,但是Hyperf\Utils\Fluent属性notnull确实设置为true。

对应源码

#Hyperf\Database\Schema\Grammars\ChangeColumn
public static function compile($grammar, Blueprint $blueprint, Fluent $command, Connection $connection) {if (!$connection->isDoctrineAvailable()) {throw new RuntimeException(sprintf('Changing columns for table "%s" requires Doctrine DBAL; install "doctrine/dbal".',$blueprint->getTable()));}$tableDiff = static::getChangedDiff($grammar,$blueprint,$schema = $connection->getDoctrineSchemaManager());if ($tableDiff !== false) {return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff);}return [];}#$tableDiff 为false
#Hyperf\Database\Schema\Grammars\ChangeColumn
protected static function getTableWithColumnChanges(Blueprint $blueprint, Table $table) {$table = clone $table;foreach ($blueprint->getChangedColumns() as $fluent) {$column = static::getDoctrineColumn($table, $fluent);// Here we will spin through each fluent column definition and map it to the proper// Doctrine column definitions - which is necessary because Laravel and Doctrine// use some different terminology for various column attributes on the tables.foreach ($fluent->getAttributes() as $key => $value) {if (!is_null($option = static::mapFluentOptionToDoctrine($key))) {if (method_exists($column, $method = 'set' . ucfirst($option))) {$column->{$method}(static::mapFluentValueToDoctrine($option, $value));}}}}return $table;}protected static function getTableWithColumnChanges(Blueprint $blueprint, Table $table) {$table = clone $table;foreach ($blueprint->getChangedColumns() as $fluent) {$column = static::getDoctrineColumn($table, $fluent);// Here we will spin through each fluent column definition and map it to the proper// Doctrine column definitions - which is necessary because Laravel and Doctrine// use some different terminology for various column attributes on the tables.foreach ($fluent->getAttributes() as $key => $value) {if (!is_null($option = static::mapFluentOptionToDoctrine($key))) {if (method_exists($column, $method = 'set' . ucfirst($option))) {$column->{$method}(static::mapFluentValueToDoctrine($option, $value));}}}}return $table;}#column 
/***
object(Doctrine\DBAL\Schema\Column)#901 (16) {["_type":protected]=>object(Doctrine\DBAL\Types\StringType)#884 (0) {}["_length":protected]=>int(255)["_precision":protected]=>int(10)["_scale":protected]=>int(0)["_unsigned":protected]=>bool(false)["_fixed":protected]=>bool(false)["_notnull":protected]=>bool(false)["_default":protected]=>NULL["_autoincrement":protected]=>bool(false)["_platformOptions":protected]=>array(2) {["charset"]=>string(7) "utf8mb4"["collation"]=>string(18) "utf8mb4_unicode_ci"}["_columnDefinition":protected]=>NULL["_comment":protected]=>NULL["_customSchemaOptions":protected]=>array(0) {}["_name":protected]=>string(4) "name"["_namespace":protected]=>NULL["_quoted":protected]=>bool(false)
}
***/#$fluent
/***
array(5) {["type"]=>string(6) "string"["name"]=>string(4) "name"["length"]=>int(255)["notnull"]=>bool(true)["change"]=>bool(true)
}
***/
#Hyperf\Database\Schema\Grammars\ChangeColumn
protected static function mapFluentOptionToDoctrine($attribute) {switch ($attribute) {case 'type':case 'name':return;case 'nullable':return 'notnull';case 'total':return 'precision';case 'places':return 'scale';default:return $attribute;}}
#Hyperf\Utils\Fluent
public function __call($method, $parameters){$this->attributes[$method] = count($parameters) > 0 ? $parameters[0] : true;return $this;}
#Doctrine\DBAL\Schema\Column
/** @return mixed[] */public function toArray(){return array_merge(['name'          => $this->_name,'type'          => $this->_type,'default'       => $this->_default,'notnull'       => $this->_notnull,'length'        => $this->_length,'precision'     => $this->_precision,'scale'         => $this->_scale,'fixed'         => $this->_fixed,'unsigned'      => $this->_unsigned,'autoincrement' => $this->_autoincrement,'columnDefinition' => $this->_columnDefinition,'comment' => $this->_comment,], $this->_platformOptions, $this->_customSchemaOptions);}
#Doctrine\DBAL\Platforms\DB2Platform
private function getAlterColumnClausesSQL(ColumnDiff $columnDiff): array{$newColumn = $columnDiff->getNewColumn()->toArray();$alterClause = 'ALTER COLUMN ' . $columnDiff->getNewColumn()->getQuotedName($this);if ($newColumn['columnDefinition'] !== null) {return [$alterClause . ' ' . $newColumn['columnDefinition']];}……
}

 

根据源码意思,应该是看Doctrine\DBAL\Schema\Column类中是否有对应的set方法。果然Column类中没有setNotnull(),仅有setNullable()。所以能用的就是Column类中以set开头的方法。

方法调用解释
Column::setType()type()字段类型
Column::setNamename()字段名
Column::setLength()length()字段长度

Column::setPrecision()

total()或者precision()

字段浮点精度

setScale()

places()或者scale()小数点后位数

setUnsigned()

unsigned()无符号

setFixed()

fixed()双精度浮点

setNotnull()

notnull()设置是否不为空

setDefault()

default()设置默认值

setPlatformOptions()

platformOptions()批量设置其他属性

setPlatformOption()

platformOption()单个设置其他属性

setColumnDefinition()

columnDefinition()大概是直接定义的语句

 

应该notnull这样的属性没被处理。 结合属性的定义,可以尝试传参数。比如nullable(false)。

执行代码改为

#migrations\2024_03_11_081819_update_userinfo2_table.php
class UpdateUserinfo2Table extends Migration {protected $connection = 'default2';/*** Run the migrations.*/public function up(): void {Schema::table('userinfo', function (Blueprint $table) {$table->string("name")->nullable(false)->change();//$table->tinyInteger('age')->nullable()->change();});}/*** Reverse the migrations.*/public function down(): void {Schema::table('userinfo', function (Blueprint $table) {$table->string("name")->change();$table->tinyInteger('age')->change();});}
}
php bin/hyperf.php   migrate --database=default2Migrating: 2024_03_11_081819_update_userinfo2_table
Migrated:  2024_03_11_081819_update_userinfo2_table

修改成功

3.2.3 删除字段

php bin/hyperf.php gen:migration update_userinfo3_table --table=userinfo[INFO] Created Migration: 2024_03_11_094726_update_userinfo3_table
#migrations\2024_03_11_094726_update_userinfo3_table.php
class UpdateUserinfo3Table extends Migration {protected $connection = 'default2';/*** Run the migrations.*/public function up(): void {Schema::table('userinfo', function (Blueprint $table) {$table->dropColumn(['name', 'age']);});}/*** Reverse the migrations.*/public function down(): void {Schema::table('userinfo', function (Blueprint $table) {//});}
}
php bin/hyperf.php   migrate --database=default2Migrating: 2024_03_11_094726_update_userinfo3_table
Migrated:  2024_03_11_094726_update_userinfo3_table
DESCRIBE userinfo

这篇关于hyperf 二十六 数据迁移 二的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/801575

相关文章

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二

Redis事务与数据持久化方式

《Redis事务与数据持久化方式》该文档主要介绍了Redis事务和持久化机制,事务通过将多个命令打包执行,而持久化则通过快照(RDB)和追加式文件(AOF)两种方式将内存数据保存到磁盘,以防止数据丢失... 目录一、Redis 事务1.1 事务本质1.2 数据库事务与redis事务1.2.1 数据库事务1.

Oracle Expdp按条件导出指定表数据的方法实例

《OracleExpdp按条件导出指定表数据的方法实例》:本文主要介绍Oracle的expdp数据泵方式导出特定机构和时间范围的数据,并通过parfile文件进行条件限制和配置,文中通过代码介绍... 目录1.场景描述 2.方案分析3.实验验证 3.1 parfile文件3.2 expdp命令导出4.总结

更改docker默认数据目录的方法步骤

《更改docker默认数据目录的方法步骤》本文主要介绍了更改docker默认数据目录的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1.查看docker是否存在并停止该服务2.挂载镜像并安装rsync便于备份3.取消挂载备份和迁

不删数据还能合并磁盘? 让电脑C盘D盘合并并保留数据的技巧

《不删数据还能合并磁盘?让电脑C盘D盘合并并保留数据的技巧》在Windows操作系统中,合并C盘和D盘是一个相对复杂的任务,尤其是当你不希望删除其中的数据时,幸运的是,有几种方法可以实现这一目标且在... 在电脑生产时,制造商常为C盘分配较小的磁盘空间,以确保软件在运行过程中不会出现磁盘空间不足的问题。但在

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines

Mybatis拦截器如何实现数据权限过滤

《Mybatis拦截器如何实现数据权限过滤》本文介绍了MyBatis拦截器的使用,通过实现Interceptor接口对SQL进行处理,实现数据权限过滤功能,通过在本地线程变量中存储数据权限相关信息,并... 目录背景基础知识MyBATis 拦截器介绍代码实战总结背景现在的项目负责人去年年底离职,导致前期规

Redis KEYS查询大批量数据替代方案

《RedisKEYS查询大批量数据替代方案》在使用Redis时,KEYS命令虽然简单直接,但其全表扫描的特性在处理大规模数据时会导致性能问题,甚至可能阻塞Redis服务,本文将介绍SCAN命令、有序... 目录前言KEYS命令问题背景替代方案1.使用 SCAN 命令2. 使用有序集合(Sorted Set)

SpringBoot整合Canal+RabbitMQ监听数据变更详解

《SpringBoot整合Canal+RabbitMQ监听数据变更详解》在现代分布式系统中,实时获取数据库的变更信息是一个常见的需求,本文将介绍SpringBoot如何通过整合Canal和Rabbit... 目录需求步骤环境搭建整合SpringBoot与Canal实现客户端Canal整合RabbitMQSp

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核