原文:使用java实现导出导入数据库的sql文件
https://blog.csdn.net/qq_39641912/article/details/79692284#commentBox
在原文基础上做了整合和扩展。
1.创建一个配置文件(其实配置文件没必要创建,只是当数据量大的时候是必须要学会读取文件的方法的,所以这里给自己记录一下)
#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程序去除
public class ConvertPropertiesToMap {
//传进来的proName为test.properties
public Map<String, String> proRead(String proName) {
Properties properties = new Properties();
Map<String, String> mpro = new HashMap<String, String>();
InputStreamReader inputStreamReader = null;
try {
inputStreamReader = new InputStreamReader(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 = new FileInputStream(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程序去除
public class ExportSql {
/* public static void main(String[] args) {
exportSql();//普通java程序,这里spring在controller中调用
}*/
public static void exportSql(){
ConvertPropertiesToMap convertPropertiesToMap = new ConvertPropertiesToMap();
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 = new String("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")
public class SqlExportController {
@CrossOrigin
@RequestMapping("/test")
public void exportExcel(HttpServletRequest request) {
ExportSql.exportSql();
}
}
输入路径即可看到F盘下有导出的.sql文件
重点:读取文件,将文件的键值对转换为Map
重点:创建runtime调用方法执行exec(command),然后能够使用cmd命令导出文件
Runtime runtime = Runtime.getRuntime();
String command = new String("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 File getCommonDocumentRoot() {
for (String commonDocRoot : COMMON_DOC_ROOTS) {
File root = new File(commonDocRoot);
if (root.exists() && root.isDirectory()) {
return root.getAbsoluteFile();
}
}
return null;
}
private static final 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()读取到真实路径,且说再说(我不知道)