mybatis-plus使用Velocity格式模板生成代码

第一步 引入所需pom文件

<!--数据库驱动 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<!--lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<!--mybatis-plus -->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.1.0</version>
		</dependency>
		<!-- 代码生成器依赖 -->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-generator</artifactId>
			<version>3.1.0</version>
		</dependency>
		<!--druid数据库连接池 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid-spring-boot-starter</artifactId>
			<version>1.1.10</version>
		</dependency>
		<dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
		<dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
		<!--模版 -->
		<dependency>
			<groupId>org.apache.velocity</groupId>
			<artifactId>velocity</artifactId>
			<version>1.7</version>
		</dependency>
		<!-- 测试 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

第二步 配置application.yml

server:
  port: 8089

#默认使用配置
spring:
  profiles:
    active: dev

#公共配置与profiles选择无关 mapperLocations指的路径是src/main/resources
#公共配置与profiles选择无关
mybatis-plus:
  typeAliasesPackage: com.example.demo
  mapperLocations: classpath:mapper/*.xml

---

#开发配置
spring:
  profiles: dev

  datasource:
    url: jdbc:mysql://ip:port/beadwalletloan?autoReconnect=true&useUnicode=true&zeroDateTimeBehavior=convertToNull&useServerPrepStmts=false&rewriteBatchedStatements=true&serverTimezone=GMT%2B8
    username: username
    password: password
    driverClassName: com.mysql.jdbc.Driver
    # 使用druid数据源
    type: com.alibaba.druid.pool.DruidDataSource
    # 配置获取连接等待超时的时间
    # 下面为连接池的补充设置,应用到上面所有数据源中
    # 初始化大小,最小,最大
    initialSize: 1
    minIdle: 3
    maxActive: 20
    # 配置获取连接等待超时的时间
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 30000
    validationQuery: select 'x'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    # 打开PSCache,并且指定每个连接上PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,slf4j
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    # 合并多个DruidDataSource的监控数据
    useGlobalDataSourceStat: true

第三步 配置数据源

DatasourceConfig.java

package com.example.demo.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;

import lombok.extern.log4j.Log4j2;

@Log4j2
@Configuration
public class DatasourceConfig {
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.username}")
    private String username;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("${spring.datasource.driverClassName}")
    private String driverClassName;
    @Value("${spring.datasource.initialSize}")
    private int initialSize;
    @Value("${spring.datasource.minIdle}")
    private int minIdle;
    @Value("${spring.datasource.maxActive}")
    private int maxActive;
    @Value("${spring.datasource.maxWait}")
    private int maxWait;
    @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;
    @Value("${spring.datasource.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;
    @Value("${spring.datasource.validationQuery}")
    private String validationQuery;
    @Value("${spring.datasource.testWhileIdle}")
    private boolean testWhileIdle;
    @Value("${spring.datasource.testOnBorrow}")
    private boolean testOnBorrow;
    @Value("${spring.datasource.testOnReturn}")
    private boolean testOnReturn;
    @Value("${spring.datasource.poolPreparedStatements}")
    private boolean poolPreparedStatements;
    @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
    private int maxPoolPreparedStatementPerConnectionSize;
    @Value("${spring.datasource.filters}")
    private String filters;
    @Value("${spring.datasource.connectionProperties}")
    private String connectionProperties;
    @Value("${spring.datasource.useGlobalDataSourceStat}")
    private boolean useGlobalDataSourceStat;
    
    @Bean
    @Primary
    public DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();
 
        datasource.setUrl(url);
        datasource.setUsername(username);
        datasource.setPassword(password);   //这里可以做加密处理
        datasource.setDriverClassName(driverClassName);
 
        //configuration
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setPoolPreparedStatements(poolPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        datasource.setUseGlobalDataSourceStat(useGlobalDataSourceStat);
        try {
            datasource.setFilters(filters);
        } catch (SQLException e) {
 
        }
        datasource.setConnectionProperties(connectionProperties);
 
        return datasource;
    }
 
 
    @Bean
    public ServletRegistrationBean druidServlet() {
        log.info("init Druid Servlet Configuration ");
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        // IP白名单
       // servletRegistrationBean.addInitParameter("allow", "192.168.2.25,127.0.0.1");
        // IP黑名单(共同存在时,deny优先于allow)
        //servletRegistrationBean.addInitParameter("deny", "192.168.1.100");
        //控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername", "admin");
        servletRegistrationBean.addInitParameter("loginPassword", "9527");
        //是否能够重置数据 禁用HTML页面上的“Reset All”功能
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }
 
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}

第四步 配置模板

实体类模板 

Entity.java.vm

package ${package}.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
#foreach ($column in $columns)
#if($column.attrType == 'LocalDate')
import java.time.LocalDate;
#break
#end
#end
#foreach ($column in $columns)
#if($column.attrType == 'LocalDateTime')
import java.time.LocalDateTime;
import com.alibaba.fastjson.annotation.JSONField;
#break
#end
#end
import lombok.Data;
/**
 * Module: ${className}.java
 *
 * @author ${author}
 * @since JDK ${jdk}
 * @version ${version}
 * @date ${date}
 * @Descriptions:
 */
