package mobvista.prd.datasource.dao.impl; import mobvista.prd.datasource.dao.DBCommonDAO; import mobvista.prd.datasource.db.DBDataSource; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.math.BigDecimal; import java.sql.*; import java.util.*; import java.util.Date; public class DBCommonDAOImpl implements DBCommonDAO { /** * 通用查询方法,返回Map集合 * @param sql * @param params * @return * @throws Exception */ public List<Map<String, Object>> findMapList(String sql, Object[] params) throws Exception { return findMapList(DBDataSource.getInstance().getConnection(), sql, params, true); } /** * * @param conn * @param sql * @param params * @param closeConn * @return * @throws Exception */ public List<Map<String, Object>> findMapList(Connection conn, String sql, Object[] params, boolean closeConn) throws Exception { ResultSet rs = null; PreparedStatement ps = null; List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); try { ps = conn.prepareStatement(sql); if (params != null && params.length > 0) { for (int i = 0; i < params.length; i++) { ps.setObject(i + 1, params[i]); } } rs = ps.executeQuery(); ResultSetMetaData rsmd = rs.getMetaData(); Map<String, Object> map = null; while (rs.next()) { map = new HashMap<String, Object>(); for (int i = 0; i < rsmd.getColumnCount(); i++) { map.put(rsmd.getColumnName(i + 1), rs.getObject(i + 1)); } list.add(map); } } finally { if (rs != null) { rs.close(); } if (ps != null) { ps.close(); } if (closeConn && conn != null) { conn.close(); } } return list; } /** * 通用查询数据方法,返回clazz类型集合 * @param sql * @param params * @param clazz * @return * @throws Exception */ public <T> List<T> findListByClass(String sql, Object[] params, Class<T> clazz) throws Exception{ ResultSet rs = null; Connection conn = null; PreparedStatement ps = null; List<T> list = new ArrayList<T>(); try { conn = DBDataSource.getInstance().getConnection(); ps = conn.prepareStatement(sql); if (params != null && params.length > 0) { for (int i = 0; i < params.length; i++) { ps.setObject(i + 1, params[i]); } } rs = ps.executeQuery(); list = parseResultSet(clazz, rs); } finally { if (rs != null) { rs.close(); } if (ps != null) { ps.close(); } if (conn != null) { conn.close(); } } return list; } /** * 通用更新方法 * @param sql 更新语句 * @param params 参数 * @return * @throws Exception */ public int update(String sql, Object[] params) throws Exception { return update(DBDataSource.getInstance().getConnection(), sql, params, true); } /** * * @param conn * @param sql * @param params * @param closeConn * @return * @throws Exception */ public int update(Connection conn, String sql, Object[] params, boolean closeConn) throws Exception { PreparedStatement ps = null; try { conn.setAutoCommit(false); ps = conn.prepareStatement(sql); if (params != null && params.length > 0) { for (int i = 0; i < params.length; i++) { ps.setObject(i + 1, params[i]); } } int count = ps.executeUpdate(); if (closeConn) { conn.commit(); } return count; } catch (Exception e) { if (closeConn && conn != null) { conn.rollback(); } throw e; } finally { if (ps != null) { ps.close(); } if (closeConn && conn != null) { conn.close(); } } } /** * 通过sql插入数据方法 * @param sql * @param params * @return * @throws Exception */ public int insert(String sql, Object[] params) throws Exception { return insert(DBDataSource.getInstance().getConnection(), sql, params, true); } /** * 通过sql插入数据方法 * @param conn * @param sql * @param params * @return * @throws Exception */ public int insert(Connection conn, String sql, Object[] params, boolean closeConn) throws Exception { PreparedStatement ps = null; try { conn.setAutoCommit(false); ps = conn.prepareStatement(sql); if (params != null && params.length > 0) { for (int i = 0; i < params.length; i++) { ps.setObject(i + 1, params[i]); } } int count = ps.executeUpdate(); if (closeConn) { conn.commit(); } return count; } catch (Exception e) { if (closeConn && conn != null) { conn.rollback(); } throw e; } finally { if (ps != null) { ps.close(); } if (closeConn && conn != null) { conn.close(); } } } /** * 解析sql查询结果,并创建clazz类型集合 * @param clazz * @param rs * @return * @throws Exception */ private <T> List<T> parseResultSet(Class<T> clazz, ResultSet rs) throws Exception { Class.forName(clazz.getName()); Field[] fields = clazz.getDeclaredFields(); T instance = null; @SuppressWarnings("rawtypes") Class type = null; String name = null; Method method = null; String methodName = null; List<T> list = new ArrayList<T>(); while (rs.next()) { instance = clazz.newInstance(); for (Field field : fields) { name = field.getName(); if (!"serialVersionUID".equals(name) && !"table".equals(name)) { methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); type = field.getType(); method = clazz.getMethod(methodName, type); if (type == Integer.class) { method.invoke(instance, rs.getInt(name)); } else if (type == String.class) { method.invoke(instance, rs.getString(name)); } else if (type == Long.class) { method.invoke(instance, rs.getLong(name)); } else if (type == Double.class) { method.invoke(instance, rs.getDouble(name)); } else if (type == Float.class) { method.invoke(instance, rs.getFloat(name)); } else if (type == Boolean.class) { method.invoke(instance, rs.getBoolean(name)); } else if (type == BigDecimal.class) { method.invoke(instance, rs.getBigDecimal(name)); } else if (type == Blob.class) { method.invoke(instance, rs.getBlob(name)); } else if (type == Clob.class) { method.invoke(instance, rs.getClob(name)); } else if (type == Byte.class) { method.invoke(instance, rs.getByte(name)); } else if (type == Date.class) { if (rs.getDate(name) != null) { method.invoke(instance, new Date(rs.getDate(name).getTime())); } } else if (type == Short.class) { method.invoke(instance, rs.getShort(name)); } } } list.add(instance); } return list; } /** * 通用新增方法 * @param obj * @return * @throws Exception */ public Integer persist(Serializable obj) throws Exception { Integer id = null; ResultSet rs = null; Connection conn = null; PreparedStatement ps = null; try { conn = DBDataSource.getInstance().getConnection(); conn.setAutoCommit(false); Map<String, Object> map = buildSqlAndParams(obj); String sql = (String) map.get("sql"); ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); @SuppressWarnings("unchecked") List<Object> params = (List<Object>) map.get("params"); if (params != null && params.size() > 0) { for (int i = 0; i < params.size(); i++) { ps.setObject(i + 1, params.get(i)); } } ps.execute(); rs = ps.getGeneratedKeys(); while (rs.next()) { id = rs.getInt(1); } conn.commit(); } catch (Exception e) { if (conn != null) { conn.rollback(); } throw e; } finally { if(rs != null) { rs.close(); } if (ps != null) { ps.close(); } if (conn != null) { conn.close(); } } return id; } private Map<String, Object> buildSqlAndParams (Serializable obj) throws Exception { Class<?> clazz = obj.getClass(); Class.forName(clazz.getName()); StringBuffer columns = new StringBuffer("("); StringBuffer values = new StringBuffer("("); List<Object> params = new ArrayList<Object>(); String name = null; Object value = null; Method method = null; Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { name = field.getName(); if (!"serialVersionUID".equals(name) && !"table".equals(name)) { method = obj.getClass().getDeclaredMethod("get" + name.substring(0, 1).toUpperCase() + name.substring(1), null); value = method.invoke(obj, null); params.add(value); columns.append(name).append(","); values.append("?,"); } } if (columns.length() > 1) { columns.setLength(columns.length() - 1); values.setLength(values.length() - 1); } columns.append(")"); values.append(")"); Field tableField = clazz.getDeclaredField("table"); tableField.setAccessible(true); Object temp = tableField.get(obj); if (temp == null) { throw new Exception(clazz.getName() + " 缺少table成员变量 "); } String table = String.valueOf(temp); StringBuffer sql = new StringBuffer("insert into ").append(table); sql.append(columns).append(" values ").append(values); Map<String, Object> map = new HashMap<String, Object>(); map.put("sql", sql.toString()); map.put("params", params); return map; } }