MyBatis-Plus Generator v2.0.8 ~ v3.1.1 最新代码自动生成器

一、概述

官网:https://baomidou.com/

官方文档 :https://baomidou.com/pages/56bac0/

官方源码地址: https://gitee.com/baomidou/mybatis-plus

官方原话:

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成
Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

配置环境

  • 开发工具 IDEA
  • JDK 8 +
  • 数据库 Mysql 、Oracle …
  • 基于SpringBoot开发框架

特性

  • 无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性
  • 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring
  • 损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作
  • 预防Sql注入:内置Sql注入剥离器,有效预防Sql注入攻击
  • 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
  • 支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
  • 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Entity、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 支持关键词自动转义:支持数据库关键词(order、key……)自动转义,还可自定义关键词
  • 内置分页插件:基于Mybatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询
  • 内置性能分析插件:可输出Sql语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作

二、配置说明

2.1 、基本配置

属性类型说明
dataSourceDataSourceConfig数据源配置,通过该配置,指定需要生成代码的具体数据库,具体请查看 数据源配置
strategyStrategyConfig数据库表配置,通过该配置,可指定需要生成哪些表或者排除哪些表,具体请查看 数据库表配置
packageInfoPackageConfig包名配置,通过该配置,指定生成代码的包路径,具体请查看 包名配置
templateTemplateConfig模板配置,可自定义代码生成的模板,实现个性化操作,具体请查看 模板配置
globalConfigGlobalConfig全局策略配置,具体请查看 全局策略配置
injectionConfigInjectionConfig注入配置,通过该配置,可注入自定义参数等操作以实现个性化操作,具体请查看 注入配置

2.2 数据库配置(DataSourceConfig)

可选配置

方法说明示例 / 参数
dbQuery(IDbQuery)数据库查询new MySqlQuery()
schema(String)数据库schema(部分数据库适用) mybatis-plus
typeConvert(ITypeConvert)数据库类型转换器new MySqlTypeConvert()
dbType数据库类型,该类内置了常用的数据库类型【必须】DbType.MYSQL
driverName驱动名称com.mysql.jdbc.Driver
urljdbc路径jdbc:mysql://localhost:3306/(数据库名称)
username数据库账号root
password数据库密码123456
		Properties props = getProperties();
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setDbType(DbType.MYSQL);
		dsc.setTypeConvert(new MySqlTypeConvert());
		dsc.setDriverName("com.mysql.jdbc.Driver");
		dsc.setUsername(props.getProperty("db.master.user"));
		dsc.setPassword(props.getProperty("db.master.password"));
		dsc.setUrl(props.getProperty("db.master.url"));
		mpg.setDataSource(dsc);

2.3 全局配置(GlobalConfig)