@Data
@TableName(value = "${tableName}")
public class ${className}  {
	
#foreach ($column in $columns)
	/** $column.comments */
#if ("id" == $column.attrname)
	@TableId(value = "id", type = IdType.AUTO)
#end 
#if ("createTime" == $column.attrname)
	@TableField(fill = FieldFill.INSERT)
#end 
#if ("updateTime" == $column.attrname)
	@TableField(fill = FieldFill.INSERT_UPDATE)
#end 
#if ("date" == $column.dataType)
	@JSONField(format = "yyyy-MM-dd")
#end 
#if ("datetime" == $column.dataType)
	@JSONField(format = "yyyy-MM-dd HH:mm:ss")
#end 
	private $column.attrType $column.attrname;
#end
}

配置service

Service.java.vm

package ${package}.service;

import ${package}.entity.${className};
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * Module: ${className}.java
 * 
 * @author ${author}
 * @since JDK ${jdk}
 * @version ${version}
 * @date ${date}
 * @Descriptions:
 */
public interface ${className}Service extends IService<${className}> {
}

配置serviceImpl

ServiceImpl.java.vm

package ${package}.service.impl;

import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ${package}.entity.${className};
import ${package}.service.${className}Service;
import ${package}.mapper.${className}Mapper;

/**
 * Module: ${className}.java
 * 
 * @author ${author}
 * @since JDK ${jdk}
 * @version ${version}
 * @date ${date}
 * @Descriptions:
 */
@Service
public class ${className}ServiceImpl extends ServiceImpl<${className}Mapper, ${className}> implements ${className}Service {

}

第五步 配置类型转换

CommonMap.java

package com.example.demo.generator;

import java.util.HashMap;
import java.util.Map;

public class CommonMap {
	/** 状态编码转换 */
	public static Map<String, String> javaTypeMap = new HashMap<String, String>();

	static {
		initJavaTypeMap();
	}

	/**
	 * 返回状态映射
	 */
	public static void initJavaTypeMap() {
		javaTypeMap.put("tinyint", "Integer");
		javaTypeMap.put("smallint", "Integer");
		javaTypeMap.put("mediumint", "Integer");
		javaTypeMap.put("int", "Integer");
		javaTypeMap.put("integer", "integer");
		javaTypeMap.put("bigint", "Long");
		javaTypeMap.put("float", "Float");
		javaTypeMap.put("double", "Double");
		javaTypeMap.put("decimal", "Double");
		// javaTypeMap.put("decimal", "BigDecimal");
		javaTypeMap.put("bit", "Boolean");
		javaTypeMap.put("char", "String");
		javaTypeMap.put("varchar", "String");
		javaTypeMap.put("tinytext", "String");
		javaTypeMap.put("text", "String");
		javaTypeMap.put("mediumtext", "String");
		javaTypeMap.put("longtext", "String");
		javaTypeMap.put("time", "LocalDateTime");
		javaTypeMap.put("date", "LocalDate");
		javaTypeMap.put("datetime", "LocalDateTime");
		javaTypeMap.put("timestamp", "LocalDateTime");

		javaTypeMap.put("tablePrefix", "");// 前缀
		javaTypeMap.put("package", "com.waterelephant.common");//包名
		javaTypeMap.put("author", "yueyiming");//作者
		javaTypeMap.put("jdk", "1.8");
		javaTypeMap.put("version", "1.0");
	}
}

第六步 配置table实体类

TableEntity .java

package com.example.demo.generator;

import java.util.List;

public class TableEntity {
	// 表的名称
	private String tableName;
	// 表的备注
	private String comments;
	// 表的主键
	private ColumnEntity pk;
	// 表的列名(不包含主键)
	private List<ColumnEntity> columns;

	// 类名(第一个字母大写),如:sys_user => SysUser
	private String className;
	// 类名(第一个字母小写),如:sys_user => sysUser
	private String classname;

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public String getComments() {
		return comments;
	}

	public void setComments(String comments) {
		this.comments = comments;
	}

	public ColumnEntity getPk() {
		return pk;
	}

	public void setPk(ColumnEntity pk) {
		this.pk = pk;
	}

	public List<ColumnEntity> getColumns() {
		return columns;
	}

