自动生成MySQL DDL建表语句

news2024/9/24 13:20:20

简介

项目中大部分情况下都是使用MySQL数据,而且主要使用的数据库类型是char、varchar、date、datetime、timestamp、int、tinyint等几种常见的数据类型;而且进行表设计时,一般都要出一份表设计文档,例如表设计模板如下

19aeebcc944537b66a410e843b582f7c.png

因为有了如此标准的表设计文档,我们就可以通过解析xlsx生成数据的建表语句。

pom文件引入

主要引入解析xlsx的poi、日志的logback类库

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.table</groupId>
 <artifactId>auto-table</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <properties>
  <maven.compiler.source>8</maven.compiler.source>
  <maven.compiler.target>8</maven.compiler.target>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>
 <dependencies>
  <!-- poi导入导出 -->
  <dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>4.1.2</version>
  </dependency>
  <dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml</artifactId>
   <version>4.1.2</version>
  </dependency>
  <dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml-schemas</artifactId>
   <version>4.1.2</version>
  </dependency>
  <dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-lang3</artifactId>
   <version>3.12.0</version>
  </dependency>
  <dependency>
   <groupId>cn.hutool</groupId>
   <artifactId>hutool-all</artifactId>
   <version>5.7.12</version>
  </dependency>
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>1.7.7</version>
  </dependency>
  <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-core</artifactId>
   <version>1.1.7</version>
  </dependency>
  <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-access</artifactId>
   <version>1.1.7</version>
  </dependency>
  <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>1.1.7</version>
  </dependency>
 </dependencies>
</project>

创建表实体和字段实体

表实体对象TableScriptDO

package com.auto.table;

import java.io.Serializable;
import java.util.List;

import cn.hutool.json.JSONUtil;

public class TableScriptDO implements Serializable {
 
 /**
  * 表名
  */
 private String tableName;
 
 /**
  * 表注释
  */
 private String tableComment;
 
 private List<ColumnScriptDO> columnScriptDOs;

 //省略 getter、setter
 
}

字段实体对象ColumnScriptDO

package com.auto.table;

import java.io.Serializable;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;

public class ColumnScriptDO implements Serializable{
 
 /**
  * 列名
  */
 private String columnName;
 
 /**
  * 列注释
  */
 private String columnComment;
 
 /**
  * 主键名,主要有只说明是主键
  */
 private String primaryKeyName;

 /**
  * 是否自增
  */
 private boolean autoIncrease = false;
 
 /**
  * 字段类型
  */
 private String type;
 
 /**
  * 字段长度
  */
 private String length;
 
 /**
  * 是否可以为空,不能为空
  */
 private boolean canNull = false;
 
 /**
  * 默认值
  */
 private String defaultValue = "";

  //省略 getter、setter
}

解析电子表格xlsx

主要使用poi的接口解析表结构设计文档

package com.auto.table;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;

import cn.hutool.core.collection.CollUtil;

public class AutoTableXlsxUtils {

 private static final Logger log = LoggerFactory.getLogger(AutoTableXlsxUtils.class);

 /**
  * 获取workbook
  * 
  * @param fileName
  * @return
  * @throws IOException
  */
 public static XSSFWorkbook getXSSFWorkbook(String fileName) throws IOException {
  URL url = AutoTableMain.class.getClassLoader().getResource(fileName);
  InputStream input = url.openStream();
  // 读取后缀为“xlsx”的excel文件代码 (“xls”不适用,“xls”得用 HSSFWorkbook)
  XSSFWorkbook wb = new XSSFWorkbook(input);
  return wb;
 }

 /**
  * 获取table脚本对象
  * 
  * @param wb
  * @return
  */
 public static List<TableScriptDO> getTableScript(XSSFWorkbook wb) {
  List<TableScriptDO> list = new ArrayList<>();
  int sheetCount = wb.getNumberOfSheets();
  for (int i = 0; i < sheetCount; i++) {
   XSSFSheet sheet = wb.getSheetAt(i);
   TableScriptDO tableScriptDO = buildTableScriptFromSheet(sheet);
   if (tableScriptDO == null) {
    continue;
   }
   list.add(tableScriptDO);
  }
  return list;
 }

