sqlload导入大量数据确实有大量优势,是一个比较好的工具。
1 public class OracleLoadDataHelperUntil { 2 3 private static String databaseUrl = ProperUtil.getValue("db.properties", "jdbc.url"); 4 5 private static String user = ProperUtil.getValue("db.properties", "jdbc.username"); 6 7 private static String pwd = ProperUtil.getValue("db.properties", "jdbc.password"); 8 9 private static String driver = ProperUtil.getValue("db.properties", "jdbc.driver"); 10 11 private static String fileRoute = ""; 12 13 /** 14 * 链接数据库地址 15 */ 16 private static String baseUrl = ""; 17 18 public OracleLoadDataHelperUntil() { 19 20 } 21 22 static { 23 try { 24 String url = databaseUrl.substring(databaseUrl.indexOf("@")); 25 baseUrl = url.replaceAll("@", "//").substring(0, url.lastIndexOf(":")+1) + "/" 26 + url.substring(url.lastIndexOf(":") + 1); 27 Class.forName(driver); 28 } catch (ClassNotFoundException e) { 29 e.printStackTrace(); 30 } 31 } 32 33 /** 34 * 根据表名称获取数据库字段 35 * 36 * @param tableName 37 * @return 38 * @throws Exception 39 */ 40 private static List<String> getFieldsByTableName(String tableName) throws Exception { 41 List<String> fields = Lists.newArrayList(); 42 Connection conn = DriverManager.getConnection(databaseUrl, user, pwd); 43 String sql = "select COLUMN_NAME from USER_TAB_COLUMNS where TABLE_NAME=upper('" + tableName + "')"; 44 Statement stmt = conn.createStatement(); 45 ResultSet rs = stmt.executeQuery(sql); 46 String filed = ""; 47 while (rs.next()) { 48 filed = rs.getString("COLUMN_NAME"); 49 fields.add(filed); 50 } 51 rs.close(); 52 conn.close(); 53 return fields; 54 } 55 56 /** 57 * 获取控制命名字符串 58 * 59 * @param fileName 导入的文件名,全路径 60 * @param tableName 表名 61 * @param delimiter 分割符 62 * @return 63 */ 64 private static String getStrCtr(String fileName, String tableName, String delimiter, List<String> fileds) { 65 StringBuffer sb = new StringBuffer(); 66 String lineSeparator = System.getProperty("line.separator"); 67 // 0是从第一行开始 1是 从第二行 68 sb.append("OPTIONS (skip=0)").append(lineSeparator); 69 // 加载数据文件 70 sb.append("LOAD DATA").append(lineSeparator); 71 // 防止中文乱码 72 sb.append("CHARACTERSET ZHS16GBK").append(lineSeparator); 73 sb.append("INFILE ").append("\'").append(fileName).append("\'").append(lineSeparator); 74 if(Strings.isStringEmpty(delimiter)) { 75 sb.append("\"str X'170A'\"").append(lineSeparator); 76 } 77 // 覆盖写入 78 sb.append("APPEND INTO TABLE ").append(tableName).append(lineSeparator); 79 sb.append("REPLACE").append(lineSeparator); 80 // 数据中每行记录用","分隔 ,TERMINATED用于控制字段的分隔符,可以为多个字符。 81 if(Strings.isStringEmpty(delimiter)) { 82 sb.append("FIELDS TERMINATED BY X'lib'").append(lineSeparator); 83 }else { 84 sb.append("FIELDS TERMINATED BY '"+delimiter+"'").append(lineSeparator); 85 } 86 // 将数据写入对应的字段 87 sb.append("trailing nullcols ( ").append(lineSeparator); 88 sb.append(getFieldsStr(fileds)).append(lineSeparator); 89 sb.append(")"); 90 91 return sb.toString(); 92 } 93 94 95 private static String getFieldsStr(List<String> fileds) { 96 StringJoiner sj = new StringJoiner("," + System.getProperty("line.separator")); 97 for (String s : fileds) { 98 sj.add(s); 99 } 100 return sj.toString(); 101 } 102 103 /** 104 * 获取控制文件的路径 105 * 106 * @param fileRoute 数据文件地址路径 107 * @param fileName 数据文件名 108 * @param tableName 表名 109 * @param delimiter 分隔符 110 * @param fieldNames 属性集合 111 * @param ctlfileName 控制文件名 112 * @return 113 */ 114 private static String getCtlFileUrl(String fileRoute, String fileName, String tableName, String delimiter, 115 List<String> fieldNames, String ctlfileName) { 116 String ctlFileUrl = ""; 117 FileWriter fw = null; 118 try { 119 String strctl = getStrCtr(fileRoute + fileName, tableName, delimiter, fieldNames); 120 fw = new FileWriter(fileRoute + "" + ctlfileName); 121 fw.write(strctl); 122 ctlFileUrl = fileRoute + "" + ctlfileName; 123 } catch (IOException e) { 124 e.printStackTrace(); 125 } finally { 126 try { 127 fw.flush(); 128 fw.close(); 129 } catch (IOException e) { 130 e.printStackTrace(); 131 } 132 } 133 return ctlFileUrl; 134 } 135 136 /** 137 * 判断是什么系统,true 为windows,false为linux 138 * 139 * @return 140 */ 141 private static Boolean isOsWin() { 142 Boolean flag = Boolean.FALSE; 143 String os = System.getProperty("os.name"); 144 if (os.toLowerCase().startsWith("win")) { 145 flag = Boolean.TRUE; 146 } 147 return flag; 148 } 149 150 /** 151 * 152 * @param fileRoute 文件路径 153 * @param ctlfileName 控制文件路径 154 * @param logfileName 日志文件路径 155 * @param flag 是否立即执行,true执行命令,false不执行 156 * @return sqlload的执行语句 157 */ 158 private static String excuteLoadData(String fileRoute, String ctlfileName, String logfileName, boolean flag) { 159 InputStream ins = null; 160 Process process = null; 161 String dos = "sqlldr " + user + "/" + pwd + "@" + baseUrl + " control=" + fileRoute + "" + ctlfileName + " log=" 162 + fileRoute + "" + logfileName; 163 System.out.println("dos:" + dos); 164 if(flag==false) { 165 return dos; 166 } 167 try { 168 if (isOsWin().equals(Boolean.FALSE)) { 169 process = Runtime.getRuntime().exec(dos); 170 } else { 171 String[] cmd = new String[] { "cmd.exe", "/C", dos }; 172 process = Runtime.getRuntime().exec(cmd); 173 } 174 ins = process.getInputStream(); 175 Charset charset=Charset.forName("GBK"); 176 BufferedReader reader = new BufferedReader(new InputStreamReader(ins,charset)); 177 String line = null; 178 while ((line = reader.readLine()) != null) { 179 String msg = new String(line.getBytes(), "GBK"); 180 System.out.println(line); 181 } 182 int exitValue = process.waitFor(); 183 if (exitValue == 0) { 184 System.out.println("返回值:" + exitValue + "\n数据导入成功"); 185 186 } else { 187 System.out.println("返回值:" + exitValue + "\n数据导入失败"); 188 } 189 process.getOutputStream().close(); 190 } catch (Exception e) { 191 e.printStackTrace(); 192 } 193 return dos; 194 } 195 196 /** 197 * 198 * 执行sqlload数据导入方法 199 * 200 * @param filePath 文件根路径 201 * @param fileName 数据文件 .dat文件 202 * @param tableName 表名 203 * @param fieldNames 属性字段 204 * @param flag 是否立即执行,true执行命令,false不执行 205 * @return sqlload的执行语句 206 * @throws Exception 207 */ 208 209 public static String excuteSqlLoadImportData(String filePath, String fileName, String tableName,String delimiter,List<String> fields, boolean flag) throws Exception { 210 String str = ""; 211 String ctlfileName = tableName + ".ctl"; 212 String logfileName = tableName + ".log"; 213 if (Strings.isStringEmpty(filePath)) { 214 filePath = fileRoute; 215 } 216 if(CollectionUtils.isEmpty(fields)) { 217 fields=getFieldsByTableName(tableName); 218 } 219 String fileUrl = getCtlFileUrl(filePath, fileName, tableName, delimiter, fields, ctlfileName); 220 if (!Strings.isStringEmpty(fileUrl)) { 221 str = excuteLoadData(filePath, ctlfileName, logfileName, flag); 222 } 223 return str; 224 } 225 226 }