首页 > 数据库 >thinkphp6 使用自定义命令,生成数据库视图

thinkphp6 使用自定义命令,生成数据库视图

时间:2024-11-16 11:19:14浏览次数:1  
标签:选项 自定义 viewName 别名 thinkphp6 视图 output 跳过

ThinkPHP 命令行工具中,你可以为选项设置 别名,通过为选项指定一个简短的别名来简化命令输入。例如,如果你希望 --force-recreate 选项有一个简短的别名 -f,你可以通过在 addOption 方法中设置第二个参数来实现这一点。

示例:为选项设置别名

addOption 方法的第二个参数中设置别名。这里是一个包含别名的示例:

<?php

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Option;
use think\Db;

class CreateViews extends Command
{
    protected function configure()
    {
        $this->setName('createViews') // 设置命令名称
            ->setDescription('为数据库中的所有表生成视图。') // 设置命令描述
            // 添加选项:是否强制重新创建视图,并设置别名 '-f'
            ->addOption(
                'force-recreate', 
                'f', // 设置别名 '-f'
                Option::VALUE_NONE, 
                '如果视图已经存在,则强制重新创建视图。' // 选项提示
            )
            // 添加选项:是否跳过已存在的视图,并设置别名 '-s'
            ->addOption(
                'skip-existing', 
                's', // 设置别名 '-s'
                Option::VALUE_NONE, 
                '如果视图已经存在,跳过视图创建。' // 选项提示
            );
    }

    protected function execute(Input $input, Output $output)
    {
        $tables = $this->getAllTables();
        
        // 获取命令行参数:是否强制重建视图
        $forceRecreate = $input->getOption('force-recreate');
        // 获取命令行参数:是否跳过已存在视图
        $skipExisting = $input->getOption('skip-existing');
        
        // 默认行为:如果没有传递参数,则设置跳过已存在视图
        if (!$forceRecreate && !$skipExisting) {
            $skipExisting = true; // 默认跳过视图创建
        }
        
        if (empty($tables)) {
            $output->writeln('没有找到任何表!');
            return;
        }

        // 遍历所有表,为每个表创建视图
        foreach ($tables as $tableName) {
            $fields = $this->getTableFields($tableName);

            if (!empty($fields)) {
                // 初始化字段映射
                $fieldMappings = [
                    'CREATED_BY' => 'CREATOR_ID',
                    'CREATED_TIME' => 'CREATE_TIME',
                    'UPDATED_BY' => 'UPDATE_USER_ID',
                    'UPDATED_TIME' => 'UPDATE_TIME',
                    'DELETED' => 'DEL_FLAG'
                ];
                
                // 构建 SELECT 语句
                $selectFields = [];
                foreach ($fields as $columnName) {
                    // 如果表中包含指定字段,进行重命名
                    if (array_key_exists($columnName, $fieldMappings)) {
                        $selectFields[] = "$columnName AS " . $fieldMappings[$columnName];
                    } else {
                        $selectFields[] = $columnName;
                    }
                }

                // 生成视图名称:使用 'view_' 作为前缀
                $viewName = 'view_' . $tableName;

                // 检查视图是否已经存在
                $viewExists = Db::query("SELECT COUNT(*) FROM information_schema.views WHERE table_name = '$viewName' AND table_schema = DATABASE()");

                if ($viewExists[0]['COUNT(*)'] > 0) {
                    if ($forceRecreate) {
                        // 如果视图存在并且需要强制重建,则先删除旧视图
                        Db::query("DROP VIEW IF EXISTS $viewName");
                        $output->writeln("视图 $viewName 已存在,已删除旧视图。");
                    } elseif ($skipExisting) {
                        // 默认行为,跳过创建视图
                        $output->writeln("视图 $viewName 已存在,跳过创建。");
                        continue; // 跳过当前表,继续处理下一个表
                    } else {
                        // 如果没有传入选项,默认跳过创建视图
                        $output->writeln("视图 $viewName 已存在,未执行操作。");
                        continue; // 跳过当前表,继续处理下一个表
                    }
                }

                // 生成 CREATE VIEW 语句
                $createViewSql = "CREATE VIEW $viewName AS SELECT " . implode(', ', $selectFields) . " FROM $tableName";
                $res = Db::query($createViewSql);

                if ($res) {
                    $output->writeln("视图 $viewName 创建成功!");
                } else {
                    $output->writeln("视图 $viewName 创建失败!");
                }

            } else {
                $output->writeln("表 $tableName 没有字段!");
            }
        }
    }

    // 获取数据库中所有的表名
    protected function getAllTables()
    {
        return Db::query("SHOW TABLES");
    }

    // 获取指定表的所有字段
    protected function getTableFields($tableName)
    {
        return Db::query("DESCRIBE $tableName");
    }
}

