在Java 程序中,运行 sql文件总结:
两种思路:
第一种思路:读取脚本文件,分解成 sql 语句,然后在程序中执行批处理。
第二种思路:利用 Ant 的SQL Task来实现执行SQL 脚本的功能。
第一种思路的麻烦之处在于,如何将一个文件中的所有语句分解成一句句的SQL语句,如果分解的稍微不成功,执行时就会出问题,所以必须在文件中作标记。
相比这下,第二种思路比较有优势,利用成熟的技术为自己所用。下面简要说说第二种思路的实现方法:
1. ant 包中的 SQLExec类的扩展,此时需要将ant 包(ant.jar)导入
import java.io.File;
import org.apache.tools.ant.*;
import org.apache.tools.ant.taskdefs.*;
import org.apache.tools.ant.types.*;
import com.microsoft.jdbc.sqlserver.SQLServerDriver;
public class AntExecSql {
public AntExecSql() {
}
public static void execSqlFile(String url,String userID,String pwd,String sqlFile){
SQLExec sqlExec = new SQLExec();
// 设置数据库参数
sqlExec.setDriver("com.microsoft.jdbc.sqlserver.SQLServerDriver");
sqlExec.setUrl(url);
sqlExec.setUserid(userID);
sqlExec.setPassword(pwd);
sqlExec.setSrc(new File(sqlFile));
// sqlExec.setOnerror((SQLExec.OnError)(EnumeratedAttribute.getInstance(SQLExec.OnError.class, "abort")));
sqlExec.setPrint(true); //设置是否输出
// 输出到文件 sql.out 中;不设置该属性,默认输出到控制台
// sqlExec.setOutput(new File("d:/script/sql.out"));
sqlExec.setProject(new Project()); // 要指定这个属性,不然会出错
sqlExec.execute();
}
}
2. 获取文件的路径问题,
新建一个自定义类KeyXMLTool,利用如下语句获得 web-inf 的绝对路径。
String web_inf_Path=new File(KeyXMLTool.class.getResource("/").getPath()).getParent();
只要绝对路径能够获得,其它路径就不是啥问题了,KeyXMLTool 的源码如下:
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.*;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.xml.sax.SAXException;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import java.io.File;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.util.Map;
import java.util.HashMap;
public class KeyXMLTool {
private Map propertyCache=new HashMap();
private static String CMBKeyFileName="system-config.xml";
//得到WEB-INF的绝对路径
private static String web_inf_Path=new File(KeyXMLTool.class.getResource("/").getPath()).getParent();
private static String CMBKeyFilePath=web_inf_Path+"\\"+CMBKeyFileName;
private static DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
public static String getUrl(){
return CMBKeyFilePath;
}
public static String getFileUrl(String fileName){
String fileUrl=web_inf_Path+"\\"+fileName;
return fileUrl;
}
public static String getRootWebUrl(){
String rootWebUrl=new File(KeyXMLTool.class.getResource("/").getPath()).getParent();
return rootWebUrl;
}
/**
* 获取一Document对象
* @param fileName String
* @return Document
*/
private static Document getDocumentByFileName(final String fileName){
Document doc=null;
try {
DocumentBuilder dombuilder = domfac.newDocumentBuilder();
InputStream in=new FileInputStream(fileName);
// InputStream in=ClassLoader.getSystemResourceAsStream(fileName);
// InputStream in = KeyXMLTool.class.getResourceAsStream("/Key.xml");
doc=dombuilder.parse(in);
} catch (ParserConfigurationException ex) {
ex.printStackTrace();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} catch (SAXException ex) {
ex.printStackTrace();
}
return doc;
}
public static String getPINKey(){
String pinKey=null;
Document doc=getDocumentByFileName(CMBKeyFilePath);
NodeList pinKeyNodeList=doc.getElementsByTagName("pinkey");
Node pinKeyNode=pinKeyNodeList.item(0);
pinKey=pinKeyNode.getFirstChild().getNodeValue();
return pinKey;
}
public static synchronized void setPINKEY(final String pinKey){
Document doc=getDocumentByFileName(CMBKeyFilePath);
NodeList pinKeyNodeList=doc.getElementsByTagName("pinkey");
Node pinKeyNode=pinKeyNodeList.item(0);
pinKeyNode.getFirstChild().setNodeValue(pinKey);
doc2XmlFile(doc,CMBKeyFilePath);
}
public static String getMACKEY(){
String macKey=null;
Document doc=getDocumentByFileName(CMBKeyFilePath);
NodeList pinKeyNodeList=doc.getElementsByTagName("mackey");
Node pinKeyNode=pinKeyNodeList.item(0);
macKey=pinKeyNode.getFirstChild().getNodeValue();
return macKey;
}
public static synchronized void setMACKEY(final String macKey){
Document doc=getDocumentByFileName(CMBKeyFilePath);
NodeList pinKeyNodeList=doc.getElementsByTagName("mackey");
Node pinKeyNode=pinKeyNodeList.item(0);
pinKeyNode.getFirstChild().setNodeValue(macKey);
doc2XmlFile(doc,CMBKeyFilePath);
}
/** 将document中的内容写入文件中 */
public static boolean doc2XmlFile(Document document,String filename){
boolean flag = true;
try {
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
/** 编码 */
//transformer.setOutputProperty(OutputKeys.ENCODING, "GB2312");
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File(filename));
transformer.transform(source, result);
}catch(Exception ex)
{
flag = false;
ex.printStackTrace();
}
return flag;
}
}
3. 利用上面的两个类,完成主体任务,执行数据库脚本文件。
String file1=KeyXMLTool.getFileUrl("STTE_createTables2.sql");
String file2=KeyXMLTool.getFileUrl("STTE_initData2.sql");
try{
AntExecSql.execSqlFile(url,username,pwd,file1);
AntExecSql.execSqlFile(url,username,pwd,file2);
}catch(Exception ex){
ex.printStackTrace();
System.out.println("error" + ex.getMessage());
errorMsg=ex.getMessage();
errorMsg=errorMsg.substring(errorMsg.indexOf("JDBC]")+5,errorMsg.length()-1);
if(errorMsg.equals("Error establishing socket")){
errorMsg="数据库地址错误!";
}
}