 /**
  * 
  * @param sheet
  * @return
  */
 private static TableScriptDO buildTableScriptFromSheet(XSSFSheet sheet) {
  if ("目录".equals(sheet.getSheetName())) {
   return null;
  }
  // 获取表名
  XSSFRow tableNameRow = sheet.getRow(1);
  XSSFCell tableNameCell = tableNameRow.getCell(2);
  String tableName = tableNameCell.getStringCellValue();
  if (StringUtils.isEmpty(tableName)) {
   return null;
  }
  TableScriptDO tableScriptDO = new TableScriptDO();
  tableScriptDO.setTableName(tableName);
  // 获取表注释
  XSSFRow tableCommentRow = sheet.getRow(2);
  XSSFCell tableCommentCell = tableCommentRow.getCell(0);
  String tableComment = tableCommentCell.getStringCellValue();
  if (StringUtils.isEmpty(tableComment)) {
   tableComment = sheet.getSheetName();
  }
  tableScriptDO.setTableComment(tableComment);
  List<ColumnScriptDO> columnScriptDOs = processColumnScript(sheet);
  if (CollUtil.isEmpty(columnScriptDOs)) {
   return null;
  }
  tableScriptDO.setColumnScriptDOs(columnScriptDOs);
  return tableScriptDO;
 }

 private static List<ColumnScriptDO> processColumnScript(XSSFSheet sheet) {
  int lastRowNum = sheet.getLastRowNum()+1;
  List<ColumnScriptDO> list = new ArrayList<>();
  for (int startRowNum = 4; startRowNum < lastRowNum; startRowNum++) {
   XSSFRow columnRow = sheet.getRow(startRowNum);
   XSSFCell columnNameCell = columnRow.getCell(1);
   XSSFCell columnCommentCell = columnRow.getCell(2);
   XSSFCell primaryKeyNameCell = columnRow.getCell(3);
   XSSFCell autoIncreaseCell = columnRow.getCell(4);
   XSSFCell typeCell = columnRow.getCell(5);
   XSSFCell lengthCell = columnRow.getCell(6);
   XSSFCell canNullCell = columnRow.getCell(7);
   XSSFCell defaultValueCell = columnRow.getCell(8);

   ColumnScriptDO columnScriptDO = new ColumnScriptDO();
   // 字段名
   String columnName = columnNameCell.getStringCellValue();
   if (StringUtils.isEmpty(columnName)) {
    log.info("columnName is empty");
    continue;
   }
   columnScriptDO.setColumnName(columnName.toLowerCase());
   // 字段注释
   columnScriptDO.setColumnComment(columnCommentCell.getStringCellValue());
   // 是否主键
   String primaryKeyName = primaryKeyNameCell.getStringCellValue();
   if (StringUtils.isNotEmpty(primaryKeyName)) {
    primaryKeyName = primaryKeyName.trim().toLowerCase();
   }
   columnScriptDO.setPrimaryKeyName(primaryKeyName);
   // 是否自增
   String autoIncrease = autoIncreaseCell.getStringCellValue();
   if (StringUtils.isNotEmpty(autoIncrease) && "y".equals(autoIncrease.trim().toLowerCase())) {
    columnScriptDO.setAutoIncrease(true);
   }
   // 字段类型
   String type = typeCell.getStringCellValue();
   if (!checkTypeVaild(type)) {
    log.info("type is not vaild");
    continue;
   }
   columnScriptDO.setType(type.trim().toLowerCase());
   // 长度
   String length = getCellValue(lengthCell);
   if (StringUtils.isEmpty(length)) {
    length = "";
   }
   length = length.trim();
   columnScriptDO.setLength(length);
   // 是否可以为空
   String canNull = canNullCell.getStringCellValue();
   if (StringUtils.isNotEmpty(canNull) && "y".equals(canNull.trim().toLowerCase())) {
    columnScriptDO.setCanNull(true);
   }
   // 默认值
   String defaultValue = getCellValue(defaultValueCell);
   if (StringUtils.isEmpty(defaultValue)) {
    defaultValue = "";
   }
   defaultValue = defaultValue.trim();
   columnScriptDO.setDefaultValue(defaultValue);

   list.add(columnScriptDO);
  }
  return list;
 }

 private static boolean checkTypeVaild(String type) {
  if (StringUtils.isEmpty(type)) {
   return false;
  }
  // TODO 其他类型判断

  return true;
 }

