使用java导Mysql的.sql文件,扩展->mysqldump命令的使用,mysql使用SQL语句查询comment注释

2022-09-15 12:36:53

原文:使用java实现导出导入数据库的sql文件
https://blog.csdn.net/qq_39641912/article/details/79692284#commentBox
在原文基础上做了整合和扩展。

1.创建一个配置文件(其实配置文件没必要创建,只是当数据量大的时候是必须要学会读取文件的方法的,所以这里给自己记录一下)

  1. 先在src/main目录下创建一个资源类文件夹resources(创建资源类文件夹,不是普通文件夹)
  2. 创建一个test.properties,内容为
#ip,-u,-p,数据库名称
host=127.0.0.1
userName=root
password=root
databaseName=db_dictionary_sys
#输入转义后的地址
exportPath=F\:\\Test0.sql

3.创建一个工具类ConvertPropertiesToMap.class

import java.io.FileInputStream;import java.io.InputStream;import java.io.InputStreamReader;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import java.util.Properties;/**
 * 类描述:这个类是为了让自己知道怎么样通过流的方式读取文件,以及不同的读取方式
 *
 * @author 07968
 * @version 1.0
 * @date 2020/9/3 1:12
 */@Component//spring使用,普通java程序去除publicclassConvertPropertiesToMap{//传进来的proName为test.propertiespublic Map<String, String>proRead(String proName){
        Properties properties=newProperties();
        Map<String, String> mpro=newHashMap<String, String>();
        InputStreamReader inputStreamReader= null;try{

            inputStreamReader=newInputStreamReader(getClass().getResourceAsStream(proName),"UTF-8");/*         InputStreamReader(InputStream.class,"UTF-8")中的第一个参数需要的InputStream.class,返回这个流可以有两种方式

            第一种,InputStream inputStream1 = new FileInputStream(filePath)通过FileInputStream读取绝对路径,然后读取文件返回流
            //获取绝对路径      //注意这儿如果filePath如果是相对路径,也就是只写test.properties,是读取不到的
            String  proName2 = Thread.currentThread().getContextClassLoader().getResource(proName).getFile();
            InputStream inputStream1 = new FileInputStream(proName2);

            InputStream is = this.getClass().getResourceAsStream(fileName);  //拿不到资源
            InputStream is = this.getClass().getResourceAsStream("/" + fileName); // 拿到资源
            InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileName); //拿到资源

            第二种,通过this.getClass().getResourceAsStream(fileName)
            一定要注意!!!
            代码在src/main/java目录下,资源文件在src/main/resources/目录下
            1)如果给fileName传递的名称中,不加"/",会从当前类的目录下去找,这个文件如果不和该类在一个目录下,是找不到的。
               注意我说的是目录directory,不是package
            2)"/"会从编译后的整个classes目录下去找,maven也会把资源文件打包进classes文件夹,所以可以找到。

            第三种 this.getClass().getClassLoader().getResourceAsStream(fileName)通过类加载去读取文件。
                  ClassLoader就是从整个classes文件夹找的,所以前面无需再加"/"
                  
                   这几句话参考这:https://www.jb51.net/article/119419.htm
            */
            properties.load(inputStreamReader);@SuppressWarnings("rawtypes")
            Enumeration en= properties.propertyNames();while(en.hasMoreElements()){
                String key=(String) en.nextElement();
                String value= properties.getProperty(key);
                mpro.put(key, value);}return mpro;}catch(Exception e1){// TODO Auto-generated catch block
            e1.printStackTrace();}return null;}}

三种读取文件的方式很重要

            InputStream inputStream1=newFileInputStream(filePath)

            InputStream is=this.getClass().getResourceAsStream(fileName); 
            InputStream is=this.getClass().getResourceAsStream("/"+ fileName); 
            
            InputStream is=this.getClass().getClassLoader().getResourceAsStream(fileName);

4.创建类ExportSql.class

import java.io.IOException;import java.util.Map;/**
 * 类描述:
 *
 * @author 07968
 * @version 1.0
 * @date 2020/9/3 1:42
 */@Component//spring使用,普通java程序去除publicclassExportSql{/*    public static void main(String[] args) {
        exportSql();//普通java程序,这里spring在controller中调用
    }*/publicstaticvoidexportSql(){

        ConvertPropertiesToMap convertPropertiesToMap=newConvertPropertiesToMap();
        String proName="test.properties";
        Map<String, String> map= convertPropertiesToMap.proRead(proName);

        String host= map.get("host");
        String user= map.get("userName");
        String password= map.get("password");
        String exportDatabaseName= map.get("databaseName");
        String exportPath= map.get("exportPath");//使用拼接的方式来完成dos命令
        String command=newString("cmd /k mysqldump -u"+user+" -p"+password+" "+exportDatabaseName+" >"+exportPath);//new String("cmd /k mysqldump -u" + user + " -p" + password + " " + exportDatabaseName + " tab_business_sys --where=\"S_SYS_CODE="+sSysCode+"\" >" + exportPath+"&& ");//这是一张表下,有限定条件的//执行命令行
        Runtime runtime= Runtime.getRuntime();try{//cmd /k在执行命令后不关掉命令行窗口  cmd /c在执行完命令行后关掉命令行窗口   \\表示转译符也可使用/替代,linux使用/
            Process process= runtime.exec(command);}catch(IOException e){// TODO Auto-generated catch block
            e.printStackTrace();}}}

