|
Demasiadas veces he debido cargar datos en tablas leyendo archivos de texto, asi que usando siempre la misma tecnica termine implementando algo general y que puedo modificar facilmente cuando lo necesito.
Se que existe mucho software que lo hace, pero no siepre esta a mano, no siepre es gratis y no siempre sirve :)
Esta clase utiliza dos parametros, el nombre de una tabla y el nombre de un archivo de datos para:
- Obtener la lista de columnas (y tipos) de la tabla
- Crear un prepared statement para cargar los datos
- Leer cada linea del archivo e ingresarla en la tabla
Es simple y relativamente eficiente, pero lo importante es que es modificable...
Notas
- El archivo se supone separado por tabs, pero puede modificarse
- La conexion a la base de datos esta en duro en la clase.
- Los formatos de fecha y hora deben asignarse al principio.
- Los Strings deben venir sin comillas
Listado 1: Loader
import java.io.*;
import java.sql.*;
import java.text.*;
import java.util.*;
public class Loader {
static SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd");
static SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss");
static SimpleDateFormat sdfTimestamp =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Connection conn;
PreparedStatement ps;
String table;
File file;
Vector cols = null;
public Loader(String table, File file) {
this.table = table;
this.file = file;
}
static class Column {
public int id;
public String name;
public int type;
public Column(int i, String n, int t) {
System.out.println(
"new column id:" + i + " type:" + t + " name:" + n);
id = i;
type = t;
name = n;
}
public void set(PreparedStatement ps, String val)
throws SQLException, ParseException {
//System.out.println(" set "+id+".-"+name+": "+val);
if (val == null) {
// reemplazar null por string vacio...
//if ((type == Types.VARCHAR) || (type == Types.CLOB))
// val = "";
//else {
ps.setNull(id, type);
return;
//}
}
switch (type) {
case Types.ARRAY :
case Types.BINARY :
case Types.BLOB :
case Types.JAVA_OBJECT :
case Types.LONGVARBINARY :
case Types.VARBINARY :
case Types.STRUCT :
throw new RuntimeException("Not supported");
case Types.BIGINT :
ps.setLong(id, Long.parseLong(val));
case Types.INTEGER :
case Types.BIT :
case Types.SMALLINT :
case Types.TINYINT :
ps.setInt(id, Integer.parseInt(val));
break;
case Types.DECIMAL :
case Types.NUMERIC :
case Types.DOUBLE :
ps.setDouble(id, Double.parseDouble(val));
break;
case Types.FLOAT :
case Types.REAL :
ps.setFloat(id, Float.parseFloat(val));
break;
case Types.CHAR :
ps.setString(id, val.substring(0, 1));
break;
case Types.CLOB :
case Types.LONGVARCHAR :
case Types.VARCHAR :
ps.setString(id, val);
break;
case Types.DATE :
ps.setDate(
id,
new java.sql.Date(sdfDate.parse(val).getTime()));
break;
case Types.TIME :
ps.setTime(
id,
new java.sql.Time(sdfDate.parse(val).getTime()));
break;
case Types.TIMESTAMP :
ps.setTimestamp(
id,
new java.sql.Timestamp(sdfDate.parse(val).getTime()));
break;
default :
break;
}
}
}
void connect() throws SQLException, ClassNotFoundException {
Class.forName("db driver class");
conn =
DriverManager.getConnection(
"jdbc:vendor:host/dbname",
"user",
"pass");
}
void disconnect() throws SQLException {
conn.close();
}
void fillColumnTypes() throws SQLException {
Statement stmt = conn.createStatement();
ResultSet rs =
stmt.executeQuery("select * from " + table + " where 1=2");
ResultSetMetaData rsmd = rs.getMetaData();
cols = new Vector();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
Column col =
new Column(i, rsmd.getColumnName(i), rsmd.getColumnType(i));
cols.add(col);
}
rs.close();
stmt.close();
}
void prepareStatement() throws SQLException {
StringBuffer sql = new StringBuffer();
sql.append("insert into " + table + " (");
for (int i = 0; i < cols.size(); i++) {
Column col = (Column) cols.get(i);
if (i > 0)
sql.append(",");
sql.append(col.name);
}
sql.append(") values (");
for (int i = 0; i < cols.size(); i++) {
if (i > 0)
sql.append(",");
sql.append("?");
}
sql.append(")");
System.out.println("SQL:" + sql.toString());
ps = conn.prepareStatement(sql.toString());
}
void setParameters(String line) throws SQLException, ParseException {
String stops = "t";
int i = 0, j = 0;
int l = line.length();
int n = 0;
while (i < l) {
if (n >= cols.size()) {
throw new RuntimeException("Too many fields");
}
j = i;
while (i < l)
if (stops.indexOf(line.charAt(i)) >= 0)
break;
else
i++;
String val = null;
if (i > j)
val = line.substring(j, i);
Column col = (Column) cols.get(n);
col.set(ps, val);
n++;
i++;
}
if (n < cols.size()) { // la ultima columna esta null o vacia
Column col = (Column) cols.get(n);
col.set(ps, "");
}
}
public void delete() throws SQLException, ClassNotFoundException {
connect();
Statement st = conn.createStatement();
st.executeUpdate("delete from "+table);
st.close();
disconnect();
}
void load(int titleLines) throws SQLException, ParseException, IOException {
prepareStatement();
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line = null;
for (int i=0; i<titleLines;i++)
line = br.readLine(); // saltar la lineas de titulos
int rows = 0;
line = br.readLine();
while (line != null) {
setParameters(line);
if ((rows % 10) == 0)
System.out.print(".");
rows += ps.executeUpdate();
line = br.readLine();
}
System.out.println("fin:" + rows + " filas creadas.");
ps.close();
br.close();
fr.close();
}
public void run() throws Exception {
connect();
fillColumnTypes();
load(1);
disconnect();
}
public static void main(String args[]) throws Exception {
{ // Test
String newArgs[] = { "table", "/tmp/data.txt" };
args = newArgs;
}
String t = args[0];
String f = args[1];
Loader loader = new Loader(t, new File(f));
loader.delete();
loader.run();
}
}
|