 public static String getCellValue(Cell cell) {
  String cellValue = "";
  if (cell == null) {
   return cellValue;
  }
  // 把数字当成String来读,避免出现1读成1.0的情况
  if (cell.getCellType() == CellType.NUMERIC) {
   cell.setCellType(CellType.STRING);
  }
  // 判断数据的类型
  switch (cell.getCellType()) {
  case NUMERIC: // 数字
   cellValue = String.valueOf(cell.getNumericCellValue());
   break;
  case STRING: // 字符串
   cellValue = String.valueOf(cell.getStringCellValue());
   break;
  case BOOLEAN: // Boolean
   cellValue = String.valueOf(cell.getBooleanCellValue());
   break;
  case FORMULA: // 公式
   cellValue = String.valueOf(cell.getCellFormula());
   break;
  case BLANK: // 空值
   cellValue = "";
   break;
  case ERROR: // 故障
   cellValue = "非法字符";
   break;
  default:
   cellValue = "未知类型";
   break;
  }
  return cellValue;
 }

}

生成MySQL建表DDL语句

通过解析xlsx后得到表实体对象TableScriptDO字段实体对象ColumnScriptDO

package com.auto.table;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;

public class AutoTableScriptGenerator {

 private static final Logger log = LoggerFactory.getLogger(AutoTableScriptGenerator.class);

 private static String DROP_TABLE = "DROP TABLE IF EXISTS %s;\n";
 
 /**
  * 前缀
  */
 private static String TABLE_PREFIX = "CREATE TABLE `%s` (\n";

 /**
  * 后缀
  */
 private static String SUFFIX_PREFIX = ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='%s';\n";
 
 public static void geneateScript(List<TableScriptDO> list, String sqlFileName) {
  if(CollUtil.isEmpty(list)) {
   return;
  }
  if(sqlFileName==null) {
   sqlFileName = "gen.sql";
  }
  if(!sqlFileName.toLowerCase().endsWith(".sql")) {
   sqlFileName = sqlFileName + ".sql";
  }
  List<String> tableScriptList = new ArrayList<>();
  for(int i=0; i<list.size(); i++) {
   TableScriptDO tableScriptDO = list.get(i);
   String tableScript = String.format(DROP_TABLE, tableScriptDO.getTableName());
   List<ColumnScriptDO> tableScriptDOs = tableScriptDO.getColumnScriptDOs();
   if(CollUtil.isEmpty(tableScriptDOs)) {
    continue;
   }
   
   String tableCreateScript = String.format(TABLE_PREFIX, tableScriptDO.getTableName());
   tableScript = tableScript + tableCreateScript;
   
   //处理中间的sql脚本生成
   List<ColumnScriptDO> columnScriptDOs = tableScriptDO.getColumnScriptDOs();
   if(CollUtil.isEmpty(columnScriptDOs)) {
    continue;
   }
   //所有字段
   String columns = "";
   String primaryKeyColumn = "";
   for(ColumnScriptDO columnScriptDO : columnScriptDOs) {
    StringBuffer columnScript = new StringBuffer();
    //字段名称
    columnScript.append("    `");
    columnScript.append(columnScriptDO.getColumnName().toLowerCase());
    columnScript.append("` ");
    
    //字段类型
    columnScript.append(columnScriptDO.getType().toUpperCase());
    //字段长度
    if(StringUtils.isNotEmpty(columnScriptDO.getLength()) && checkNeedAddLen(columnScriptDO.getType().toLowerCase())) {
     columnScript.append("(");
     columnScript.append(columnScriptDO.getLength().trim());
     columnScript.append(")");
    }
    
    if(!columnScriptDO.isCanNull()) {
     columnScript.append(" NOT NULL ");
    }
    
    if(columnScriptDO.getDefaultValue()==null) {
     columnScript.append(" DEFAULT '" + columnScriptDO.getDefaultValue() + "' ");
    }else {
     if(columnScriptDO.isCanNull()) {
      columnScript.append(" DEFAULT NULL ");  
     }
    }
    
    if(columnScriptDO.isAutoIncrease()) {
     columnScript.append(" AUTO_INCREMENT "); 
    }
    
    //字段注释
    if(StringUtils.isEmpty(columnScriptDO.getColumnComment())) {
     columnScript.append(",\n");
    }else {
     columnScript.append("COMMENT '");
     columnScript.append(columnScriptDO.getColumnComment());
     columnScript.append("',\n");
    }
    columns = columns + columnScript.toString();
    
    if(StringUtils.isNotEmpty(columnScriptDO.getPrimaryKeyName())) {
     primaryKeyColumn = columnScriptDO.getColumnName();
    }
   }
   tableScript = tableScript + columns;
   
   if(primaryKeyColumn!=null) {
    String primaryKeyScript = "    PRIMARY KEY (`" + primaryKeyColumn + "`)\n";
    tableScript = tableScript + primaryKeyScript;
   }else {
    tableScript = tableScript.substring(0, tableScript.length()-1);
   }
   
   String tableCommentScript = String.format(SUFFIX_PREFIX, tableScriptDO.getTableComment());
   tableScript = tableScript + tableCommentScript + "\n\n";
   tableScriptList.add(tableScript);
  }
  String allScript = "";
  for( String tableScript : tableScriptList) {
   allScript = allScript + tableScript;
  }
  File file = FileUtil.writeBytes(allScript.getBytes(), sqlFileName);
  log.info(file.getAbsolutePath());
  System.out.println(allScript);
 }

