/* * Copyright 2006-2020 www.anyline.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * */ package org.anyline.dao.impl.springjdbc; import org.anyline.cache.PageLazyStore; import org.anyline.dao.AnylineDao; import org.anyline.dao.impl.BatchInsertStore; import org.anyline.entity.DataRow; import org.anyline.entity.DataSet; import org.anyline.entity.PageNavi; import org.anyline.jdbc.config.ConfigParser; import org.anyline.jdbc.config.ConfigStore; import org.anyline.jdbc.config.db.Procedure; import org.anyline.jdbc.config.db.SQL; import org.anyline.jdbc.config.db.impl.ProcedureParam; import org.anyline.jdbc.config.db.run.RunSQL; import org.anyline.jdbc.config.db.sql.auto.TableSQL; import org.anyline.jdbc.ds.DataSourceHolder; import org.anyline.jdbc.exception.SQLQueryException; import org.anyline.jdbc.exception.SQLUpdateException; import org.anyline.jdbc.util.SQLCreaterUtil; import org.anyline.util.BasicUtil; import org.anyline.util.ConfigTable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.CallableStatementCallback; import org.springframework.jdbc.core.CallableStatementCreator; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.PreparedStatementCreator; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.KeyHolder; import org.springframework.stereotype.Repository; import java.sql.*; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @Repository("anyline.dao") public class AnylineDaoImpl implements AnylineDao { protected static final Logger log = LoggerFactory.getLogger(AnylineDaoImpl.class); @Autowired(required=false) protected JdbcTemplate jdbc; public JdbcTemplate getJdbc(){ return jdbc; } protected BatchInsertStore batchInsertStore = new BatchInsertStore(); protected static boolean showSQL = false; protected static boolean showSQLParam = false; protected static boolean showSQLWhenError = true; protected static boolean showSQLParamWhenError = true; protected static boolean isBatchInsertRun = false; public AnylineDaoImpl(){ showSQL = ConfigTable.getBoolean("SHOW_SQL",showSQL); showSQLParam = ConfigTable.getBoolean("SHOW_SQL_PARAM",showSQLParam); showSQLWhenError = ConfigTable.getBoolean("SHOW_SQL_WHEN_ERROR",showSQLWhenError); showSQLParamWhenError = ConfigTable.getBoolean("SHOW_SQL_PARAM_WHEN_ERROR",showSQLParamWhenError); } /** * 查询 */ @Override public List<Map<String,Object>> maps(SQL sql, ConfigStore configs, String ... conditions) { List<Map<String,Object>> maps = null; try { RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createQueryRunSQL(sql, configs, conditions); if (showSQL && !run.isValid()) { String tmp = "[valid:false]"; String src = ""; if (sql instanceof TableSQL) { src = sql.getTable(); } else { src = sql.getText(); } tmp += "[SQL:" + ConfigParser.createSQLSign(false, false, src, configs, conditions) + "][thread:" + Thread.currentThread().getId() + "][ds:" + DataSourceHolder.getDataSource() + "]"; log.warn(tmp); } if (run.isValid()) { maps = maps(run.getFinalQueryTxt(), run.getValues()); } else { maps = new ArrayList<Map<String,Object>>(); } }finally { //自动切换回默认数据源 if(DataSourceHolder.isAutoDefault()){ DataSourceHolder.recoverDataSource(); } } return maps; } public List<Map<String,Object>> maps(SQL sql, String ... conditions){ return maps(sql, null, conditions); } /** * 查询 */ @Override public DataSet querys(SQL sql, ConfigStore configs, String ... conditions) { DataSet set = null; try { RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createQueryRunSQL(sql, configs, conditions); if (showSQL && !run.isValid()) { String tmp = "[valid:false]"; String src = ""; if (sql instanceof TableSQL) { src = sql.getTable(); } else { src = sql.getText(); } tmp += "[SQL:" + ConfigParser.createSQLSign(false, false, src, configs, conditions) + "][thread:" + Thread.currentThread().getId() + "][ds:" + DataSourceHolder.getDataSource() + "]"; log.warn(tmp); } PageNavi navi = run.getPageNavi(); int total = 0; if (run.isValid()) { if (null != navi) { if (navi.getLastRow() == 0) { //第一条 total = 1; } else { //未计数(总数 ) if (navi.getTotalRow() == 0) { total = getTotal(run.getTotalQueryTxt(), run.getValues()); navi.setTotalRow(total); } else { total = navi.getTotalRow(); } } } if (showSQL) { log.warn("[查询记录总数][行数:{}]", total); } } if (run.isValid() && (null == navi || total > 0)) { set = select(run.getFinalQueryTxt(), run.getValues()); } else { set = new DataSet(); } set.setDataSource(sql.getDataSource()); set.addQueryParam("query_config", configs) .addQueryParam("query_condition", conditions) .addQueryParam("query_order", run.getOrderStore()) .addQueryParam("query_column", sql.getColumns()); // set.setSchema(sql.getSchema()); // set.setTable(sql.getTable()); set.setNavi(navi); if (null != navi && navi.isLazy()) { PageLazyStore.setTotal(navi.getLazyKey(), navi.getTotalRow()); } }finally { //自动切换回默认数据源 if(DataSourceHolder.isAutoDefault()){ DataSourceHolder.recoverDataSource(); } } return set; } public DataSet querys(SQL sql, String ... conditions){ return querys(sql, null, conditions); } /** * 查询 */ @Override public DataSet selects(SQL sql, ConfigStore configs, String ... conditions) { return querys(sql, configs, conditions); } public DataSet selects(SQL sql, String ... conditions){ return querys(sql, null, conditions); } public int count(SQL sql, ConfigStore configs, String ... conditions){ int count = -1; try{ RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createQueryRunSQL(sql, configs, conditions); count = getTotal(run.getTotalQueryTxt(), run.getValues()); }finally{ //自动切换回默认数据源 if(DataSourceHolder.isAutoDefault()){ DataSourceHolder.recoverDataSource(); } } return count; } public int count(SQL sql, String ... conditions){ return count(sql, null, conditions); } public boolean exists(SQL sql, ConfigStore configs, String ... conditions){ boolean result = false; try { RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createQueryRunSQL(sql, configs, conditions); String txt = run.getExistsTxt(); List<Object> values = run.getValues(); long fr = System.currentTimeMillis(); String random = ""; if (showSQL) { random = "[SQL:" + System.currentTimeMillis() + "-" + BasicUtil.getRandomNumberString(8) + "][thread:" + Thread.currentThread().getId() + "][ds:" + DataSourceHolder.getDataSource() + "]"; log.warn("{}[txt:\n{}\n]", random, txt); log.warn("{}[参数:{}]", random, paramLogFormat(values)); } /*执行SQL*/ try { Map<String, Object> map = null; if (null != values && values.size() > 0) { map = getJdbc().queryForMap(txt, values.toArray()); } else { map = getJdbc().queryForMap(txt); } if (null == map) { result = false; } else { result = BasicUtil.parseBoolean(map.get("IS_EXISTS"), false); } if (showSQL) { log.warn("{}[执行耗时:{}ms][影响行数:{}]", random, System.currentTimeMillis() - fr, result); } } catch (Exception e) { log.error(random + "异常:" + e); if (showSQLWhenError) { log.error(random + "[异常TXT:\n{}\n]", sql); log.error(random + "[异常参数:{}]", paramLogFormat(values)); } throw new SQLQueryException("查询异常:" + e); } }finally { //自动切换回默认数据源 if(DataSourceHolder.isAutoDefault()){ DataSourceHolder.recoverDataSource(); } } return result; } public boolean exists(SQL sql, String ... conditions){ return exists(sql, null, conditions); } /** * 总记录数 * @param sql sql * @param values values * @return return */ protected int getTotal(String sql, List<Object> values) { int total = 0; DataSet set = select(sql,values); total = set.getInt(0,"CNT",0); return total; } /** * 更新记录 * @param obj 需要更新的数据 row 需要更新的数据 * @param dest dest * @param columns 需要更新的列 columns 需要更新的列 * @return return */ @Override public int update(String dest, Object obj, String ... columns ){ if(null == obj){ throw new SQLUpdateException("更新空数据"); } int result = 0; if(obj instanceof DataSet){ DataSet set = (DataSet)obj; for(int i=0; i<set.size(); i++){ result += update(dest, set.getRow(i), columns); } return result; } RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createUpdateTxt(dest, obj, false, columns); String sql = run.getUpdateTxt(); if(BasicUtil.isEmpty(sql)){ log.warn("[不具备更新条件][dest:{}]",dest); return -1; } List<Object> values = run.getValues(); long fr = System.currentTimeMillis(); String random = ""; if(showSQL){ random = "[SQL:" + System.currentTimeMillis() + "-" + BasicUtil.getRandomNumberString(8) + "][thread:"+Thread.currentThread().getId()+"][ds:"+ DataSourceHolder.getDataSource()+"]"; log.warn(random + "[txt:\n{}\n]",sql); log.warn(random + "[参数:{}]",paramLogFormat(values)); } /*执行SQL*/ try{ result = getJdbc().update(sql, values.toArray()); if(showSQL){ log.warn(random + "[执行耗时:{}ms][影响行数:{}]",System.currentTimeMillis() - fr,result); } }catch(Exception e){ e.printStackTrace(); if(showSQLWhenError){ log.error(random + "[异常][txt:\n{}\n]",sql); log.error(random + "[异常参数][param:{}]",paramLogFormat(values)); } throw new SQLUpdateException("更新异常:" + e); }finally{ //自动切换回默认数据源 if(DataSourceHolder.isAutoDefault()){ DataSourceHolder.recoverDataSource(); } } return result; } @Override public int update(Object data, String ... columns){ return update(null, data, columns); } /** * 保存(insert|upate) */ @Override public int save(String dest, Object data, boolean checkParimary, String ... columns){ if(null == data){ throw new SQLUpdateException("保存空数据"); } if(data instanceof Collection){ Collection<?> items = (Collection<?>)data; int cnt = 0; for(Object item:items){ cnt += save(dest, item, checkParimary, columns); } return cnt; } return saveObject(dest, data, checkParimary, columns); } @Override public int save(Object data, boolean checkParimary, String ... columns){ return save(null, data, checkParimary, columns); } @Override public int save(String dest, Object data, String ... columns){ return save(dest, data, false, columns); } @Override public int save(Object data, String ... columns){ return save(null, data, false, columns); } protected int saveObject(String dest, Object data, boolean checkParimary, String ... columns){ if(null == data){ return 0; } if(checkIsNew(data)){ return insert(dest, data, checkParimary, columns); }else{ return update(dest, data, columns); } } protected boolean checkIsNew(Object obj){ if(null == obj){ return false; } if(obj instanceof DataRow){ DataRow row = (DataRow)obj; return row.isNew(); } return false; } /** * 添加 * @param checkParimary 是否需要检查重复主键,默认不检查 * @param columns 需要插入的列 * @param dest dest * @param data data * @return return */ @Override public int insert(String dest, Object data, boolean checkParimary, String ... columns){ RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createInsertTxt(dest, data, checkParimary, columns); if(null == run){ return 0; } int cnt = 0; final String sql = run.getInsertTxt(); final List<Object> values = run.getValues(); KeyHolder keyholder = new GeneratedKeyHolder(); long fr = System.currentTimeMillis(); String random = ""; if(showSQL){ random = "[SQL:" + System.currentTimeMillis() + "-" + BasicUtil.getRandomNumberString(8) + "][thread:"+Thread.currentThread().getId()+"][ds:"+ DataSourceHolder.getDataSource()+"]"; log.warn(random + "[txt:\n{}\n]",sql); log.warn(random + "[参数:{}]",paramLogFormat(values)); } try{ cnt= getJdbc().update(new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement ps = con.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS); int idx = 0; if(null != values){ for(Object obj:values){ ps.setObject(++idx, obj); } } return ps; } }, keyholder); if (cnt == 1) { try{ int id = (int)keyholder.getKey().longValue(); setPrimaryValue(data, id); }catch(Exception e){ } } if(showSQL){ log.warn(random + "[执行耗时:{}ms][影响行数:{}]",System.currentTimeMillis() - fr,cnt); } }catch(Exception e){ e.printStackTrace(); if(showSQLWhenError){ log.error(random + "[异常][txt:\n{}\n]",sql); log.error(random + "[异常参数][param:{}]",paramLogFormat(values)); } throw new SQLUpdateException("插入异常:" + e); }finally{ //自动切换回默认数据源 if(DataSourceHolder.isAutoDefault()){ DataSourceHolder.recoverDataSource(); } } return cnt; } @Override public int insert(Object data, boolean checkParimary, String ... columns){ return insert(null, data, checkParimary, columns); } @Override public int insert(String dest, Object data, String ... columns){ return insert(dest, data, false, columns); } @Override public int insert(Object data, String ... columns){ return insert(null, data, false, columns); } @Override public int batchInsert(final String dest, final Object data, final boolean checkParimary, final String ... columns){ if(null == data){ return 0; } if(data instanceof DataSet){ DataSet set = (DataSet)data; int size = set.size(); for(int i=0; i<size; i++){ batchInsert(dest, set.getRow(i), checkParimary, columns); } } String table = DataSourceHolder.parseDataSource(dest,data);//SQLCreaterUtil.getCreater(getJdbc()).getDataSource(data); List<String> cols = SQLCreaterUtil.getCreater(getJdbc()).confirmInsertColumns(dest, data, columns); String strCols = ""; int size = cols.size(); for(int i=0; i<size; i++){ String col = cols.get(i); strCols += "," +col; } synchronized (batchInsertStore) { batchInsertStore.addData(table, strCols,(DataRow)data); if(!isBatchInsertRun){ isBatchInsertRun = true; new Thread(new Runnable(){ public void run(){ try{ while(true){ DataSet list = batchInsertStore.getDatas(); if(null != list && list.size()>0){ insert(dest, list, checkParimary, columns); }else{ Thread.sleep(1000*10); } } }catch(Exception e){ e.printStackTrace(); } } }).start(); } } return 0; } @Override public int batchInsert(Object data, boolean checkParimary, String ... columns){ return batchInsert(null, data, checkParimary, columns); } @Override public int batchInsert(String dest, Object data, String ... columns){ return batchInsert(dest, data, false, columns); } @Override public int batchInsert(Object data, String ... columns){ return batchInsert(null, data, false, columns); } protected void setPrimaryValue(Object obj, int value){ if(null == obj){ return; } if(obj instanceof DataRow){ DataRow row = (DataRow)obj; row.put(row.getPrimaryKey(), value); }else{ // String key = BeanUtil.getPrimaryKey(obj.getClass()); // BeanUtil.setFieldValue(obj, key, value); } } /** * 查询 * @param sql sql * @param values values * @return return */ protected List<Map<String,Object>> maps(String sql, List<Object> values){ List<Map<String,Object>> maps = null; if(BasicUtil.isEmpty(sql)){ throw new SQLQueryException("未指定SQL"); } long fr = System.currentTimeMillis(); String random = ""; if(showSQL){ random = "[SQL:" + System.currentTimeMillis() + "-" + BasicUtil.getRandomNumberString(8) + "][thread:"+Thread.currentThread().getId()+"][ds:"+ DataSourceHolder.getDataSource()+"]"; log.warn(random + "[txt:\n{}\n]",sql); log.warn(random + "[参数:{}]",paramLogFormat(values)); } try{ if(null != values && values.size()>0){ maps = getJdbc().queryForList(sql, values.toArray()); }else{ maps = getJdbc().queryForList(sql); } long mid = System.currentTimeMillis(); if(showSQL){ log.warn(random + "[执行耗时:{}ms]",mid - fr); } if(showSQL){ log.warn(random + "[封装耗时:{}ms][封装行数:{}]",System.currentTimeMillis() - mid,maps.size() ); } }catch(Exception e){ e.printStackTrace(); if(showSQLWhenError){ log.error(random + "[异常][txt:\n{}\n]",sql); log.error(random + "[异常][参数:{}]",paramLogFormat(values)); } throw new SQLQueryException("查询异常:" + e + "\ntxt:" + sql + "\nparam:" + values); } return maps; } /** * 查询 * @param sql sql * @param values values * @return return */ protected DataSet select(String sql, List<Object> values){ if(BasicUtil.isEmpty(sql)){ throw new SQLQueryException("未指定SQL"); } long fr = System.currentTimeMillis(); String random = ""; if(showSQL){ random = "[SQL:" + System.currentTimeMillis() + "-" + BasicUtil.getRandomNumberString(8) + "][thread:"+Thread.currentThread().getId()+"][ds:"+ DataSourceHolder.getDataSource()+"]"; log.warn(random + "[txt:\n{}\n]",sql); log.warn(random + "[参数:{}]",paramLogFormat(values)); } DataSet set = new DataSet(); try{ List<Map<String,Object>> list = null; if(null != values && values.size()>0){ list = getJdbc().queryForList(sql, values.toArray()); }else{ list = getJdbc().queryForList(sql); } long mid = System.currentTimeMillis(); if(showSQL){ log.warn(random + "[执行耗时:{}ms]",mid - fr); } for(Map<String,Object> map:list){ DataRow row = new DataRow(map); row.clearUpdateColumns(); set.add(row); } set.setDatalink(DataSourceHolder.getDataSource()); if(showSQL){ log.warn(random + "[封装耗时:{}ms][封装行数:{}]",System.currentTimeMillis() - mid,list.size() ); } }catch(Exception e){ e.printStackTrace(); if(showSQLWhenError){ log.error(random + "[异常][txt:\n{}\n]",sql); log.error(random + "[异常][参数:{}]",paramLogFormat(values)); } throw new SQLQueryException("查询异常:" + e + "\ntxt:" + sql + "\nparam:" + values); } return set; } @Override public int execute(SQL sql, ConfigStore configs, String ... conditions){ int result = -1; RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createExecuteRunSQL(sql, configs, conditions); if(!run.isValid()){ if(showSQL){ log.warn("[valid:false]"); } return -1; } String txt = run.getExecuteTxt(); List<Object> values = run.getValues(); long fr = System.currentTimeMillis(); String random = ""; if(showSQL){ random = "[SQL:" + System.currentTimeMillis() + "-" + BasicUtil.getRandomNumberString(8) + "][thread:"+Thread.currentThread().getId()+"][ds:"+ DataSourceHolder.getDataSource()+"]"; log.warn(random + "[txt:\n{}\n]", txt); log.warn(random + "[参数:{}]",paramLogFormat(values)); } try{ if(null != values && values.size() > 0){ result = getJdbc().update(txt, values.toArray()); }else{ result = getJdbc().update(txt); } if(showSQL){ log.warn(random + "[执行耗时:{}ms][影响行数:{}]",System.currentTimeMillis()-fr,result); } }catch(Exception e){ log.error(random+":" + e); if(showSQLWhenError){ log.error(random + "[异常][txt:\n{}\n]",sql); log.error(random + "[异常][参数:{}]",paramLogFormat(values)); } throw new SQLUpdateException(random + "执行异常:" + e + "\nTXT:" + txt + "\nPARAM:" + values); }finally{ //自动切换回默认数据源 if(DataSourceHolder.isAutoDefault()){ DataSourceHolder.recoverDataSource(); } } return result; } @Override public int execute(SQL sql, String ... conditions){ return execute(sql, null, conditions); } // @SuppressWarnings("unchecked") // @Override // public boolean executeProcedure(Procedure procedure){ // boolean result = false; // List<Object> list = new ArrayList<Object>(); // final List<String> inputValues = procedure.getInputValues(); // final List<Integer> inputTypes = procedure.getInputTypes(); // final List<Integer> outputTypes = procedure.getOutputTypes(); // long fr = System.currentTimeMillis(); // String random = ""; // if(showSQL){ // random = "[SQL:" + System.currentTimeMillis() + "-" + BasicUtil.getRandomNumberString(8) + "][thread:"+Thread.currentThread().getId()+"][ds:"+DataSourceHolder.getDataSource()+"]"; // log.warn(random + "[txt:\n{}\n]",procedure.getName() ); // log.warn(random + "[参数:{}]",paramLogFormat(inputValues)); // } // String sql = "{call " +procedure.getName()+"("; // final int sizeIn = null == inputTypes? 0 : inputTypes.size(); // final int sizeOut = null == outputTypes? 0 : outputTypes.size(); // final int size = sizeIn + sizeOut; // for(int i=0; i<size; i++){ // sql += "?"; // if(i < size-1){ // sql += ","; // } // } // sql += ")}"; // try{ // list = (List<Object>)getJdbc().execute(sql,new CallableStatementCallback<Object>(){ // public Object doInCallableStatement(final CallableStatement cs) throws SQLException, DataAccessException { // final List<Object> result = new ArrayList<Object>(); // for(int i=1; i<=sizeIn; i++){ // Object value = inputValues.get(i-1); // if(null == value || "NULL".equalsIgnoreCase(value.toString())){ // value = null; // } // cs.setObject(i, value, inputTypes.get(i-1)); // } // for(int i=1; i<=sizeOut; i++){ // cs.registerOutParameter(i+sizeIn, outputTypes.get(i-1)); // } // if(sizeOut > 0){ // //注册输出参数 // cs.execute(); // for(int i=1; i<=sizeOut; i++){ // final Object output = cs.getObject(sizeIn+i); // result.add(output); // } // }else{ // cs.execute(); // } // return result; // } // }); // // if(showSQL){ // log.warn(random + "[执行耗时:{}ms]",System.currentTimeMillis()-fr); // log.warn(random + "[输出参数:{}]",list); // } // procedure.setResult(list); // result = true; // }catch(Exception e){ // result = false; // log.error(random+":" +e); // if(showSQLWhenError){ // log.error(random + "[异常][txt:\n{}\n]",sql); // log.error(random + "[异常][参数:{}]",paramLogFormat(inputValues)); // } // e.printStackTrace(); // throw new SQLUpdateException("PROCEDURE执行异常:" + e + "\nPROCEDURE:" + procedure.getName() + "\nPARAM:" + procedure.getInputValues()); // }finally{ // //自动切换回默认数据源 // if(DataSourceHolder.isAutoDefault()){ // DataSourceHolder.recoverDataSource(); // } // } // return result; // } @Override public boolean execute(Procedure procedure){ boolean result = false; List<Object> list = new ArrayList<Object>(); final List<ProcedureParam> inputs = procedure.getInputs(); final List<ProcedureParam> outputs = procedure.getOutputs(); long fr = System.currentTimeMillis(); String random = ""; if(showSQL){ random = "[SQL:" + System.currentTimeMillis() + "-" + BasicUtil.getRandomNumberString(8) + "][thread:"+Thread.currentThread().getId()+"][ds:"+ DataSourceHolder.getDataSource()+"]"; log.warn("{}[txt:\n{}\n]",random,procedure.getName() ); log.warn("{}[输入参数:{}]",random,paramLogFormat(inputs)); log.warn("{}[输出参数:{}]",random,paramLogFormat(outputs)); } String sql = "{call " +procedure.getName()+"("; final int sizeIn = inputs.size(); final int sizeOut = outputs.size(); final int size = sizeIn + sizeOut; for(int i=0; i<size; i++){ sql += "?"; if(i < size-1){ sql += ","; } } sql += ")}"; try{ list = (List<Object>)getJdbc().execute(sql,new CallableStatementCallback<Object>(){ public Object doInCallableStatement(final CallableStatement cs) throws SQLException, DataAccessException { final List<Object> result = new ArrayList<Object>(); for(int i=1; i<=sizeIn; i++){ ProcedureParam param = inputs.get(i-1); Object value = param.getValue(); if(null == value || "NULL".equalsIgnoreCase(value.toString())){ value = null; } cs.setObject(i, value, param.getType()); } for(int i=1; i<=sizeOut; i++){ ProcedureParam param = outputs.get(i-1); if(null == param.getValue()){ cs.registerOutParameter(i+sizeIn, param.getType()); }else{ cs.setObject(i+sizeIn, param.getValue(), param.getType()); } } if(sizeOut > 0){ //注册输出参数 cs.execute(); for(int i=1; i<=sizeOut; i++){ final Object output = cs.getObject(sizeIn+i); result.add(output); } }else{ cs.execute(); } return result; } }); if(showSQL){ log.warn("{}[执行耗时:{}ms]",random,System.currentTimeMillis()-fr); log.warn("{}[输出参数:{}]",random,list); } procedure.setResult(list); result = true; }catch(Exception e){ result = false; log.error(random+":" +e); if(showSQLWhenError){ log.error("{}[异常][txt:\n{}\n]",random,sql); log.error("{}[异常][输入参数:{}]",random,paramLogFormat(inputs)); log.error("{}[异常][输出参数:{}]",random,paramLogFormat(outputs)); } e.printStackTrace(); throw new SQLUpdateException("procedure执行异常:" + e + "\nprocedure:" + procedure.getName() + "\ninputs:" + paramLogFormat(inputs)+"\noutputs:"+paramLogFormat(outputs)); }finally{ //自动切换回默认数据源 if(DataSourceHolder.isAutoDefault()){ DataSourceHolder.recoverDataSource(); } } return result; } /** * 根据存储过程查询(MSSQL AS 后必须加 SET NOCOUNT ON) * @param procedure procedure * @return return */ @Override public DataSet query(final Procedure procedure){ final List<ProcedureParam> inputs = procedure.getInputs(); final List<ProcedureParam> outputs = procedure.getOutputs(); long fr = System.currentTimeMillis(); String random = ""; if(showSQL){ random = "[SQL:" + System.currentTimeMillis() + "-" + BasicUtil.getRandomNumberString(8) + "][thread:"+Thread.currentThread().getId()+"][ds:"+ DataSourceHolder.getDataSource()+"]"; log.warn("{}[txt:\n{}\n]", random, procedure.getName()); log.warn("{}[输入参数:{}]", random, paramLogFormat(inputs)); log.warn("{}[输出参数:{}]", random, paramLogFormat(inputs)); } final String rdm = random; DataSet set = null; try{ set = (DataSet)getJdbc().execute(new CallableStatementCreator(){ public CallableStatement createCallableStatement(Connection conn) throws SQLException { String sql = "{call " +procedure.getName()+"("; final int sizeIn = inputs.size(); final int sizeOut = outputs.size(); final int size = sizeIn + sizeOut; for(int i=0; i<size; i++){ sql += "?"; if(i < size-1){ sql += ","; } } sql += ")}"; CallableStatement cs = conn.prepareCall(sql); for(int i=1; i<=sizeIn; i++){ ProcedureParam param = inputs.get(i-1); Object value = param.getValue(); if(null == value || "NULL".equalsIgnoreCase(value.toString())){ value = null; } cs.setObject(i, value, param.getType()); } for(int i=1; i<=sizeOut; i++){ ProcedureParam param = outputs.get(i-1); if(null == param.getValue()){ cs.registerOutParameter(i+sizeIn, param.getType()); }else{ cs.setObject(i, param.getValue(), param.getType()); } } return cs; } }, new CallableStatementCallback<Object>(){ public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException { ResultSet rs = cs.executeQuery(); DataSet set = new DataSet(); ResultSetMetaData rsmd = rs.getMetaData(); int cols = rsmd.getColumnCount(); for(int i=1; i<=cols; i++){ set.addHead(rsmd.getColumnName(i)); } long mid = System.currentTimeMillis(); while(rs.next()){ DataRow row = new DataRow(); for(int i=1; i<=cols; i++){ row.put(rsmd.getColumnName(i), rs.getObject(i)); } set.addRow(row); } set.setDatalink(DataSourceHolder.getDataSource()); if(showSQL){ log.warn("{}[封装耗时:{}ms][封装行数:{}]", rdm, System.currentTimeMillis() - mid,set.size()); } return set; } }); if(showSQL){ log.warn("{}[执行耗时:{}ms]", random,System.currentTimeMillis() - fr); } }catch(Exception e){ e.printStackTrace(); if(showSQLWhenError){ log.error("{}[异常][txt:\n{}\n]",random,procedure.getName()); log.error("{}[输入参数:{}]",random,paramLogFormat(inputs)); log.error("{}[输出参数:{}]",random,paramLogFormat(inputs)); } throw new SQLQueryException("查询异常:" + e + "\nPROCEDURE:" + procedure.getName()); }finally{ //自动切换回默认数据源 if(DataSourceHolder.isAutoDefault()){ DataSourceHolder.recoverDataSource(); } } return set; } public int deletes(String table, String key, Collection<Object> values){ RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createDeleteRunSQL(table, key, values); int result = exeDelete(run); return result; } public int deletes(String table, String key, String ... values){ List<String> list = new ArrayList<String>(); if(null != values){ for(String value:values){ list.add(value); } } RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createDeleteRunSQL(table, key, list); int result = exeDelete(run); return result; } @Override public int delete(String dest, DataSet set, String... columns) { int size = 0; for(DataRow row:set){ size += delete(dest, row, columns); } return size; } @Override public int delete(String dest, DataRow row, String... columns) { RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createDeleteRunSQL(dest, row, columns); int result = exeDelete(run); return result; } @Override public int delete(String table, ConfigStore configs, String... conditions) { RunSQL run = SQLCreaterUtil.getCreater(getJdbc()).createDeleteRunSQL(table, configs, conditions); int result = exeDelete(run); return result; } protected int exeDelete(RunSQL run){ int result = 0; final String sql = run.getDeleteTxt(); final List<Object> values = run.getValues(); long fr = System.currentTimeMillis(); String random = ""; if(showSQL){ random = "[SQL:" + System.currentTimeMillis() + "-" + BasicUtil.getRandomNumberString(8) + "][thread:"+Thread.currentThread().getId()+"][ds:"+ DataSourceHolder.getDataSource()+"]"; log.warn("{}[txt:\n{}\n]",random,sql); log.warn("{}[参数:{}]",random,paramLogFormat(values)); } try{ result = getJdbc().update(sql,values.toArray()); // result = getJdbc().update( // new PreparedStatementCreator() { // public PreparedStatement createPreparedStatement(Connection con) throws SQLException // { // PreparedStatement ps = getJdbc().getDataSource().getConnection().prepareStatement(sql); // int idx = 0; // if(null != values){ // for(Object obj:values){ // ps.setObject(++idx, obj); // } // } // return ps; // } // }); if(showSQL){ log.warn("{}[执行耗时:{}ms][影响行数:{}]",random,System.currentTimeMillis()-fr,result); } result = 1; }catch(Exception e){ log.error("删除异常:" +e); if(showSQLWhenError){ log.error("{}[异常][txt:\n{}\n]",random,sql); log.error("{}[异常][参数:{}]",random, paramLogFormat(values)); } result = 0; throw new SQLUpdateException("删除异常:" + e); }finally{ //自动切换回默认数据源 if(DataSourceHolder.isAutoDefault()){ DataSourceHolder.recoverDataSource(); } } return result; } /** * 参数日志格式化 * @param params params * @return return */ protected String paramLogFormat(List<?> params){ String result = ""; if(null != params){ int idx = 0; for(Object param:params){ result += " param" + idx++ + "="; result += param; if(null != param){ result += "(" + param.getClass().getSimpleName() + ")"; } } } return result; } }