数据源配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" xmlns:rabbit="http://www.springframework.org/schema/rabbit" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!-- spring的属性加载器,加载properties文件中的属性 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>classpath:common.properties</value> </property> <property name="fileEncoding" value="utf-8" /> </bean> <bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass"> <value>com.mysql.jdbc.Driver</value> </property> <property name="jdbcUrl"> <value>jdbc:mysql://${mysql.db.ip}:${mysql.db.port}/${mysql.db.database}?useUnicode=true&characterEncoding=UTF-8</value> </property> <property name="user"> <value>${mysql.db.user}</value> </property> <property name="password"> <value>${mysql.db.password}</value> </property> <!--连接池中保留的最小连接数。 --> <property name="minPoolSize"> <value>1</value> </property> <!--连接池中保留的最大连接数。Default: 15 --> <property name="maxPoolSize"> <value>15</value> </property> <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 --> <property name="initialPoolSize"> <value>1</value> </property> <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 --> <property name="maxIdleTime"> <value>60</value> </property> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 --> <property name="acquireIncrement"> <value>5</value> </property> <!--JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements 属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。 如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 --> <property name="maxStatements"> <value>0</value> </property> <!--每60秒检查所有连接池中的空闲连接。Default: 0 --> <property name="idleConnectionTestPeriod"> <value>60</value> </property> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 --> <property name="acquireRetryAttempts"> <value>30</value> </property> <!--获取连接失败将会引起所有等待连接池来获取连接的线程抛出异常。但是数据源仍有效 保留,并在下次调用getConnection()的时候继续尝试获取连接。如果设为true,那么在尝试 获取连接失败后该数据源将申明已断开并永久关闭。Default: false --> <property name="breakAfterAcquireFailure"> <value>true</value> </property> <!--因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的 时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable 等方法来提升连接测试的性能。Default: false --> <property name="testConnectionOnCheckout"> <value>false</value> </property> </bean> <!-- 连接管理对象 --> <bean id="c3P0ConnectionProvider" class="com.kingdee.mysql.provider.C3P0ConnectionProvider"> <property name="dataSource" ref="dataSource"></property> </bean> </beans>
数据源生成器代码
package com.kingdee.mysql.provider; import java.sql.Connection; public interface ConnecttionProvider { public Connection getConnection()throws Exception; }
package com.kingdee.mysql.provider; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ImportResource; import org.springframework.stereotype.Component; @Component public class C3P0ConnectionProvider implements ConnecttionProvider{ @Autowired private DataSource dataSource; public Connection getConnection() throws Exception { // TODO Auto-generated method stub Connection connection = dataSource.getConnection(); return connection; } public DataSource getDataSource() { return dataSource; } public void setDataSource(DataSource dataSource){ if(dataSource == null){ System.out.println("===null===="); }else { System.out.println("======!!!!null"); } this.dataSource = dataSource; } }
package com.kingdee.dao.impl; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; import org.hibernate.validator.internal.util.privilegedactions.GetMethod; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.StringUtils; import com.kingdee.dao.IPage; import com.kingdee.dao.JdbcUtil; import com.kingdee.mysql.provider.ConnecttionProvider; import com.mysql.cj.jdbc.result.ResultSetMetaData; import com.sun.org.apache.xerces.internal.util.SynchronizedSymbolTable; import com.sun.xml.internal.bind.v2.schemagen.xmlschema.List; public class CommonDao { private static Logger logger = LoggerFactory.getLogger(CommonDao.class); @Autowired private ConnecttionProvider c3P0ConnectionProvider; public ConnecttionProvider getC3P0ConnectionProvider() { return c3P0ConnectionProvider; } public void setC3P0ConnectionProvider(ConnecttionProvider c3p0ConnectionProvider) { c3P0ConnectionProvider = c3p0ConnectionProvider; } public IPage getPage() { return page; } public void setPage(IPage page) { this.page = page; } private static ThreadLocal<Connection> connWrapper = new ThreadLocal<Connection>(); @Autowired private IPage page; public Connection getConnection() throws Exception { Connection connection = connWrapper.get(); if (connection != null && !connection.isClosed()) { return connection; } // 取连接并放入线程属性域中 connection = c3P0ConnectionProvider.getConnection(); if (connection == null) { throw new SQLException("无法获取数据库连接"); } connWrapper.set(connection); return connection; } // 如果当前线程有连接则调用该方法关闭掉 public static void closeConnection() { Connection conn = connWrapper.get(); if (conn != null) { try { conn.close(); } catch (SQLException e) { logger.error("Can not close database connection", e); } // 释放掉保存的对象 connWrapper.remove(); } } public Method getMethod(Method[] methods,String pre, String name){ for(Method method:methods){ String methodname = method.getName(); if (methodname.equalsIgnoreCase(pre+name)) { return method; } } return null; } public void cleanup(ResultSet set,PreparedStatement pre){ if (set!=null) { try{ set.close(); }catch(SQLException e){ } } cleanup(pre); } public void cleanup(PreparedStatement pre){ if (pre!=null) { try{ pre.close(); }catch(SQLException e){ } } } public void cleanup(Statement stat) { if (stat != null) { try { stat.close(); } catch (SQLException e) { // ignore } } } public <T> LinkedList<T> queryBeans(String sql, Object[] params, Class<T> clazz, int offset, int limit) throws Exception{ Connection con = getConnection(); LinkedList<T> result = new LinkedList<T>(); sql = page.formatPageSQL(sql, offset, limit); ResultSet rs = null; PreparedStatement pre = null; try{ pre = con.prepareStatement(sql); if(params!=null&¶ms.length>0){ for(int i=0;i<params.length;i++){ pre.setObject(i+1, params[i]); } } rs = pre.executeQuery(); ResultSetMetaData RSMD = (ResultSetMetaData) rs.getMetaData(); int count = RSMD.getColumnCount(); Method[] methods = clazz.getMethods(); while(rs.next()){ T bean = clazz.newInstance(); for(int i=1;i<=count;i++){ String name = RSMD.getColumnName(i); Method method = getMethod(methods,"set",name); if (method==null) { continue; } Class[] arguments = method.getParameterTypes(); Object value = JdbcUtil.getResultSetValue(rs, i, arguments[0]); method.invoke(bean, value); } result.add(bean); } }finally{ cleanup(rs, pre); closeConnection(); } return result; } public LinkedList<HashMap<String,Object>> query(String sql, Object[] params, int offset, int limit) throws Exception{ Connection con = getConnection(); sql = page.formatPageSQL(sql, offset, limit); ResultSet rs = null; PreparedStatement pre = null; LinkedList<HashMap<String,Object>> result = new LinkedList<HashMap<String,Object>>(); try{ pre = con.prepareStatement(sql); if(params!=null&¶ms.length>0){ for(int i=0;i<params.length;i++){ pre.setObject(i+1, params[i]); } } rs = pre.executeQuery(); ResultSetMetaData RSMD = (ResultSetMetaData) rs.getMetaData(); int count = RSMD.getColumnCount(); while(rs.next()){ HashMap<String,Object> map = new HashMap<String,Object>(); for(int i=1;i<=count;i++){ Object value = rs.getObject(i); String name = RSMD.getColumnName(i); map.put(name, value); } result.add(map); } }finally{ cleanup(rs, pre); closeConnection(); } return result; } /** * 查询单一的实体对象 * * @param <T> * @param sql * @param clazz * @return */ public <T> T querySingleBean(String sql, Class<T> clazz) throws Exception { return this.querySingleBean(sql, new Object[0], clazz); } public <T> T querySingleBean(String sql, Object[] params, Class<T> clazz) throws Exception { LinkedList<T> beans = this.queryBeans(sql, params, clazz); if (beans == null || beans.isEmpty()) { return null; } return beans.get(0); } public <T> T querySingleBean(String sql, Class<T> clazz, Object... params) throws Exception { if (params == null) { return querySingleBean(sql, (Object[]) null, clazz); } return querySingleBean(sql, params, clazz); } /** * 支持分页的查询 * * @param <T> * @param sql * @param clazz * @param offset * @param limit * @return * @throws Exception */ public <T> LinkedList<T> queryBeans(String sql, Class<T> clazz, int offset, int limit) throws Exception { return queryBeans(sql, null, clazz, offset, limit); } /** * * @param <T> * @param sql * @param clazz * @return * @throws Exception */ public <T> LinkedList<T> queryBeans(String sql, Class<T> clazz) throws Exception { return this.queryBeans(sql, new Object[0], clazz); } /** * * @param sql * @param params * @return */ public <T> LinkedList<T> queryBeans(String sql, Object[] params, Class<T> clazz) throws Exception { return queryBeans(sql, params, clazz, 0, 0); } public <T> LinkedList<T> queryBeans(String sql, Class<T> clazz, Object[] params) throws Exception { return queryBeans(sql, params, clazz, 0, 0); } public <T> LinkedList<T> queryBeans(String sql, Class<T> clazz, int offset, int limit, Object... params) throws Exception { return queryBeans(sql, (Object[]) params, clazz, offset, limit); } /** * 查询 * * @param sql * @return */ public LinkedList<HashMap<String, Object>> query(String sql) throws Exception { return this.query(sql, 0,0); } public LinkedList<HashMap<String, Object>> query(String sql, int offset, int limit) throws Exception { return this.query(sql, (String[]) null, offset, limit); } public LinkedList<HashMap<String, Object>> query(String sql, Object[] params) throws Exception { return this.query(sql, params, 0,0); } public HashMap<String, Object> querySingle(String sql, Object[] params) throws Exception { LinkedList<HashMap<String, Object>> result = query(sql, params); if (result.isEmpty()) { return null; } return result.get(0); } /** * @deprecated * @param sql * @param params * @return */ public <T> int countBeans(String sql, Object[] params, Class<T> clazz) throws Exception { LinkedList<T> result = this.queryBeans(sql, params, clazz); return result == null ? -1 : result.size(); } /** * 查询数据库中的单一整形字段 * * @param sql * @param params * @return * @throws Exception */ public int queryIntegerValue(String sql, Object[] params) throws Exception { LinkedList<HashMap<String, Object>> result = this.query(sql, params); if (result == null || result.isEmpty()) { return -1; } HashMap<String, Object> data = result.get(0); Object[] ret = data.values().toArray(); if (ret.length == 0 || ret[0] == null) { return -1; } return ((Number) ret[0]).intValue(); } public int queryIntegerValue(String sql) throws Exception { return this.queryIntegerValue(sql, new Object[0]); } public int count(String sql) throws Exception { return this.queryIntegerValue(sql, new Object[0]); } public int count(String sql, Object[] params) throws Exception { return this.queryIntegerValue(sql, params); } /** * 执行数据的更新操作 * * @param sql * @param params * @return * @throws Exception */ public int execute(String sql) throws Exception { return this.execute(sql, new Object[0]); } // note:UPDATE和DELETE操作能返回被操作到的行数,INSERT成功则都是返回0 public int execute(String sql, Object[] params) throws Exception { Connection conn = getConnection(); PreparedStatement ps = null; try { ps = conn.prepareStatement(sql); for (int i = 0; i < params.length; i++) { ps.setObject(i + 1, params[i]); } return ps.executeUpdate(); } finally { cleanup(ps); closeConnection(); } } public boolean existByCondition(String tableName, String condition, Object... params) throws Exception { return this.count("select count(0) from " + tableName + " where " + condition, params) != 0; } /** * 执行删除操作 * * @param tableName * @param conditions * @param params * @throws Exception */ public int delete(String tableName, String conditions, Object... params) throws Exception { StringBuffer sql = new StringBuffer("DELETE FROM "); sql.append(tableName); sql.append(" WHERE "); sql.append(conditions); return this.execute(sql.toString(), params); } public <T> int createBean(T bean, String tableName) throws Exception { return this.createBean(bean, tableName, null); } /** * 在数据库中创建一个对象: 使用约定优于配置的方式 <br> * 1.所有的get属性的字段与数据库中对应 <br> * 2.表名与实体名对应(或者需要将表名传递进来)<br> * * @param <T> * @param bean * @return * @throws Exception */ public <T> int createBean(T bean, String tableName, LinkedList<String> ignoreFieldNames) throws Exception { // 分析bean中的数据 Class clazz = bean.getClass(); Map<String, Object> data = new LinkedHashMap<String, Object>(); Field[] fields = clazz.getDeclaredFields(); Method[] allMethods = clazz.getMethods(); for (Field f : fields) { if (!Modifier.isStatic(f.getModifiers())) { String name = f.getName(); if (ignoreFieldNames != null && ignoreFieldNames.contains(name)) { continue; } // 忽略javabean字段的大小写 Method method = this.getMethod(allMethods,"get", name); if (method != null) { data.put(f.getName(), method.invoke(bean, new Object[0])); } } } // 合成insert SQL语句 StringBuffer sql = new StringBuffer("INSERT INTO " + tableName + data.keySet().toString().replace("[", "(").replace("]", ")") + " VALUES("); LinkedList<Map.Entry<String, Object>> entrys = new LinkedList<Map.Entry<String, Object>>( data.entrySet()); int size = entrys.size(); Object[] params = new Object[size]; for (int i = 0; i < size; i++) { Map.Entry<String, Object> entry = entrys.get(i); sql.append("?"); if (i != size - 1) { sql.append(","); } params[i] = entry.getValue(); } sql.append(")"); // 执行sql return this.execute(sql.toString(), params); } public <T> int createBean(T bean) throws Exception { return this.createBean(bean, bean.getClass().getSimpleName()); } /** * * @param <T> * @param bean * @param idcol * @param tableName * @return * @throws Exception */ private static boolean isIgnoreCols(String colName, String[] ignoreCols) { for (String ignoreCol : ignoreCols) { if (ignoreCol.equalsIgnoreCase(colName)) { return true; } } return false; } public <T> int updateBeanByCondition(T bean, String condition, String tableName) throws Exception { return updateBeanByCondition(bean, condition, tableName, new String[0]); } public <T> int updateBeanByCondition(T bean, String condition, String tableName, String[] ignoreCols) throws Exception { // 分析bean中的数据 Class clazz = bean.getClass(); Map<String, Object> data = new LinkedHashMap<String, Object>(); Field[] fields = clazz.getDeclaredFields(); Method[] allMethods = clazz.getMethods(); for (Field f : fields) { if (!Modifier.isStatic(f.getModifiers())) { String name = f.getName(); // 有需要忽略的列,则不生成指定的字段的sql if (ignoreCols != null && isIgnoreCols(name, ignoreCols)) { continue; } Method method = this.getMethod(allMethods,"get", name); if (method != null) { Object value = method.invoke(bean, new Object[0]); if (value != null) { data.put(f.getName() + "=?", value); } } } } // 合成update SQL语句 String sql = "UPDATE " + tableName + " SET " + data.keySet().toString().replace("[", "").replace("]", "") + " WHERE " + condition; return this.execute(sql.toString(), data.values().toArray()); } public <T> int updateBean(T bean, String idcol, String tableName, String[] ignoreCols) throws Exception { // 分析bean中的数据 Class clazz = bean.getClass(); Map<String, Object> data = new LinkedHashMap<String, Object>(); Field[] fields = clazz.getDeclaredFields(); Method[] allMethods = clazz.getMethods(); Object idvalue = ""; for (Field f : fields) { if (!Modifier.isStatic(f.getModifiers())) { String name = f.getName(); // 有需要忽略的列,则不生成指定的字段的sql if (ignoreCols != null && isIgnoreCols(name, ignoreCols)) { continue; } Method method = this.getMethod(allMethods,"get", name); if (method != null) { Object value = method.invoke(bean, new Object[0]); data.put(f.getName() + "=?", value); if (name.equals(idcol)) {// 获得ID条件 idvalue = value; } } } } // 合成update SQL语句 String sql = "UPDATE " + tableName + " SET " + data.keySet().toString().replace("[", "").replace("]", "") + " WHERE " + idcol + "='" + idvalue + "'"; return this.execute(sql.toString(), data.values().toArray()); } /** * 执行批量sql语句 * @param sql * @return * @throws Exception */ public int[] excute(String[] sql) throws Exception { Connection conn = getConnection(); Statement sta = null; try { sta = conn.createStatement(); for(String temp : sql) { sta.addBatch(temp); } return sta.executeBatch(); } finally { cleanup(sta); closeConnection(); } } /** * 执行批量sql语句 * @param sql * @return * @throws Exception */ public int[] excutePrepare(String sql, LinkedList<Object[]> params) throws Exception { Connection conn = getConnection(); PreparedStatement ps = null; try { ps = conn.prepareStatement(sql); int count = 1; for(Object[] temp : params) { int i = 1; for(Object tp1 : temp) { if(tp1 instanceof Integer) { ps.setInt(i, (Integer) tp1); } else if(tp1 instanceof Double) { ps.setDouble(i, (Double) tp1); } else if(tp1 instanceof String) { ps.setString(i, (String) tp1); } else if(tp1 instanceof Date) { ps.setDate(i, (java.sql.Date) tp1); } i ++; } ps.addBatch(); if(count% 50 ==0) { ps.executeBatch(); ps.clearBatch(); } count ++; } return ps.executeBatch(); } finally { cleanup(ps); closeConnection();; } } }
package com.kingdee.dao; import org.springframework.stereotype.Component; @Component("page") public class MySQLPage implements IPage{ public String formatPageSQL(String sql, int offset, int limit) { // TODO Auto-generated method stub if(offset<0){ offset=0; } if(limit<0){ limit=0; } if(offset==0&&limit==0){ return sql; } if(offset>0&&limit==0){ limit = Integer.MAX_VALUE; } sql = sql + "limit " + offset + " , "+ limit; return sql; } }
package com.kingdee.dao; import java.math.BigDecimal; import java.sql.Blob; import java.sql.Clob; import java.sql.ResultSet; import java.sql.SQLException; public class JdbcUtil { /** * * @param rs * @param index * @param requiredType * @return * @throws SQLException */ public static Object getResultSetValue(ResultSet rs, int index, Class requiredType) throws SQLException { if (requiredType == null) { return getResultSetValue(rs, index); } Object value = null; boolean wasNullCheck = false; // Explicitly extract typed value, as far as possible. if (String.class.equals(requiredType)) { value = rs.getString(index); } else if (boolean.class.equals(requiredType) || Boolean.class.equals(requiredType)) { value = rs.getBoolean(index); wasNullCheck = true; } else if (byte.class.equals(requiredType) || Byte.class.equals(requiredType)) { value = rs.getByte(index); wasNullCheck = true; } else if (short.class.equals(requiredType) || Short.class.equals(requiredType)) { value = rs.getShort(index); wasNullCheck = true; } else if (int.class.equals(requiredType) || Integer.class.equals(requiredType)) { value = rs.getInt(index); wasNullCheck = true; } else if (long.class.equals(requiredType) || Long.class.equals(requiredType)) { value = rs.getLong(index); wasNullCheck = true; } else if (float.class.equals(requiredType) || Float.class.equals(requiredType)) { value = rs.getFloat(index); wasNullCheck = true; } else if (double.class.equals(requiredType) || Double.class.equals(requiredType) || Number.class.equals(requiredType)) { value = rs.getDouble(index); wasNullCheck = true; } else if (byte[].class.equals(requiredType)) { value = rs.getBytes(index); } else if (java.sql.Date.class.equals(requiredType)) { value = rs.getDate(index); } else if (java.sql.Time.class.equals(requiredType)) { value = rs.getTime(index); } else if (java.sql.Timestamp.class.equals(requiredType) || java.util.Date.class.equals(requiredType)) { value = rs.getTimestamp(index); } else if (BigDecimal.class.equals(requiredType)) { value = rs.getBigDecimal(index); } else if (Blob.class.equals(requiredType)) { value = rs.getBlob(index); } else if (Clob.class.equals(requiredType)) { value = rs.getClob(index); } else { // Some unknown type desired -> rely on getObject. value = getResultSetValue(rs, index); } // Perform was-null check if demanded (for results that the // JDBC driver returns as primitives). if (wasNullCheck && value != null && rs.wasNull()) { value = null; } return value; } /** * @see org.springframework.jdbc.support.JdbcUtils * @param rs * @param index * @return * @throws SQLException */ public static Object getResultSetValue(ResultSet rs, int index) throws SQLException { return org.springframework.jdbc.support.JdbcUtils.getResultSetValue(rs, index); } }
package com.kingdee.dao; public interface IPage { public String formatPageSQL(String sql, int offset, int limit); }