package edu.sjtu.infosec.ismp.manager.comm.comm.conn.jdbc; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.sql.Connection; import java.sql.Date; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.DynaBean; import org.apache.commons.beanutils.RowSetDynaClass; import org.apache.log4j.Logger; import org.infosec.ismp.manager.rmi.sysm.config.model.SysConfigDb; import org.infosec.ismp.manager.rmi.sysm.config.service.SysConfigDbService; public class JdbcSensorClient { private static SysConfigDbService sysConfigDbService; public static LinkedList<SysConfigDbService> list = new LinkedList<SysConfigDbService>(); private static Connection conn = null; private Statement stmt = null; private PreparedStatement prepstmt = null; private static Logger logger = Logger.getLogger(JdbcSensorClient.class); /** * @param sysConfigDbService the sysConfigDbService to set */ public static void setSysConfigDbService(SysConfigDbService sysConfigDbService) { JdbcSensorClient.sysConfigDbService = sysConfigDbService; } /** * 以创建Statement 初始化Mysql */ public JdbcSensorClient() { try { getDirectConn(); stmt = conn.createStatement(); } catch (Exception e) { System.err.println("jdbc init error: " + e); } } /* * private void getDataSource() { try { Context ctx = new InitialContext(); * if (ctx == null) throw new Exception("Boom - No Context"); * * DataSource ds = (DataSource) ctx .lookup("java:comp/env/jdbc/userDB"); if * (ds != null) conn = ds.getConnection(); * * } catch (Exception e) { System.err.println("getDataSource() error: " + * e); } } */ // 数据库Connection是使用DataSource接口建立, // 它为用户提供的能力比DriverManager提供的基本Connection对象的能力要多得多v private static final Connection getDirectConn() { synchronized (list) { ReadProp readProp = new ReadProp(); Properties properties = readProp.read(); String driver = properties.getProperty("Ums.Driver"); String url = properties.getProperty("Ums.url"); String username = properties.getProperty("Ums.username"); String password = properties.getProperty("Ums.password"); System.out.println(driver + url + username + password); System.out.println(sysConfigDbService); if(list.size() > 0 ){ try { SysConfigDb sysConfigDb = list.getLast().findByName("WSUS"); driver = sysConfigDb.getDbDriver(); url = sysConfigDb.getDbUrl(); username = sysConfigDb.getUsername(); password =sysConfigDb.getPassword(); while (list.size() > 2 ){ list.remove(); } } catch (Exception e) { } } try { Class.forName(driver).newInstance(); conn = DriverManager.getConnection(url, username, password); } catch (Exception e) { e.printStackTrace(); System.err.println("getDataSource() error: " + e); } } return conn; } /** * 以创建PreparedStatement 初始化Mysql */ public JdbcSensorClient(String sql) { try { getDirectConn(); prepareStatement(sql); } catch (Exception e) { System.err.println("jdbc init error: " + e); } } public static Connection getConnection() { return conn; } public void prepareStatement(String sql) throws SQLException { prepstmt = conn.prepareStatement(sql); } public void setString(int index, String value) throws SQLException { prepstmt.setString(index, value); } public void setInt(int index, int value) throws SQLException { prepstmt.setInt(index, value); } public void setBoolean(int index, boolean value) throws SQLException { prepstmt.setBoolean(index, value); } public void setDate(int index, Date value) throws SQLException { prepstmt.setDate(index, value); } public void setLong(int index, long value) throws SQLException { prepstmt.setLong(index, value); } public void setFloat(int index, float value) throws SQLException { prepstmt.setFloat(index, value); } public void setBinaryStream(int index, InputStream in, int length) throws SQLException { prepstmt.setBinaryStream(index, in, length); } public void clearParameters() throws SQLException { prepstmt.clearParameters(); } public PreparedStatement getPreparedStatement() { return prepstmt; } public Statement getStatement() { return stmt; } /** * 执行Statement查询语句 * * @param sql * @return * @throws SQLException */ public ResultSet executeQuery(String sql) throws SQLException { if (stmt != null) { return stmt.executeQuery(sql); } else return null; } /** * 执行Statement查询语句 * * @param sql * @return String * @throws SQLException */ public String executeQueryString(String sql) throws SQLException { String value = null; ResultSet rs = null; try { rs = executeQuery(sql); if (rs.next()) { value = rs.getString(1); } } catch (Exception e) { // TODO: handle exception } finally { if (rs != null) { rs.close(); } close();// 关闭连接 } System.out.println("executeQueryString---------------------------------"+value); return value; } /** * 执行PreparedStatement查询语句 * * @return * @throws SQLException */ public ResultSet executeQuery() throws SQLException { if (prepstmt != null) { return prepstmt.executeQuery(); } else return null; } public List populate(String sql, Class clazz) throws Exception { ResultSet rs = executeQuery(sql); ResultSetMetaData metaData = rs.getMetaData(); // 取得结果集的元元素 int colCount = metaData.getColumnCount(); // 取得所有列的个数 List ret = new ArrayList(); // 存放返回结果的容器 Field[] fields = clazz.getDeclaredFields(); // 取得业务对象的属性 while (rs.next()) { Object newInstance = clazz.newInstance(); // 构造业务对象实例 // 将结果集中每一条记录,每一个字段取出,根据命名规则,对对应的业务对象的属性进行赋值 for (int i = 1; i <= colCount; i++) { // 对于该记录的每一列 try { Object value = rs.getObject(i); for (int j = 0; j < fields.length; j++) { Field f = fields[j]; if (f.getName().equalsIgnoreCase( metaData.getColumnName(i).replaceAll("_", ""))) { if (value == null) value = ""; BeanUtils.copyProperty(newInstance, f.getName(), value); } } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } ret.add(newInstance); } if (rs != null) rs.close(); close();// 关闭连接 return ret; } public static List find(String sSQL, Class elementClass, Object[] objParms) throws Exception { long begin = System.currentTimeMillis(); List listReturn = new LinkedList(); RowSetDynaClass rowset = execQuery(sSQL, objParms); RowSetToObjectCollection(rowset, elementClass, listReturn); // logger.info("SQL LoG \n SQL = " + sSQL + " Parm Collection Dump -- " // + dumpCollection(createParmCollection(objParms))); long cost = System.currentTimeMillis() - begin; if (cost > 200) { logger .warn(" ** A find cost over 200ms, please have a check the sql, the reason maybe a bad sql or the sql return a lot of records. sSQL = '" + sSQL + "' Parm Collection Dump -- " + dumpCollection(createParmCollection(objParms)) + " ** "); } else { // logger.debug(" * find cost = '" + cost + "' * "); } return listReturn; } public static Collection createParmCollection(Object[] objParms) { Collection col = new LinkedList(); for (int i = 0; i < objParms.length; i++) { Object objParm = objParms[i]; col.add(objParm); } return col; } protected static String dumpCollection(Collection colToDump) { if (colToDump == null) { return " null collection "; } else { StringBuffer sbDumpResult = new StringBuffer(" Dump Collection : "); int iPos = 0; for (Iterator iterator = colToDump.iterator(); iterator.hasNext();) { Object emt = iterator.next(); sbDumpResult.append(++iPos).append(":'").append(emt).append( "' "); } return sbDumpResult.toString(); } } public static RowSetDynaClass execQuery(String sSQL, Object[] oaParms) throws Exception { long begin = System.currentTimeMillis(); Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { con = getDirectConn(); pstmt = con.prepareStatement(sSQL, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); int iPos = 0; for (int i = 0; i < oaParms.length; i++) { Object parm = oaParms[i]; // NGtodo Change for TEMP. but needed in AIX's weblogic if (parm == null) { parm = ""; } pstmt.setObject(++iPos, parm); } rs = pstmt.executeQuery(); rs.beforeFirst(); RowSetDynaClass rsdc = new RowSetDynaClass(rs); long cost = System.currentTimeMillis() - begin; if (cost > 200) { logger .warn(" ** A execQuery cost over 200ms, please have a check the sql, the reason maybe a bad sql or the sql return a lot of records. sSQL = '" + sSQL + "' Parm Collection Dump -- " + dumpCollection(createParmCollection(oaParms)) + " ** "); } else { // logger.debug(" * execQuery cost = '" + cost + "' * "); } return rsdc; } catch (SQLException e) { logger.error("SQLException \n SQL = " + sSQL + " Parm Collection Dump -- " + dumpCollection(createParmCollection(oaParms)), e); throw new Exception("SQLException", e); } finally { cleanup(pstmt, con, rs); } } /** * Convert RowSet objects to specified javabean collection. * * @param p_rowset * @param javabeanClass * @param p_colReturn * this function will add the new instance into this collection. * Must be Not Null. * @throws Exception */ private static void RowSetToObjectCollection(RowSetDynaClass p_rowset, Class javabeanClass, Collection p_colReturn) throws Exception { List rows = p_rowset.getRows(); try { if (rows.size() > 0) { for (int i = 0; i < rows.size(); i++) { DynaBean dynaBean = (DynaBean) rows.get(i); Object javabean = javabeanClass.newInstance(); populate(javabean, BeanUtils.describe(dynaBean), true); p_colReturn.add(javabean); } } } catch (InstantiationException e) { logger.error("InstantiationException", e); throw new Exception("InstantiationException", e); } catch (IllegalAccessException e) { logger.error("IllegalAccessException ( class DynaBean )", e); throw new Exception("IllegalAccessException", e); } catch (NoSuchMethodException e) { logger.error("NoSuchMethodException ( class DynaBean )", e); throw new Exception("NoSuchMethodException", e); } } /** * Enhance the BeanUtils's populate function to support ignore properties' * case. but before use it, please be sure the bean's field name and the * map's key names has no duplicate. ignoreCase = false 's performance is * better than ignorCase = true. * * @param beanTo * @param mapFrom * @param ignoreCase * ignore the properties' names' case or not. * @throws IllegalAccessException * @throws InvocationTargetException */ private static void populate(Object beanTo, Map mapFrom, boolean ignoreCase) throws IllegalAccessException, InvocationTargetException { // Do nothing unless both arguments have been specified if ((beanTo == null) || (mapFrom == null)) { return; } if (ignoreCase) { // Loop through the property name/value pairs to be set Iterator names = mapFrom.keySet().iterator(); Field[] fields = beanTo.getClass().getDeclaredFields(); Map mapFieldName = new HashMap(fields.length); Map mapTypeName = new HashMap(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; String name = field.getName(); mapFieldName.put(name.toLowerCase(), name); mapTypeName.put(name.toLowerCase(), field.getType()); } while (names.hasNext()) { // Identify the property name and value(s) to be assigned String name = (String) names.next(); if (name == null) { continue; } else if (mapFieldName.get(name.toLowerCase()) == null) { continue; } Class type = (Class) mapTypeName.get(name.toLowerCase()); if (mapFrom.get(name) == null && java.sql.Timestamp.class.equals(type)) continue; // System.out.println(type.getName()); Object value = mapFrom.get(name) == null ? "" : mapFrom .get(name); // Perform the assignment for this property BeanUtils.setProperty(beanTo, mapFieldName.get( name.toLowerCase()).toString(), value); } mapFieldName.clear(); } else { BeanUtils.populate(beanTo, mapFrom); } } private static Field[] getFields(Object objToListFields) { // after test, use cache is not faster than no cache. JDK1.4.1 return objToListFields.getClass().getDeclaredFields(); /* * Field[] FieldsForFrom; Class objFromClass; String objFromClassName = * null; objFromClass = objToListFields.getClass(); objFromClassName = * objFromClass.getName(); FieldsForFrom = * (Field[])ReflectCacheForFields.get(objFromClassName); if (null == * FieldsForFrom) { FieldsForFrom = objFromClass.getDeclaredFields(); * ReflectCacheForFields.put(objFromClassName, FieldsForFrom); } return * FieldsForFrom; */ } /** * 执行Statement更改语句 * * @param sql * @throws SQLException */ public void executeUpdate(String sql) throws SQLException { if (stmt != null) stmt.executeUpdate(sql); close();// 关闭连接 } /** * 执行PreparedStatement更改语句 * * @throws SQLException */ public void executeUpdate() throws SQLException { if (prepstmt != null) prepstmt.executeUpdate(); close();// 关闭连接 } public final static void cleanup(Statement stmt, Connection conn, ResultSet rs) { try { if (rs != null) { rs.close(); rs = null; } } catch (Exception ex) { } try { if (stmt != null) { stmt.close(); stmt = null; } } catch (Exception e) { } try { if (conn != null) { conn.close(); conn = null; } } catch (Exception e) { } } /** * 关闭连接 */ public void close() { try { if (stmt != null) { stmt.close(); stmt = null; } if (prepstmt != null) { prepstmt.close(); prepstmt = null; } if (conn != null) { conn.close(); conn = null; } } catch (Exception e) { System.err.println("Mysql close error: " + e); } } }