(进阶版)自定义数据库配置,代码生成并打包成ZIP文件、导出zip文件完整实现过程。

一:效果图:
效果图仅供参考,以下功能经过完善加工。
在这里插入图片描述
在这里插入图片描述

基础版:mybatis-plus根据Mysql数据库自动生成代码到项目
二:代码展示
数据库字段展示:
在这里插入图片描述
代码展示:

  • 实体类
package com.backstage.manage.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;

import java.time.LocalDateTime;

import com.baomidou.mybatisplus.annotation.TableField;

import java.io.Serializable;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
 * <p>
 * 数据库配置(代码生成)
 * </p>
 *
 * @author xu
 * @since 2022-02-22
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("db_config")
public class DbConfig implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * ip
     */
    @TableId(value = "ip", type = IdType.ASSIGN_ID)
    private String ip;

    /**
     * 账号
     */
    @TableField("db_root")
    private String dbRoot;

    /**
     * 密码
     */
    @TableField("db_password")
    private String dbPassword;

    /**
     * 端口
     */
    @TableField("db_port")
    private String dbPort;

    /**
     * 数据库名字
     */
    @TableField("db_name")
    private String dbName;

    /**
     * 创建时间
     */
    @TableField("create_time")
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @TableField("update_time")
    private LocalDateTime updateTime;

    /**
     * 表名
     */
    @TableField(exist = false)
    private String tableName;

}

  • mapper层
package com.backstage.manage.mapper;

import com.backstage.manage.entity.DbConfig;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 * 数据库配置(代码生成) Mapper 接口
 * </p>
 *
 * @author xu
 * @since 2022-02-22
 */
public interface DbConfigMapper extends BaseMapper<DbConfig> {

}

  • seriviceimpl层
package com.backstage.manage.service.impl;

import com.backstage.manage.config.Result;
import com.backstage.manage.entity.DbConfig;
import com.backstage.manage.mapper.DbConfigMapper;
import com.backstage.manage.service.DbConfigService;
import com.backstage.manage.utils.CodeUtils;
import com.backstage.manage.utils.MySqlUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 数据库配置(代码生成) 服务实现类
 * </p>
 *
 * @author xu
 * @since 2022-02-22
 */
@Service
public class DbConfigServiceImpl extends ServiceImpl<DbConfigMapper, DbConfig> implements DbConfigService {


    @Override
    public Result autoGenerateCode2(DbConfig dbConfig) throws Exception {
        //判断数据库是否存在这个表名
        if (!MySqlUtils.isExistTableNames(dbConfig)) {
            return Result.failed("数据库不存在该表名!");
        }
        //生成代码
        CodeUtils.generator(dbConfig);
        return Result.ok("导出成功");
    }
}
  • serivice层
package com.backstage.manage.service;

import com.backstage.manage.config.Result;
import com.backstage.manage.entity.DbConfig;
import com.baomidou.mybatisplus.extension.service.IService;

/**
 * <p>
 * 数据库配置(代码生成) 服务类
 * </p>
 *
 * @author xu
 * @since 2022-02-22
 */
public interface DbConfigService extends IService<DbConfig> {


    /**
     * 生成代码
     * @param dbConfig
     * @return
     * @throws Exception
     */
    Result autoGenerateCode2(DbConfig dbConfig) throws Exception;

}

  • controller层
package com.backstage.manage.frameController;


import com.backstage.manage.config.Result;
import com.backstage.manage.entity.DbConfig;
import com.backstage.manage.service.DbConfigService;
import com.backstage.manage.utils.FileZipUtil;
import com.backstage.manage.utils.MySqlUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;

/**
 * <p>
 * 数据库配置(代码生成) 前端控制器
 * </p>
 *
 * @author xu
 * @since 2022-02-22
 */
@RestController
@CrossOrigin
@RequestMapping("/dbConfig")
public class DbConfigController {

    @Autowired
    DbConfigService dbConfigService;
    @Value("${sourceFilePath}")
    private String sourceFilePath;

    /**
     * 分页查询数据库配置
     *
     * @param page
     * @param dbConfig
     * @return
     */
    @GetMapping("/page")
    public Result page(Page page, DbConfig dbConfig) {
        return Result.ok(dbConfigService.page(page, Wrappers.query(dbConfig).orderByDesc("create_time")));
    }

    /**
     * 保存数据库配置
     *
     * @param dbConfig
     * @return
     */
    @PostMapping("/save")
    public Result save(@RequestBody DbConfig dbConfig) {
        return Result.ok(dbConfigService.save(dbConfig));
    }