方法说明示例 / 参数
outputDir生成文件的输出目录默认值:D 盘根目录
fileOverride是否覆盖已有文件默认值:false
open是否打开输出目录默认值:true
enableCache是否在 xml 中添加二级缓存配置默认值:`false
author开发人员默认值:null
kotlin开启 Kotlin 模式默认值:false
swagger2开启 swagger2 模式默认值:false
activeRecord开启 ActiveRecord 模式默认值:false
baseResultMap开启 BaseResultMap默认值:false
baseColumnList开启 baseColumnList默认值:false
dateType时间类型对应策略默认值:TIME_PACK 注意事项: 如下配置 %s 为占位符
entityName实体命名方式默认值:null 例如:%sEntity 生成 UserEntity
mapperNamemapper 命名方式默认值:null 例如:%sDao 生成 UserDao
xmlNameMapper xml 命名方式默认值:null 例如:%sDao 生成 UserDao.xml
serviceNameservice 命名方式默认值:null 例如:%sBusiness 生成 UserBusiness
serviceImplNameservice impl 命名方式默认值:null 例如:%sBusinessImpl 生成 UserBusinessImpl
controllerNamecontroller 命名方式默认值:null 例如:%sAction 生成 UserAction
idType指定生成的主键的 ID 类型默认值:null
		// 全局配置
		GlobalConfig gc = new GlobalConfig();
		gc.setOutputDir(outputDir);
		gc.setFileOverride(true);
		gc.setActiveRecord(true);// 开启 activeRecord 模式
		gc.setEnableCache(false);// XML 二级缓存
		gc.setBaseResultMap(true);// XML ResultMap
		gc.setBaseColumnList(false);// XML columList
		gc.setAuthor("zhixuan.wang");

		// 自定义文件命名,注意 %s 会自动填充表实体属性!
		gc.setMapperName("%sMapper");
		gc.setXmlName("%sMapper");
		gc.setServiceName("I%sService");
		gc.setServiceImplName("%sServiceImpl");
		gc.setControllerName("%sController");
		mpg.setGlobalConfig(gc);

2.4 包配置(PackageConfig)

方法说明示例 / 参数
parent(String)父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名
moduleName(String)父包模块名默认值:无
entity(String)实体类 Entity 包名默认值:entity
service(String)Service 包名默认值:service
serviceImpl(String)实现类 Service Impl 包名默认值:service.impl
mapper(String)Mapper 包名默认值:mapper
xmlMapper XML 包名默认值:mapper.xml
controllerController 包名默认值:controller
pathInfo(Map<OutputFile, String>)路径配置信息Collections.singletonMap(OutputFile.mapperXml, “D://”)
		// 包配置
		PackageConfig pc = new PackageConfig();
		pc.setModuleName(null);  //所属模块
		pc.setParent("com.wangzhixuan"); // 自定义包路径
		pc.setController("controller"); // 这里是控制器包名,默认 web
		pc.setEntity("model");
		pc.setXml("sqlMapperXml");
		mpg.setPackageInfo(pc);

2.5 模板配置(TemplateConfig)

方法说明示例 / 参数
entity(String)设置实体模板路径(JAVA)/templates/entity.java
entityKt(String)设置实体模板路径(kotlin)/templates/entity.java
service(String)设置 service 模板路径/templates/service.java
serviceImpl(String)设置 serviceImpl 模板路径/templates/serviceImpl.java
mapper(String)设置 mapper 模板路径/templates/mapper.java
xml(String)设置 mapperXml 模板路径/templates/mapper.xml
controller(String)设置 controller 模板路径/templates/controller.java
		//初始化模板配置
		TemplateConfig templateConfig = new TemplateConfig();
		templateConfig.setController("/templates/controller.java.vm");
		templateConfig.setEntity("/templates/controller.java.vm");
		templateConfig.setXml("/templates/sqlMapperXml.xml.vm");
		templateConfig.setMapper("/templates/mapper.java.vm");
		templateConfig.setService("/templates/service.java.vm");
		templateConfig.setServiceImpl("/templates/serviceImpl.java.vm");
		

MyBatis-Plus 原生默认模板:

在这里插入图片描述

2.6 注入配置(InjectionConfig)

方法说明示例 / 参数
map自定义返回配置 Map 对象该对象可以传递到模板引擎通过 cfg.xxx 引用
fileOutConfigList自定义输出文件配置 FileOutConfig 指定模板文件、输出文件达到自定义文件生成目的
fileCreate自定义判断是否创建文件 实现 IFileCreate 接口该配置用于判断某个类是否需要覆盖创建,当然你可以自己实现差异算法 merge 文件
initMap注入自定义 Map 对象(注意需要 setMap 放进去)
		// 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {}
		};
		// 生成的模版路径,不存在时需要先新建
		File viewDir = new File(viewOutputDir);
		if (!viewDir.exists()) {
			viewDir.mkdirs();
		}
		List<FileOutConfig> focList = new ArrayList<FileOutConfig>();
		focList.add(new FileOutConfig("/templates/add.jsp.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getGeneratorViewPath(viewOutputDir, tableInfo, "Add.jsp");
			}
		});
		focList.add(new FileOutConfig("/templates/edit.jsp.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getGeneratorViewPath(viewOutputDir, tableInfo, "Edit.jsp");
			}
		});
		focList.add(new FileOutConfig("/templates/list.jsp.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getGeneratorViewPath(viewOutputDir, tableInfo, "List.jsp");
			}
		});
		cfg.setFileOutConfigList(focList);
		mpg.setCfg(cfg);
		

在这里插入图片描述

2.7 策略配置(StrategyConfig)

方法说明示例 / 参数
isCapitalMode是否大写命名
skipView是否跳过视图
naming数据库表映射到实体的命名策略
columnNaming数据库表字段映射到实体的命名策略, 未指定按照 naming 执行
tablePrefix表前缀
fieldPrefix字段前缀
superEntityClass自定义继承的 Entity 类全称,带包名
superEntityColumns自定义基础的 Entity 类,公共字段
superMapperClass自定义继承的 Mapper 类全称,带包名
superServiceClass自定义继承的 Service 类全称,带包名
superServiceImplClass自定义继承的 ServiceImpl 类全称,带包名
superControllerClass自定义继承的 Controller 类全称,带包名
enableSqlFilter(since 3.3.1)默认激活进行 sql 模糊表名匹配关闭之后 likeTable 与 notLikeTable 将失效,include 和 exclude 将使用内存过滤 ,如果有 sql 语法兼容性问题的话,请手动设置为 false
include需要包含的表名,当 enableSqlFilter 为 false 时,允许正则表达式(与 exclude 二选一配置)
likeTable自 3.3.0 起,模糊匹配表名(与 notLikeTable 二选一配置)
exclude需要排除的表名,当 enableSqlFilter 为 false 时,允许正则表达式
notLikeTable自 3.3.0 起,模糊排除表名
entityColumnConstant【实体】是否生成字段常量(默认 false)
entityBuilderModel【实体】是否为构建者模型(默认 false),自 3.3.2 开始更名为 chainModel
chainModel(since 3.3.2)【实体】是否为链式模型(默认 false)
entityLombokModel【实体】是否为 lombok 模型(默认 false)3.3.2 以下版本默认生成了链式模型,3.3.2 以后,默认不生成,如有需要,请开启 chainModel
entityBooleanColumnRemoveIsPrefixBoolean 类型字段是否移除 is 前缀(默认 false)
restControllerStyle生成 @RestController 控制器
controllerMappingHyphenStyle驼峰转连字符
entityTableFieldAnnotationEnable是否生成实体时,生成字段注解
versionFieldName乐观锁属性名称
logicDeleteFieldName逻辑删除属性名称
tableFillList表填充字段
		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		// strategy.setCapitalMode(true);// 全局大写命名
		// strategy.setDbColumnUnderline(true);//全局下划线命名
//		strategy.setTablePrefix(new String[] { "bmd_", "mp_" });// 此处可以修改为您的表前缀
		strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
		// strategy.setInclude(new String[] { "user" }); // 需要生成的表
		// strategy.setExclude(new String[]{"test"}); // 排除生成的表
		// 自定义实体父类
		// strategy.setSuperEntityClass("com.baomidou.demo.TestEntity");
		// 自定义实体,公共字段
		// strategy.setSuperEntityColumns(new String[] { "test_id", "age" });
		// 自定义 mapper 父类
		// strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
		// 自定义 service 父类
		// strategy.setSuperServiceClass("com.baomidou.demo.TestService");
		// 自定义 service 实现类父类
		// strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");
		// 自定义 controller 父类
		strategy.setSuperControllerClass("com.wangzhixuan.commons.base.BaseController");
		// 【实体】是否生成字段常量(默认 false)
		// public static final String ID = "test_id";
		// strategy.setEntityColumnConstant(true);
		// 【实体】是否为构建者模型(默认 false)
		// public User setName(String name) {this.name = name; return this;}
		// strategy.setEntityBuliderModel(true);
		mpg.setStrategy(strategy);

注意 : 使用时,先看清楚归于哪一类的配置,避免出现找不到的情况!

三、MyBatis-Plus Generator

2.1、导入依赖

<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 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.wangzhixuan</groupId>
	<artifactId>school-management</artifactId>
	<packaging>war</packaging>
	<version>1.3.0</version>
	<name>school-management</name>
	<url>http://demo.dreamlu.net</url>

	<properties>
		<project.build.sourceEncoding>utf-8</project.build.sourceEncoding>
		<jdk.version>1.7</jdk.version>
		<junit.version>4.12</junit.version>
		<servlet.version>3.0.1</servlet.version>
		<log4j2.version>2.8.2</log4j2.version>
		<spring.version>4.3.8.RELEASE</spring.version>
		<mybaitsplus.version>2.0.8</mybaitsplus.version>
		<mysql.version>5.1.40</mysql.version>
		<druid.version>1.0.29</druid.version>
		<shiro.version>1.3.2</shiro.version>
		<ehcache.version>2.6.11</ehcache.version>
		<jackson.version>2.8.8</jackson.version>
		<commons-io.version>2.5</commons-io.version>
		<hibernate-validator.version>5.3.5.Final</hibernate-validator.version>
		<poi.version>3.16</poi.version>
	</properties>

	<dependencies>
		<!-- Spring begin -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>4.3.8.RELEASE</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.3.8.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>4.3.8.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>4.3.8.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>4.3.8.RELEASE</version>
		</dependency>
		<!-- spring end -->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>${commons-io.version}</version>
		</dependency>
		<!--Mybatis-Plus-->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus</artifactId>
			<version>${mybaitsplus.version}</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>${druid.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.velocity</groupId>
			<artifactId>velocity</artifactId>
			<version>1.7</version>
		</dependency>
	</dependencies>


	<!-- 使用aliyun镜像 -->
	<repositories>
		<repository>
			<id>aliyun</id>
			<name>aliyun</name>
			<url>http://maven.aliyun.com/nexus/content/groups/public</url>
		</repository>
	</repositories>

</project>

2.2、运行类(放在测试类中即可)

package com.wangzhixuan.generator;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.toolkit.StringUtils;

/**
 * <p>
 * 代码生成器演示
 * </p>
 * 
 * @author goujiatao
 * @date 2016-12-01
 */
public class MysqlGenerator {

	/**
	 * <p>
	 * MySQL 生成演示
	 * </p>
	 */
	public static void main(String[] args) {
		/* 获取 JDBC 配置文件 */
		Properties props = getProperties();
		AutoGenerator mpg = new AutoGenerator();

		//String outputDir = "/Users/lcm/Desktop/generator/code";
		String outputDir = "C:/Users/Administrator/Desktop/新建文件夹";
		final String viewOutputDir = outputDir + "/view/";
		
		// 全局配置
		GlobalConfig gc = new GlobalConfig();
		gc.setOutputDir(outputDir);
		gc.setFileOverride(true);
		gc.setActiveRecord(true);// 开启 activeRecord 模式
		gc.setEnableCache(false);// XML 二级缓存
		gc.setBaseResultMap(true);// XML ResultMap
		gc.setBaseColumnList(false);// XML columList
		gc.setAuthor("zhixuan.wang");

		// 自定义文件命名,注意 %s 会自动填充表实体属性!
		gc.setMapperName("%sMapper");
		gc.setXmlName("%sMapper");
		gc.setServiceName("I%sService");
		gc.setServiceImplName("%sServiceImpl");
		gc.setControllerName("%sController");
		mpg.setGlobalConfig(gc);

		// 数据源配置
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setDbType(DbType.MYSQL);
		dsc.setTypeConvert(new MySqlTypeConvert());
		dsc.setDriverName("com.mysql.jdbc.Driver");
		dsc.setUsername(props.getProperty("db.master.user"));
		dsc.setPassword(props.getProperty("db.master.password"));
		dsc.setUrl(props.getProperty("db.master.url"));
		mpg.setDataSource(dsc);

		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		// strategy.setCapitalMode(true);// 全局大写命名
		// strategy.setDbColumnUnderline(true);//全局下划线命名
//		strategy.setTablePrefix(new String[] { "bmd_", "mp_" });// 此处可以修改为您的表前缀
		strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略
		// strategy.setInclude(new String[] { "user" }); // 需要生成的表
		// strategy.setExclude(new String[]{"test"}); // 排除生成的表
		// 自定义实体父类
		// strategy.setSuperEntityClass("com.baomidou.demo.TestEntity");
		// 自定义实体,公共字段
		// strategy.setSuperEntityColumns(new String[] { "test_id", "age" });
		// 自定义 mapper 父类
		// strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
		// 自定义 service 父类
		// strategy.setSuperServiceClass("com.baomidou.demo.TestService");
		// 自定义 service 实现类父类
		// strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");
		// 自定义 controller 父类
		strategy.setSuperControllerClass("com.wangzhixuan.commons.base.BaseController");
		// 【实体】是否生成字段常量(默认 false)
		// public static final String ID = "test_id";
		// strategy.setEntityColumnConstant(true);
		// 【实体】是否为构建者模型(默认 false)
		// public User setName(String name) {this.name = name; return this;}
		// strategy.setEntityBuliderModel(true);
		mpg.setStrategy(strategy);

		// 包配置
		PackageConfig pc = new PackageConfig();
		pc.setModuleName(null);  //所属模块
		pc.setParent("com.wangzhixuan"); // 自定义包路径
		pc.setController("controller"); // 这里是控制器包名,默认 web
		pc.setEntity("model");
		pc.setXml("sqlMapperXml");
		mpg.setPackageInfo(pc);

		// 注入自定义配置,可以在 VM 中使用 cfg.abc 设置的值
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {}
		};
		// 生成的模版路径,不存在时需要先新建
		File viewDir = new File(viewOutputDir);
		if (!viewDir.exists()) {
			viewDir.mkdirs();
		}
		List<FileOutConfig> focList = new ArrayList<FileOutConfig>();
		focList.add(new FileOutConfig("/templates/add.jsp.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getGeneratorViewPath(viewOutputDir, tableInfo, "Add.jsp");
			}
		});
		focList.add(new FileOutConfig("/templates/edit.jsp.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getGeneratorViewPath(viewOutputDir, tableInfo, "Edit.jsp");
			}
		});
		focList.add(new FileOutConfig("/templates/list.jsp.vm") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				return getGeneratorViewPath(viewOutputDir, tableInfo, "List.jsp");
			}
		});
		cfg.setFileOutConfigList(focList);
		mpg.setCfg(cfg);

		// 执行生成
		mpg.execute();
	}

	/**
	 * 获取配置文件
	 *
	 * @return 配置Props
	 */
	private static Properties getProperties() {
		// 读取配置文件
		Resource resource = new ClassPathResource("/config/application.properties");
		Properties props = new Properties();
		try {
			props = PropertiesLoaderUtils.loadProperties(resource);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return props;
	}
	
	/**
	 * 页面生成的文件名
	 */
	private static String getGeneratorViewPath(String viewOutputDir, TableInfo tableInfo, String suffixPath) {
		String name = StringUtils.firstToLowerCase(tableInfo.getEntityName());
		String path = viewOutputDir + "/" + name + "/" + name + suffixPath;
		File viewDir = new File(path).getParentFile();
		if (!viewDir.exists()) {
			viewDir.mkdirs();
		}
		return path;
	}
}

2.4、运行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT小郭.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值