package com.github.walker.easydb.dao.oracle; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Blob; import java.sql.Clob; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.Properties; import com.github.walker.easydb.exception.FileAccessException; import oracle.sql.CLOB; import com.github.walker.easydb.assistant.DateTimeUtil; import com.github.walker.easydb.dao.BaseEntity; import com.github.walker.easydb.dao.PageList; import com.github.walker.easydb.dao.ResultAssembler; import com.github.walker.easydb.dao.SettingMethodExp; import com.github.walker.easydb.datatype.EBinFile; import com.github.walker.easydb.datatype.EDouble; import com.github.walker.easydb.datatype.EFloat; import com.github.walker.easydb.datatype.EInteger; import com.github.walker.easydb.datatype.ELString; import com.github.walker.easydb.datatype.ELong; import com.github.walker.easydb.datatype.EString; import com.github.walker.easydb.datatype.ETimestamp; import com.github.walker.easydb.datatype.ETxtFile; import com.github.walker.easydb.exception.DataAccessException; import com.github.walker.easydb.exception.IllegalEntityException; /** * The Oracle database version of ResultAssembler. * * @author HuQingmiao */ class OracleRsAssembler extends ResultAssembler { public String getDBType() { return "oracle"; } protected OracleRsAssembler(ResultSet rs, Class<?> entityClass) { super(rs, entityClass); } /** * Build ArrayList object with query result. * * @return * @throws IllegalEntityException * @throws DataAccessException */ @SuppressWarnings("unchecked") protected void buildList() throws IllegalEntityException, DataAccessException, FileAccessException { //用于处理BLOB/CLOB的输入输出流 OutputStream out = null; InputStream in = null; try { this.rsList = new PageList(); while (rs.next()) { //Get the entity instance by the constructor and empty // parameter BaseEntity entity = (BaseEntity) cons.newInstance(new Object[]{}); for (Iterator<Integer> it = indexMethodExpMap.keySet().iterator(); it.hasNext(); ) { Integer col = it.next(); SettingMethodExp mdExp = (SettingMethodExp) indexMethodExpMap .get(col); Method method = mdExp.getMethod(); String paraType = mdExp.getParamType(); if ("walker.easydb.datatype.EString".equals(paraType)) { String v = rs.getString(col); EString ev = (v == null) ? new EString() : new EString(v); method.invoke(entity, new Object[]{ev}); } else if ("walker.easydb.datatype.ELong".equals(paraType)) { String v = rs.getString(col); ELong ev = (v == null) ? new ELong() : new ELong(rs .getLong(col)); method.invoke(entity, new Object[]{ev}); } else if ("walker.easydb.datatype.EInteger" .equals(paraType)) { String v = rs.getString(col); EInteger ev = (v == null) ? new EInteger() : new EInteger(rs .getInt(col)); method.invoke(entity, new Object[]{ev}); } else if ("walker.easydb.datatype.EDouble" .equals(paraType)) { String v = rs.getString(col); EDouble ev = (v == null) ? new EDouble() : new EDouble(rs .getDouble(col)); method.invoke(entity, new Object[]{ev}); } else if ("walker.easydb.datatype.ETimestamp".equals(paraType)) { Timestamp v = rs.getTimestamp(col); ETimestamp ev = (v == null) ? new ETimestamp() : new ETimestamp(v.getTime()); method.invoke(entity, new Object[]{ev}); } else if ("walker.easydb.datatype.ELString".equals(paraType)) { Clob clob = rs.getClob(col); if (clob == null) { method.invoke(entity, new Object[]{new ELString()}); } else { String ev = this.clobToString((oracle.sql.CLOB) clob); method.invoke(entity, new Object[]{new ELString(ev)}); } } else if ("walker.easydb.datatype.EBinFile" .equals(paraType)) { Blob blob = rs.getBlob(col); if (blob == null) { method.invoke(entity, new Object[]{new EBinFile()}); } else { //如果没有在easydb.property中配置文件存放目录, 则取java临时目录 String tmpDir = BASE_FILE_DIRC; if (tmpDir == null) { Properties env = System.getProperties(); tmpDir = env.getProperty("java.io.tmpdir"); } //if the #{tmpDir} not exists, created File dir = new File(tmpDir); if (!dir.exists()) { dir.mkdirs(); } //Ouput the file to the directory #{tmpDir}, //and build the file name: tmpDir + entityName +'#' // + fieldName StringBuffer fileName = new StringBuffer(tmpDir); //entity name String className = entity.getClass().getName(); int index = className.lastIndexOf('.'); fileName.append(className.substring(index + 1)); fileName.append("#"); //field name fileName.append(method.getName().substring( "Set".length())); fileName.append(DateTimeUtil.format(new Date(), "HHmmss")); File file = new EBinFile(fileName.toString()); fileName.delete(0, fileName.length()); if (file.exists()) { file.delete(); } //get input stream from clob in = blob.getBinaryStream(); byte[] b = new byte[(int) blob.length()]; //build output stream out = new FileOutputStream(file); int len = 0; while ((len = in.read(b)) != -1) out.write(b, 0, len); in.close(); out.close(); method.invoke(entity, new Object[]{file}); } } else if ("walker.easydb.datatype.ETxtFile" .equals(paraType)) { Clob clob = rs.getClob(col); if (clob == null) { method.invoke(entity, new Object[]{new ETxtFile()}); } else { //如果没有在easydb.property中配置文件存放目录, 则取java临时目录 String tmpDir = BASE_FILE_DIRC; if (tmpDir == null) { Properties env = System.getProperties(); tmpDir = env.getProperty("java.io.tmpdir"); } //if the #{tmpDir} not exists, created File dir = new File(tmpDir); if (!dir.exists()) { dir.mkdirs(); } //Ouput the file to the directory #{tmpDir}, //and build the file name: tmpDir + entityName +'#' // + fieldName StringBuffer fileName = new StringBuffer(tmpDir); //entity name String className = entity.getClass().getName(); int index = className.lastIndexOf('.'); fileName.append(className.substring(index + 1)); fileName.append("#"); //field name fileName.append(method.getName().substring( "Set".length())); fileName.append(DateTimeUtil.format(new Date(), "HHmmss")); File file = new ETxtFile(fileName.toString()); fileName.delete(0, fileName.length()); if (file.exists()) { file.delete(); } //get input stream from clob in = clob.getAsciiStream(); byte[] b = new byte[(int) clob.length()]; //build output stream out = new FileOutputStream(file); int len = 0; while ((len = in.read(b)) != -1) out.write(b, 0, len); in.close(); out.close(); method.invoke(entity, new Object[]{file}); } } else if ("walker.easydb.datatype.EFloat".equals(paraType)) { String v = rs.getString(col); EFloat ev = (v == null) ? new EFloat() : new EFloat(rs .getFloat(col)); method.invoke(entity, new Object[]{ev}); } else { //不支持的数据类型 throw new IllegalEntityException( IllegalEntityException.DATATYPE_NOT_SUPPORT, paraType); } paraType = null; } rsList.add(entity); } } catch (SQLException e) { log.error(e.getErrorCode(), e); throw new DataAccessException(this.getDBType(), e.getErrorCode(), e.getMessage()); } catch (IllegalArgumentException e) { log.error("", e); throw new IllegalEntityException(e.getMessage()); } catch (IllegalAccessException e) { log.error("", e); throw new IllegalEntityException(e.getMessage()); } catch (InvocationTargetException e) { log.error("", e); throw new IllegalEntityException(e.getMessage()); } catch (InstantiationException e) { log.error("", e); throw new IllegalEntityException(e.getMessage()); } catch (FileNotFoundException e) { log.error("", e); throw new FileAccessException(FileAccessException.FILE_NOTFOUND, e.getMessage()); } catch (IOException e) { log.error("", e); throw new FileAccessException(FileAccessException.IO_EXCEPTION, e.getMessage()); } catch (SecurityException e) { log.error("", e); } finally { try { if (in != null) { in.close(); } if (out != null) { out.close(); } } catch (IOException e1) { log.error("", e1); } } } /** * Load data to the specified entity */ protected boolean loadData(BaseEntity entity) throws IllegalEntityException, DataAccessException, FileAccessException { //用于处理BLOB/CLOB的输入输出流 OutputStream out = null; InputStream in = null; try { if (rs.next()) { for (Iterator<Integer> it = indexMethodExpMap.keySet().iterator(); it.hasNext(); ) { Integer col = it.next(); SettingMethodExp mdExp = (SettingMethodExp) indexMethodExpMap .get(col); Method method = mdExp.getMethod(); String paraType = mdExp.getParamType(); if ("walker.easydb.datatype.EString".equals(paraType)) { String v = rs.getString(col); EString ev = (v == null) ? new EString() : new EString(v); method.invoke(entity, new Object[]{ev}); } else if ("walker.easydb.datatype.ELong".equals(paraType)) { String v = rs.getString(col); ELong ev = (v == null) ? new ELong() : new ELong(rs .getLong(col)); method.invoke(entity, new Object[]{ev}); } else if ("walker.easydb.datatype.EInteger" .equals(paraType)) { String v = rs.getString(col); EInteger ev = (v == null) ? new EInteger() : new EInteger(rs .getInt(col)); method.invoke(entity, new Object[]{ev}); } else if ("walker.easydb.datatype.EDouble" .equals(paraType)) { String v = rs.getString(col); EDouble ev = (v == null) ? new EDouble() : new EDouble(rs .getDouble(col)); method.invoke(entity, new Object[]{ev}); } else if ("walker.easydb.datatype.ETimestamp" .equals(paraType)) { Timestamp v = rs.getTimestamp(col); ETimestamp ev = (v == null) ? new ETimestamp() : new ETimestamp(v .getTime()); method.invoke(entity, new Object[]{ev}); } else if ("walker.easydb.datatype.ELString".equals(paraType)) { Clob clob = rs.getClob(col); if (clob == null) { method.invoke(entity, new Object[]{new ELString()}); } else { String ev = this.clobToString((oracle.sql.CLOB) clob); method.invoke(entity, new Object[]{new ELString(ev)}); } } else if ("walker.easydb.datatype.EBinFile" .equals(paraType)) { Blob blob = rs.getBlob(col); if (blob == null) { method.invoke(entity, new Object[]{new EBinFile()}); } else { //如果没有在easydb.property中配置文件存放目录, 则取java临时目录 String tmpDir = BASE_FILE_DIRC; if (tmpDir == null) { Properties env = System.getProperties(); tmpDir = env.getProperty("java.io.tmpdir"); } //if the #{tmpDir} not exists, created File dir = new File(tmpDir); if (!dir.exists()) { dir.mkdirs(); } //Ouput the file to the directory #{tmpDir}, //and build the file name: tmpDir + entityName +'#' // + fieldName StringBuffer fileName = new StringBuffer(tmpDir); //entity name String className = entity.getClass().getName(); int index = className.lastIndexOf('.'); fileName.append(className.substring(index + 1)); fileName.append("#"); //field name fileName.append(method.getName().substring( "Set".length())); fileName.append(DateTimeUtil.format(new Date(), "HHmmss")); File file = new EBinFile(fileName.toString()); fileName.delete(0, fileName.length()); if (file.exists()) { file.delete(); } //get input stream from clob in = blob.getBinaryStream(); byte[] b = new byte[(int) blob.length()]; //build output stream out = new FileOutputStream(file); int len = 0; while ((len = in.read(b)) != -1) out.write(b, 0, len); in.close(); out.close(); method.invoke(entity, new Object[]{file}); } } else if ("walker.easydb.datatype.ETxtFile" .equals(paraType)) { Clob clob = rs.getClob(col); if (clob == null) { method.invoke(entity, new Object[]{new ETxtFile()}); } else { //如果没有在easydb.property中配置文件存放目录, 则取java临时目录 String tmpDir = BASE_FILE_DIRC; if (tmpDir == null) { Properties env = System.getProperties(); tmpDir = env.getProperty("java.io.tmpdir"); } //if the #{tmpDir} not exists, created File dir = new File(tmpDir); if (!dir.exists()) { dir.mkdirs(); } //Ouput the file to the directory #{tmpDir}, //and build the file name: tmpDir + entityName +'#' // + fieldName StringBuffer fileName = new StringBuffer(tmpDir); //entity name String className = entity.getClass().getName(); int index = className.lastIndexOf('.'); fileName.append(className.substring(index + 1)); fileName.append("#"); //field name fileName.append(method.getName().substring( "Set".length())); fileName.append(DateTimeUtil.format(new Date(), "HHmmss")); File file = new ETxtFile(fileName.toString()); fileName.delete(0, fileName.length()); if (file.exists()) { file.delete(); } //get input stream from clob in = clob.getAsciiStream(); byte[] b = new byte[(int) clob.length()]; //build output stream out = new FileOutputStream(file); int len = 0; while ((len = in.read(b)) != -1) out.write(b, 0, len); in.close(); out.close(); method.invoke(entity, new Object[]{file}); } } else if ("walker.easydb.datatype.EFloat".equals(paraType)) { String v = rs.getString(col); EFloat ev = (v == null) ? new EFloat() : new EFloat(rs .getFloat(col)); method.invoke(entity, new Object[]{ev}); } else { //不支持的数据类型 throw new IllegalEntityException( IllegalEntityException.DATATYPE_NOT_SUPPORT, paraType); } paraType = null; } // 查询出来的结果数大于1,请检查WHERE子句中的查询条件! if (rs.next()) { throw new DataAccessException( DataAccessException.RS_COUNT_GREATER1, ""); } return true; }//end if(rs.next()) //没找到与主键匹配的数据,载入失败 return false; } catch (SQLException e) { log.error(e.getErrorCode(), e); throw new DataAccessException(this.getDBType(), e.getErrorCode(), e.getMessage()); } catch (IllegalArgumentException e) { log.error("", e); throw new IllegalEntityException(e.getMessage()); } catch (IllegalAccessException e) { log.error("", e); throw new IllegalEntityException(e.getMessage()); } catch (InvocationTargetException e) { log.error("", e); throw new IllegalEntityException(e.getMessage()); } catch (FileNotFoundException e) { log.error("", e); throw new FileAccessException(FileAccessException.FILE_NOTFOUND, e.getMessage()); } catch (IOException e) { log.error("", e); throw new FileAccessException(FileAccessException.IO_EXCEPTION, e.getMessage()); } finally { try { if (in != null) { in.close(); } if (out != null) { out.close(); } } catch (IOException e1) { log.error("", e1); } } } /** * return the ArrayList object that have already assembled. */ public ArrayList<BaseEntity> getRsList() { return rsList; } // 将字CLOB转成STRING类型 public String clobToString(CLOB clob) throws SQLException, IOException { Reader is = clob.getCharacterStream();// 得到流 BufferedReader br = new BufferedReader(is); String s = br.readLine(); StringBuffer buff = new StringBuffer(); while (s != null) {// 执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成STRING buff.append(s); s = br.readLine(); } br.close(); return buff.toString(); } }