    /**
     * 更新数据库配置
     *
     * @param dbConfig
     * @return
     */
    @PutMapping
    public Result update(@RequestBody DbConfig dbConfig) {
        return Result.ok(dbConfigService.updateById(dbConfig));
    }

    /**
     * 删除数据库配置
     *
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public Result update(@PathVariable("id") String id) {
        return Result.ok(dbConfigService.removeById(id));
    }

    /**
     * 获取数据库所有表名
     *
     * @param dbConfig
     * @return
     */
    @PostMapping("/getTableName")
    public Result getTableName(@RequestBody DbConfig dbConfig) throws Exception {
        return MySqlUtils.getTableName(dbConfig);
    }

    /**
     * 生成代码到服务器并使用浏览器下载ZIP文件
     * @param response
     * @param dbConfig
     * @throws Exception
     */
    @PostMapping("/exportToZip")
    public void exportToZip(HttpServletResponse response, DbConfig dbConfig) throws Exception {
        System.out.println("请求参数" + dbConfig);
        if (StringUtils.isEmpty(dbConfig.getDbRoot())) {
            throw new RuntimeException("数据信息请填写完整,数据库用户名不能为空");
        }
        if (StringUtils.isEmpty(dbConfig.getIp())) {
            throw new RuntimeException("数据信息请填写完整,数据库IP不能为空");
        }
        if (StringUtils.isEmpty(dbConfig.getDbPort())) {
            throw new RuntimeException("数据信息请填写完整,数据库端口不能为空");
        }
        if (StringUtils.isEmpty(dbConfig.getDbName())) {
            throw new RuntimeException("数据信息请填写完整,数据库名不能为空");
        }
        if (StringUtils.isEmpty(dbConfig.getTableName())) {
            throw new RuntimeException("数据信息请填写完整,数据库表名不能为空");
        }
        //先生成代码
        Result result = dbConfigService.autoGenerateCode2(dbConfig);
        if (result.getCode() != 0) {
            throw new RuntimeException(result.getMsg());
        }
         //下载生成的打包好的代码zip文件
        FileZipUtil.exportZip(response, sourceFilePath);
    }

}


  • 工具类:
package com.backstage.manage.utils;



import com.backstage.manage.config.Result;
import com.backstage.manage.entity.DbConfig;
import org.apache.commons.lang.StringUtils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * @author lenovo
 */
public class MySqlUtils {
    /**
     * 创建数据库连接
     * @param dbConfig
     * @return
     * @throws Exception
     */
    public static Connection getMySqlConnection(DbConfig dbConfig) throws Exception {
        String driverName = "com.mysql.cj.jdbc.Driver";
        String url = "jdbc:mysql://" + dbConfig.getIp() + ":" + dbConfig.getDbPort() + "/" + dbConfig.getDbName() + "?serverTimezone=UTC";
        String username = dbConfig.getDbRoot();
        String password = dbConfig.getDbPassword();
        Class.forName(driverName);
        Connection con = DriverManager.getConnection(url, username, password);
        con.setAutoCommit(false);
        return con;
    }

    /**
     * 获取表名列表
     * @param dbConfig
     * @return
     * @throws Exception
     */
    public static Result getTableName(DbConfig dbConfig) throws Exception {
        if (StringUtils.isNotEmpty(dbConfig.getDbRoot()) && StringUtils.isNotEmpty(dbConfig.getDbPassword())
                && StringUtils.isNotEmpty(dbConfig.getIp()) && StringUtils.isNotEmpty(dbConfig.getDbPort()) && StringUtils.isNotEmpty(dbConfig.getDbName())) {
            Connection connection = MySqlUtils.getMySqlConnection(dbConfig);
            String sql = "SELECT table_name FROM information_schema.tables WHERE table_schema=?";
            PreparedStatement ps = connection.prepareStatement(sql);
            ps.setString(1, dbConfig.getDbName());
            ResultSet rs = ps.executeQuery();
            List<String> tableNameList = new ArrayList<>();
            while (rs.next()) {
                String tableName = rs.getString("table_name");
                System.out.println("表名" + tableName);
                tableNameList.add(tableName);
            }
            rs.close();
            ps.close();
            connection.close();
            return Result.ok(tableNameList);
        } else {
            return Result.failed("数据库信息不完整");
        }
    }