关键点:

  • 别名的设置:在 addOption 方法的第二个参数中设置别名:
    • --force-recreate 的别名是 -f
    • --skip-existing 的别名是 -s

使用命令行时:

你可以通过别名来快速使用选项。例如:

  • 使用 -f 别名代替 --force-recreate

    php think createViews -f
    
  • 使用 -s 别名代替 --skip-existing

    php think createViews -s
    
  • 使用完整选项:

    php think createViews --force-recreate --skip-existing
    

总结:

标签:选项,自定义,viewName,别名,thinkphp6,视图,output,跳过
From: https://www.cnblogs.com/zxingduo/p/18549179

相关文章

  • 大数据-226 离线数仓 - Flume 优化配置 自定义拦截器 拦截原理 了 拦截器实现 Java
    点一下关注吧!!!非常感谢!!持续更新!!!Java篇开始了!目前开始更新MyBatis,一起深入浅出!目前已经更新到了:Hadoop(已更完)HDFS(已更完)MapReduce(已更完)Hive(已更完)Flume(已更完)Sqoop(已更完)Zookeeper(已更完)HBase(已更完)Redis(已更完)Kafka(已更完)Spark(已更完)Flink(已更完)ClickHouse(已更完)Kudu(......
  • 鸿蒙NEXT自定义组件:太极Loading
     【引言】(完整代码在最后面)本文将介绍如何在鸿蒙NEXT中创建一个自定义的“太极Loading”组件,为你的应用增添独特的视觉效果。【环境准备】电脑系统:windows10开发工具:DevEcoStudioNEXTBeta1BuildVersion:5.0.3.806工程版本:API12真机:mate60pro语言:ArkTS、ArkUI......
  • 自定义注解进行数据脱敏
    前言有些时候,我们可能对输出的某些字段要做特殊的处理在输出到前端,比如:身份证号,电话等信息,在前端展示的时候我们需要进行脱敏处理,这时候通过自定义注解就非常的有用了。在Jackson中要自定义注解,我们可以通过@JacksonAnnotationsInside注解来实现,如下示例:一、自定义注解import......
  • go fiber: 抛出自定义异常
    一,代码:1,自定义错误类:packageconfigimport("fmt")//定义错误代码和错误信息typeMyErrorstruct{CodeintMsgstring}//需要定义通用的Error()方法func(eMyError)Error()string{returnfmt.Sprintf("Code:%d,Msg:%s",e.Code,e.M......
  • 织梦自定义图片字段报错 Call to a member function GetInnerText()
    问题:添加自定义图片字段时,前台打开当前栏目列表出现 Fatalerror:CalltoamemberfunctionGetInnerText()onstring 错误。解决方法:修改 customfields.func.php 文件:打开 /include/customfields.func.php 文件,搜索:  $fvalue=trim($ntag->GetInnerTe......
  • HowTo—— Swift2.0在视图中显示地图
    HowTo——Swift2.0在视图中显示地图东坡肘子​ ​关注他 4人赞同了该文章HowTo系列只提供代码和简单的说明,XcodeVersion12.0beta2(12A6163b)Swift2.0中,苹果添加了Map,让开发者可以非常容易的在View中添加需要的地图元素。importSwiftUIimpor......
  • ABB AC900F学习笔记331:使用ST做自定义功能块,计算最近60秒的分钟均值和最近60分钟的小
    前面自己学习了在西门子TIA使用SCL编程,施耐德Unity中使用ST编程做分钟均值和小时均值的方法,今晚在家练习了在ABBFreelance中自定义功能块使用ST语言做分钟均值和小时均值。新建项目、插入硬件、仿真器、操作站等不做介绍。新建一个用户功能块池,下面建一个功能块类。功能块类定......
  • Rust ?(Rust错误传播运算符?)(用于简化错误处理,自动将错误从函数中返回)(可恢复错误Result<T
    文章目录Rust错误传播运算符:深入理解与应用1.错误处理的基础1.1`Result`枚举1.2`Option`枚举2.错误传播运算符(`?`)2.1基本语法2.2工作原理1.检查返回值2.提取`Ok`值2.3错误传播示例3.错误传播与自定义错误类型(没仔细看)3.1定义自定义错误类型3.2自定义......
  • echarts自定义tooltip
    tooltip配置tooltip:{show:true,trigger:'axis',formatter:params=>{letresult=`<div>${params[0].axisValue}</div>`params.forEach(item=>{if(......
  • Flask新手教程之- 视图函数的装饰器
    除了@app.route,Flask还支持其他装饰器,用于实现更复杂的功能。 示例:@app.before_request:在每个请求处理之前运行的函数。@app.after_request:在每个请求处理之后运行的函数。@app.teardown_request:在请求结束后运行的函数,用于清理工作。  实例:@app.before_requestd......