	public void setColumns(List<ColumnEntity> columns) {
		this.columns = columns;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public String getClassname() {
		return classname;
	}

	public void setClassname(String classname) {
		this.classname = classname;
	}
}

第七步 配置Column实体类

ColumnEntity 实体类

package com.example.demo.generator;

public class ColumnEntity {
	// 列名
	private String columnName;
	// 列名类型
	private String dataType;
	// 列名备注
	private String comments;

	// 属性名称(第一个字母大写),如:user_name => UserName
	private String attrName;
	// 属性名称(第一个字母小写),如:user_name => userName
	private String attrname;
	// 属性类型
	private String attrType;
	// auto_increment
	private String extra;

	public String getColumnName() {
		return columnName;
	}

	public void setColumnName(String columnName) {
		this.columnName = columnName;
	}

	public String getDataType() {
		return dataType;
	}

	public void setDataType(String dataType) {
		this.dataType = dataType;
	}

	public String getComments() {
		return comments;
	}

	public void setComments(String comments) {
		this.comments = comments;
	}

	public String getAttrname() {
		return attrname;
	}

	public void setAttrname(String attrname) {
		this.attrname = attrname;
	}

	public String getAttrName() {
		return attrName;
	}

	public void setAttrName(String attrName) {
		this.attrName = attrName;
	}

	public String getAttrType() {
		return attrType;
	}

	public void setAttrType(String attrType) {
		this.attrType = attrType;
	}

	public String getExtra() {
		return extra;
	}

	public void setExtra(String extra) {
		this.extra = extra;
	}
}

第八步 配置所需查询mapper

GenMapper

package com.example.demo.mapper;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Select;

public interface GenMapper {

	@Select("select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables  where table_schema = (SELECT DATABASE()) and table_name = #{tableName}")
	Map<String, Object> queryTable(String tableName);

	@Select("select column_name columnName, data_type dataType, column_comment columnComment, column_key columnKey, extra from information_schema.columns  where table_name =#{tableName} and table_schema = (SELECT DATABASE())  order by ordinal_position")
	List<Map<String, Object>> queryColumns(String tableName);

	@Select("select table_name tableName from information_schema.tables  where table_schema = (SELECT DATABASE())")
	List<String> queryAllTable();
}

第九步 生成代码工具类

GenUtils.java

package com.example.demo.generator;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.WordUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

public class GenUtils {
	/** 时间格式(yyyy-MM-dd) */
	public final static String DATE_PATTERN = "yyyy-MM-dd";
	/** 时间格式(yyyy-MM-dd HH:mm:ss) */
	public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

	public static String format(Date date) {
		return format(date, DATE_PATTERN);
	}

	public static String format(Date date, String pattern) {
		if (date != null) {
			SimpleDateFormat df = new SimpleDateFormat(pattern);
			return df.format(date);
		}
		return null;
	}

	public static List<String> getTemplates() {
		List<String> templates = new ArrayList<>();
		templates.add("vm/Entity.java.vm");
		templates.add("vm/Service.java.vm");
		templates.add("vm/ServiceImpl.java.vm");
		templates.add("vm/Mapper.java.vm");
		return templates;
	}