 /**
  * 检查是否需要添加长度
  * 
  * @param columnType
  * @return
  */
 private static boolean checkNeedAddLen(String columnType) {
  List<String> type = Arrays.asList(new String[] {"date", 
    "datetime", 
    "text", 
    "timestamp", 
    "json"});
  if(type.contains(columnType)) {
   return false;
  }
  return true;
 }

}

测试生成DDL语句

try {
   XSSFWorkbook wb = AutoTableXlsxUtils.getXSSFWorkbook("Car-Custom_v2.0.xlsx");
   AutoTableScriptGenerator.geneateScript(AutoTableXlsxUtils.getTableScript(wb), "gen.sql");
  } catch (Exception e) {
   e.printStackTrace();
  }

可以解决90%的MySQL的建表语句生成,源码如下

https://gitee.com/hjj520/springcloud-learn/tree/master/auto-table

2e8479463fdc1a79d2646e9a14cf0ff2.gif

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

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

相关文章

[附源码]Nodejs计算机毕业设计基于移动端的药方收集系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

【Spring】一文带你吃透IOC容器技术

目录 一、前言 二、IOC容器技术 1、ioc概念 2、DI依赖注入 2.1、构造注入依赖 2.2、setter注入依赖 3、ioc底层实现 4、基于xml配置声明Bean以及使用 4.1、根节点标签beans 4.2、声明Bean 4.3、Bean的使用 5、面向接口编程 5.1、新增接口IOrderService 5.2、Order…

非零基础自学Golang 第11章 文件操作 11.2 文件基本操作 11.2.2 文件读取

非零基础自学Golang 文章目录非零基础自学Golang第11章 文件操作11.2 文件基本操作11.2.2 文件读取第11章 文件操作 11.2 文件基本操作 11.2.2 文件读取 想要读取文件可以使用os库中的Read接口&#xff1a; func (f &#xff0a;File) Read(b []byte) (n int, err error)Re…

RCNN网络源码解读(Ⅳ) --- 训练SVM二分类模型的准备过程

目录 1.回忆上一讲及本讲我们要做什么 2.回顾finetune是怎么训练的&#xff08;finetune.py&#xff09; 3. 训练SVM二分类模型 &#xff08;linear_svm.py&#xff09; 3.1 load_data 3.2 custom_classifier_dataset.py 3.3 custom_batch_sampler.py 3.4 hinge_loss 1…

python制作问题搜索解答器,从此学习无忧

前言 大家早好、午好、晚好吖 ❤ ~ 今天博主给大家带来一个问题搜索解答器&#xff01;&#xff01; 需要素材 以及一双慧手和一个灵活的脑子~ 效果展示 代码展示 导入模块 import requests import tkinter as tk from tkinter import ttk import webbrowserdef search(wor…

北京车牌那么难摇为什么还能那么受欢迎?

在北京生活的人来说一块北京车牌真的影响正常生活&#xff0c;特别是这两年的疫情反复...&#xff0c;面对房贷房租&#xff0c;衣食住行&#xff0c;就算外面世界再纷纷扰扰&#xff0c;也要面对...所以在北京生活没有一辆北京车牌汽车真的很麻烦。 对于在北京生活的人来说就…

【C语言刷题】PTA基础编程题目集精选

作者&#xff1a;匿名者Unit 专栏&#xff1a; 《C语言刷题》 目录题目精选6-7 统计某类完全平方数6-9 统计个位数字6-10 阶乘计算升级版6-11 求自定类型元素序列的中位数题目精选 6-7 统计某类完全平方数 我们先看一下题目要求&#xff1a; 根据题目给出的要求&#xff1a…

瑞格科技IPO被终止:曾拟募资5.6亿 江振翔三兄弟为实控人

雷递网 雷建平 12月17日浙江瑞格智能科技股份有限公司&#xff08;简称&#xff1a;“瑞格科技”&#xff09;日前IPO被终止。瑞格科技计划募资5.59亿元&#xff0c;其中&#xff0c;2.55亿元用于年产1000万套汽车配件技改项目&#xff0c;9240万元用于年产500万件智能传感器及…