    /**
     * 判断数据库是否存在表名
     * @param dbConfig
     * @return
     * @throws Exception
     */
    public static boolean isExistTableNames(DbConfig dbConfig) throws Exception {
        Connection connection = getMySqlConnection(dbConfig);
        String sql = "SELECT COUNT(1) FROM information_schema.tables WHERE table_schema=? AND table_name=?";
        PreparedStatement ps = connection.prepareStatement(sql);
        ps.setString(1, dbConfig.getDbName());
        ps.setString(2, dbConfig.getTableName());
        ResultSet rs = ps.executeQuery();
        if (rs.next()) {
            rs.close();
            ps.close();
            connection.close();
            System.out.println("数据库表名存在");
            return true;
        } else {
            rs.close();
            ps.close();
            connection.close();
            System.out.println("数据库表名不存在");
            return false;
        }
    }
}

package com.backstage.manage.utils;

import com.backstage.manage.entity.DbConfig;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
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.rules.NamingStrategy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;

/**
 * 代码生成工具
 * @author lenovo
 */
@RestController
public class CodeUtils {

    //这个写在配置文件里,意思是生成的代码打包zip文件存放的位置
    @Value("${sourceFilePath}")
    private static String sourceFilePath;

    /**
     * 生成代码
     * @param dbConfig
     */
    public static void generator(DbConfig dbConfig) {
        //创建generator对象
        AutoGenerator autoGenerator = new AutoGenerator();
        //数据源
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);
        dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSourceConfig.setUsername(dbConfig.getDbRoot());
        dataSourceConfig.setPassword(dbConfig.getDbPassword());
        dataSourceConfig.setUrl("jdbc:mysql://" + dbConfig.getIp() + ":" + dbConfig.getDbPort() + "/" + dbConfig.getDbName() + "?serverTimezone=UTC?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai");
        autoGenerator.setDataSource(dataSourceConfig);
        //全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOpen(false);
        globalConfig.setOutputDir(sourceFilePath);
        globalConfig.setAuthor("dreamXu");
        globalConfig.setServiceName("%sService");
        globalConfig.setIdType(IdType.ASSIGN_ID);
        autoGenerator.setGlobalConfig(globalConfig);
        //包信息
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.backstage.manage");
        packageConfig.setController("controller");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("service.impl");
        packageConfig.setMapper("mapper");
        packageConfig.setEntity("entity");
        autoGenerator.setPackageInfo(packageConfig);
        //配置策略
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude(dbConfig.getTableName());
        System.out.println("表名" + strategyConfig.getInclude());
        strategyConfig.setEntityLombokModel(true);
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        autoGenerator.setStrategy(strategyConfig);
        autoGenerator.execute();
    }
}

package com.backstage.manage.utils;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author wx
 * @date 2020/10/29 5:19 下午
 */
public class FileZipUtil {

    /**
     * @param zip
     * @param file 文件夹目录
     * @param dir
     * @throws Exception
     */
    private static void handlerFile(ZipOutputStream zip, File file, String dir) throws Exception {
        //如果当前的是文件夹,则进行进一步处理
        if (file.isDirectory()) {
            //得到文件列表信息
            File[] fileArray = file.listFiles();
            if (fileArray == null) {
                return;
            }
            //将文件夹添加到下一级打包目录
            zip.putNextEntry(new ZipEntry(dir + "/"));
            dir = dir.length() == 0 ? "" : dir + "/";
            //递归将文件夹中的文件打包
            for (File f : fileArray) {
                handlerFile(zip, f, dir + f.getName());
            }
        } else {
            //当前的是文件,打包处理
            //文件输入流
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
            ZipEntry entry = new ZipEntry(dir);
            zip.putNextEntry(entry);
            zip.write(FileUtils.readFileToByteArray(file));
            IOUtils.closeQuietly(bis);
            zip.flush();
            zip.closeEntry();
        }
    }

    private static byte[] createZip(String sourceFilePath) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ZipOutputStream zip = new ZipOutputStream(outputStream);
        //将目标文件打包成zip导出
        File file = new File(sourceFilePath);
        handlerFile(zip, file, "");
        IOUtils.closeQuietly(zip);
        return outputStream.toByteArray();
    }


    /**
     * 导出目标文件为zip
     *
     * @param response
     * @param sourceFilePath
     */
    public static void exportZip(HttpServletResponse response, String sourceFilePath) {
        //文件名以时间戳作为前缀
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String filePrefix = sdf.format(new Date());
        String downloadName = filePrefix + ".zip";
        //将文件进行打包下载
        try {
            OutputStream out = response.getOutputStream();
            //接收压缩包字节
            byte[] data = createZip(sourceFilePath);
            response.reset();
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Expose-Headers", "*");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + downloadName);
            response.addHeader("Content-Length", "" + data.length);
            response.setContentType("application/octet-stream;charset=UTF-8");
            IOUtils.write(data, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

XuDream

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

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

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

打赏作者

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

抵扣说明:

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

余额充值