	/**
	 * 生成代码
	 */
	public static void generatorCode(Map<String, Object> table, List<Map<String, Object>> columns, ZipOutputStream zip) {
		// 表信息
		TableEntity tableEntity = new TableEntity();
		tableEntity.setTableName(table.get("tableName") + "");
		tableEntity.setComments(table.get("tableComment") + "");
		// 表名转换成Java类名
		String className = tableToJava(tableEntity.getTableName(), CommonMap.javaTypeMap.get("tablePrefix"));
		tableEntity.setClassName(className);
		tableEntity.setClassname(StringUtils.uncapitalize(className));
		// 列信息
		List<ColumnEntity> columsList = new ArrayList<>();
		for (Map<String, Object> column : columns) {
			ColumnEntity columnEntity = new ColumnEntity();
			columnEntity.setColumnName(column.get("columnName") + "");
			columnEntity.setDataType(column.get("dataType") + "");
			columnEntity.setComments(column.get("columnComment") + "");
			columnEntity.setExtra(column.get("extra") + "");

			// 列名转换成Java属性名
			String attrName = columnToJava(columnEntity.getColumnName());
			columnEntity.setAttrName(attrName);
			columnEntity.setAttrname(StringUtils.uncapitalize(attrName));

			// 列的数据类型,转换成Java类型
			String attrType = CommonMap.javaTypeMap.get(columnEntity.getDataType());
			attrType = StringUtils.isBlank(attrType) ? "unknowType" : attrType;
			columnEntity.setAttrType(attrType);

			// 是否主键
			if ("PRI".equalsIgnoreCase(column.get("columnKey") + "") && tableEntity.getPk() == null) {
				tableEntity.setPk(columnEntity);
			}
			columsList.add(columnEntity);
		}
		tableEntity.setColumns(columsList);

		// 没主键,则第一个字段为主键
		if (tableEntity.getPk() == null) {
			tableEntity.setPk(tableEntity.getColumns().get(0));
		}

		// 设置velocity资源加载器
		Properties prop = new Properties();
		prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
		Velocity.init(prop);

		// 封装模板数据
		Map<String, Object> map = new HashMap<>();
		map.put("tableName", tableEntity.getTableName());
		map.put("comments", tableEntity.getComments());
		map.put("pk", tableEntity.getPk());
		map.put("className", tableEntity.getClassName());
		map.put("classname", tableEntity.getClassname());
		map.put("pathName", tableEntity.getClassname().toLowerCase());
		map.put("columns", tableEntity.getColumns());
		map.put("package", CommonMap.javaTypeMap.get("package"));
		map.put("author", CommonMap.javaTypeMap.get("author"));
		map.put("date", format(new Date(), DATE_PATTERN));
//		map.put("db", db);
		map.put("jdk", CommonMap.javaTypeMap.get("jdk"));
		map.put("version", CommonMap.javaTypeMap.get("version"));
		VelocityContext context = new VelocityContext(map);

		// 获取模板列表
		List<String> templates = getTemplates();
		for (String template : templates) {
			// 渲染模板
			StringWriter sw = new StringWriter();
			Template tpl = Velocity.getTemplate(template, "UTF-8");
			tpl.merge(context, sw);

			try {
				// 添加到zip
				zip.putNextEntry(new ZipEntry(getFileName(template, tableEntity.getClassName(), CommonMap.javaTypeMap.get("package"))));
				IOUtils.write(sw.toString(), zip, "UTF-8");
				IOUtils.closeQuietly(sw);
				zip.closeEntry();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 列名转换成Java属性名
	 */
	public static String columnToJava(String columnName) {
		return WordUtils.capitalizeFully(columnName, new char[] { '_' }).replace("_", "");
	}

	/**
	 * 表名转换成Java类名
	 */
	public static String tableToJava(String tableName, String tablePrefix) {
		if (StringUtils.isNotBlank(tablePrefix)) {
			tableName = tableName.replace(tablePrefix, "");
		}
		return columnToJava(tableName);
	}

	/**
	 * 获取文件名
	 */
	public static String getFileName(String template, String className, String packageName) {
		String packagePath = "main" + File.separator + "java" + File.separator;
		if (StringUtils.isNotBlank(packageName)) {
			packagePath += packageName.replace(".", File.separator) + File.separator;
		}
		if (template.contains("Entity.java.vm")) {
			return packagePath + "entity" + File.separator + className + ".java";
		}
		if (template.contains("Service.java.vm")) {
			return packagePath + "service" + File.separator + className + "Service.java";
		}
		if (template.contains("ServiceImpl.java.vm")) {
			return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java";
		}
		if (template.contains("Mapper.java.vm")) {
			return packagePath + "mapper" + File.separator + className + "Mapper.java";
		}
		return null;
	}

}

第十步:查询所有表,调用生成工具类

GenComp.java

package com.example.demo.generator;

import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.example.demo.mapper.GenMapper;


@Component
public class GenComp {

	@Autowired
	GenMapper genMapper;

	/**
	 * 生成所有表
	 * @return
	 */
	public byte[] generatorCode() {
		 List<String> tableNames=genMapper.queryAllTable();
		 return generatorCode(tableNames);
	}
	/**
	 * 生成指定表
	 * @param tableNames
	 * @return
	 */
	public byte[] generatorCode( List<String> tableNames) {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		ZipOutputStream zip = new ZipOutputStream(outputStream);
		for (String tableName : tableNames) {
			Map<String, Object> table = genMapper.queryTable(tableName);
			List<Map<String, Object>> columns = genMapper.queryColumns(tableName);
			GenUtils.generatorCode( table, columns, zip);
		}
		IOUtils.closeQuietly(zip);
		return outputStream.toByteArray();
	}

}

测试

package com.example.demo;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.example.demo.generator.GenComp;

@SpringBootTest
@RunWith(SpringRunner.class)
public class MybatisDemoApplicationTests {
	@Autowired
	private GenComp genComp;

	@Test
	public void test() {
		 byte[] zipByte = genComp.generatorCode();
         try {
            //生成路径
			FileUtils.writeByteArrayToFile(new File("C:\\1.zip"), zipByte);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

测试生成成功

下面是生成代码截图

 

发布了61 篇原创文章 · 获赞 48 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/hzau_itdog/article/details/89215158