/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.kamike.divide; import com.kamike.db.generic.GenericColumn; import com.kamike.db.generic.GenericType; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; import java.util.Iterator; import java.util.concurrent.CountDownLatch; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author THiNk */ public class KamiQuery implements Runnable { private CountDownLatch doneSignal; private KamiResultSet result; private KamiStatement cs; private ArrayList<GenericType> types; public KamiQuery(CountDownLatch doneSignal, KamiStatement cs, KamiResultSet result) { this.cs = cs; this.doneSignal = doneSignal; this.result = result; this.types = new ArrayList<>(); } public KamiQuery(KamiStatement cs, KamiResultSet result) { this.cs = cs; this.result = result; this.types = new ArrayList<>(); } public void fillResultTypes(ResultSet rs) throws SQLException { ResultSetMetaData rsmd = rs.getMetaData(); for (int i = 1; i <= rsmd.getColumnCount(); i++) { int type = rsmd.getColumnType(i); String name = rsmd.getColumnName(i); switch (type) { case Types.BIGINT: types.add(GenericType.Long); break; case Types.BIT: case Types.BOOLEAN: case Types.INTEGER: case Types.TINYINT: case Types.SMALLINT: types.add(GenericType.Int); break; case Types.CHAR: case Types.CLOB: case Types.LONGNVARCHAR: case Types.LONGVARCHAR: case Types.NCHAR: case Types.NCLOB: case Types.VARCHAR: types.add(GenericType.String); break; case Types.DATE: case Types.TIME: case Types.TIMESTAMP: types.add(GenericType.Timestamp); break; case Types.DECIMAL: case Types.DOUBLE: case Types.FLOAT: case Types.NUMERIC: types.add(GenericType.Double); default: types.add(GenericType.String); break; } } } public void execute() { ResultSet rs = null; PreparedStatement ps = null; Connection conn = null; KamiRow entity = null; try { conn = KamiDbInst.getInstance().getDatabase(cs.getId()).getConnection(); ps = conn.prepareStatement(cs.getSql(), cs.getResultSetOption1(), cs.getResultSetOption2()); ArrayList<GenericColumn> columns = cs.getColumns(); int i = 1; for (Iterator<GenericColumn> it = columns.iterator(); it.hasNext();) { GenericColumn column = it.next(); switch (column.getType()) { case Int: ps.setInt(i, column.getIntValue()); break; case Long: ps.setLong(i, column.getLongValue()); break; case Double: ps.setDouble(i, column.getDoubleValue()); break; case Boolean: ps.setBoolean(i, column.getBooleanValue()); break; case Timestamp: ps.setTimestamp(i, column.getTimestampValue()); break; case String: ps.setString(i, column.getStrValue()); break; } i++; } rs = ps.executeQuery(); //下面解析recordset的metadata this.fillResultTypes(rs); while (rs.next()) { entity = new KamiRow(); i = 1; for (Iterator<GenericType> it = types.iterator(); it.hasNext();) { GenericType type = it.next(); GenericColumn column = new GenericColumn(); column.setType(type); switch (type) { case Int: column.setIntValue(rs.getInt(i)); break; case Long: column.setLongValue(rs.getLong(i)); break; case Double: column.setDoubleValue(rs.getDouble(i)); break; case Boolean: column.setBooleanValue(rs.getInt(i) > 0); break; case Timestamp: column.setTimestampValue(rs.getTimestamp(i)); break; case String: column.setStrValue(rs.getString(i)); break; } i++; entity.getColumns().add(column); } if (result != null) { result.add(entity); } } } catch (Exception e) { System.out.println(this.getClass().getName() + e.toString()); } finally { try { if (rs != null) { rs.close(); rs = null; } if (ps != null) { ps.close(); ps = null; } if (conn != null) { conn.close(); conn = null; } } catch (SQLException ex) { Logger.getLogger(KamiQuery.class.getName()).log(Level.SEVERE, null, ex); } } doneSignal.countDown(); } /** * @return the result */ public KamiResultSet getResult() { return result; } @Override public void run() { execute(); } }