css深度选择器deep

1.为什么要有deep 1.当我们给组件设置scoped的时候&#xff0c;此时我们组件的css样式只会对自己的内容生效&#xff0c;不会对子组件里面的内容生效。 <style lang"scss" scoped> .login-page {min-height: 100vh;background: url(/assets/login-bg.svg) no-r…

大脑网络的图论分析

利用图论测量大脑结构和功能网络的四个步骤: 定义网络节点——在脑电研究中&#xff0c;电极天然形成节点&#xff1b;在磁共振研究中&#xff0c;可以使用不同的脑图谱作为节点或者基于体素水平进行研究估计节点之间的连接性——结构上&#xff0c;可以由DTI计算两个脑区之间…

一文深度剖析扩散模型究竟学到了什么?

Title: <Diffusion Art or Digital Forgery? Investigating Data Replication in Diffusion Models> Paper: https://arxiv.org/pdf/2212.03860.pdf Github: Just get the point. 文章目录导读技术提升动机贡献背景图像检索与复制检测深度学习中的记忆语言模型中的记忆扩…

Linux Qt连接达梦数据库

最近因为工作需要&#xff0c;需要使用Qt连接达梦数据库&#xff0c;在Linux上比较麻烦&#xff0c;首先需要自己编译UnixODBC和Qt的QODBC库&#xff0c;其次还有各种环境配置。这里在安装好后记录一下&#xff0c;以后找起来方便。 先说下我的电脑是麒麟V10系统飞腾的CPU&…

共享SimpleDateFormat的并发问题

1、问题提出 梳理订单逻辑时发现对日期格式进行format的代码有如下写法 OneDateUtil中定义了一个全局static的SimpleDateFormat对象。SimpleDateFormat对象不是线程安全的&#xff0c;在多线程环境下容易造成数据转换和处理错误。 2、为什么SimpleDateFormat线程不安全 Sim…

[附源码]Node.js计算机毕业设计红色景点自驾游网站管理系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

MySQL~索引

7、索引 MySQL官方对索引的定义为&#xff1a;索引&#xff08;Index&#xff09;是帮助MySQL高效获取数据的数据结构。 提取句子主干&#xff0c;就可以得到索引的本质&#xff1a;索引是数据结构。 7.1、索引的分类 在一个表中&#xff0c;主键索引只能有一个&#xff0c;唯一…

微机原理与接口技术笔记(持续更新)

文章目录前言储存系统与技术材料高速储存器缓冲储存器&#xff08;Cache&#xff09;材料&#xff0c;局部性&#xff0c;访问方式Cache全相联映射Cache交换与一致性单核CPU一致性处理多核CPU的MESI协议主储存器&#xff08;内存&#xff09;主要技术指标容量带宽内存模组与内存…

机器学习100天(九):009 多项式回归理论

机器学习100天,今天讲的是:多项式回归理论! 在前两期视频我们讲解了简单线性回归理论,并解决了一个房价预测的问题,建立了一个房价与地区人口的线性关系。然而,如果数据的分布不是简单的线性关系,又该怎么做呢? 一、多项式回归 我们来看一个例子,在这个二维平面上,…

【蓝桥杯】砝码称重

3417. 砝码称重 - AcWing题库 题意&#xff1a; 思路回顾&#xff1a; 首先这道题一开始我没想用DP做&#xff0c;看到标签是入门题就没想DP qwq 其实这就是一个普通背包 一开始设计状态设计不出来&#xff0c;刚开始设的是dp[i][j]表示前i个物品能表示j种重量 显然是不行…

计算机毕业设计django基于python商品比价平台

项目介绍 随着计算机技术的发展和网络的普及。采用当前流行的B/S模式以及3层架构的设计思想通过Python技术来开发此系统的目的是建立一个配合网络环境的商品比价系统的平台,这样可以有效地解决数据商品比价系统混乱的局面。 本文首先介绍了商品比价系统的发展背景与发展现状,…

年后面试,给你提6点建议!

你好&#xff0c;我是田哥转眼年底&#xff0c;很大部分人都在观望&#xff0c;甚至已经开始着手准备明年的面试了&#xff0c;不知道屏幕前的你是如何打算的&#xff1f;从现在开始&#xff0c;到明年三月份还有两个多月的时间&#xff0c;时间不多&#xff0c;但也不少了。只…