创建一个
ExportSqlController.class

import com.tiandy.easy7.ddmsystem.core.sjh.utils.ExportSql;import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;/**
 * 类描述:
 *
 * @author 07968
 * @version 1.0
 * @date 2020/8/31 9:32
 */@RestController@RequestMapping("/export")publicclassSqlExportController{@CrossOrigin@RequestMapping("/test")publicvoidexportExcel(HttpServletRequest request){
        ExportSql.exportSql();}}

输入路径即可看到F盘下有导出的.sql文件


重点:读取文件,将文件的键值对转换为Map
重点:创建runtime调用方法执行exec(command),然后能够使用cmd命令导出文件

Runtime runtime= Runtime.getRuntime();
String command=newString("cmd /k mysqldump -u"+user+" -p"+password+" "+exportDatabaseName+" >"+exportPath);
Process process= runtime.exec(command);

上面使用的是mysqldump命令,cmd命令行只导出一张表或者几张表的数据如下
mysql利用mysqldump导出表结构或者表数据
https://blog.csdn.net/u013946356/article/details/84990671
重点:>>表示追加,-d表示只导出结构,数据库名称后写表明是导出该表数据

既然能够导出数据库下的一张表的数据,是不是也能够加上限定条件导出表里面的部分数据
这篇文章:MYSQL使用mysqldump导出表的部分数据
https://www.cnblogs.com/bbox/p/9750214.html
重点:使用命令-where=" A=1 and B=2"做条件限定,使用cmd命令只导出一张表的部分数据

导出数据还有没有更详细的呢,有,诺,查询出这个表里面的字段注释。
mysql使用sql语句查询数据库所有表注释已经表字段注释

SELECT COLUMN_NAME,COLUMN_COMMENT from INFORMATION_SCHEMA.Columns WHERE table_name='tab_business_sys' and TABLE_SCHEMA='db_dictionary_sys'

来自:https://www.cnblogs.com/007sx/p/7093429.html 参数只需要数据库和表名称,如图所示

在这里插入图片描述


还有第一个中创建用来执行命令行的Runtime runtime = Runtime.getRuntime();

在 Runtime.getRunTime(). exec上,如果需要执行多个命令,中间加上 & 或者 && 可以执行多条
Runtime.getRuntime().exec("cmd1 && " +"cmd2 && " +"cmd3 && " );
来自:https://blog.csdn.net/maimiho/article/details/94035837
(我感觉这其实是一条。。。合一起了呗)


推文

java项目下资源文件路径的获取
https://blog.csdn.net/lj_dreamone/article/details/79280085
JAVA中读取配置文件以及修改配置文件
https://blog.csdn.net/qq_37725650/article/details/79744847

这两个文章都教给我获取文件绝对路径的方法

            String realPath= request.getServletContext().getRealPath("test.properties");//下面可这种是可以读取的,上面的不行//String  proName2 = Thread.currentThread().getContextClassLoader().getResource(proName).getFile();//InputStream inputStream1 = new FileInputStream(proName2);

request.getServletContext().getRealPath我记得我以前在SSM程序中用过,是可以正常获取路径的啊,为啥这里不行呢,无论怎么尝试都是给我一个临时文件夹,并且这个临时文件夹下是个空文件夹,但是居然输出语句中给我放到这个文件夹下了。好气。
在这里插入图片描述
和记忆严重不符合,创建一个SpringMVC程序测试一下吧,看看结果
哎呀,不会使用idea创建SpringMVC,看着两个文章,很棒
文章1:https://www.cnblogs.com/wormday/p/8435617.html
文章2:https://blog.csdn.net/weixin_42518668/article/details/103594144
得到的测试结果如下,都能读取得到。
在这里插入图片描述

好像哪里不太对,都是Spring一家的,为什么SpringBoot使用request.getServletContext().getRealPath只能读取得到临时文件夹,SpringMVC却能够正常读取。

周折之后明白,默认情况下springboot中request.getServletContext().getRealPath 返回的是一个临时文件夹的地址
通过查看源代码 位置在

org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory#getCommonDocumentRoot
private FilegetCommonDocumentRoot(){for(String commonDocRoot: COMMON_DOC_ROOTS){
            File root=newFile(commonDocRoot);if(root.exists()&& root.isDirectory()){return root.getAbsoluteFile();}}return null;}
privatestaticfinal String[] COMMON_DOC_ROOTS={"src/main/webapp","public","static"};

可以看到springboot 会尝试读取COMMON_DOC_ROOTS 配置里面的路径,所以我们只需要在springboot 所在的jar 或者项目所在的根目录下新建一个public或者static的文件夹,那么通过 request.getServletContext().getRealPath 就会得到public或者static的路径

文章参考:spring boot 的request.getServletContext().getRealPath路径获取问题:
https://www.cnblogs.com/netcorner/p/12001668.html
至于现在的情况,怎么样在springboot中用request.getServletContext().getRealPath()读取到真实路径,且说再说(我不知道)

  • 作者:爱花的蛋
  • 原文链接:https://blog.csdn.net/weixin_45633422/article/details/108350793
    更新时间:2022-09-15 12:36:53