259 lines
6.4 KiB
Java
259 lines
6.4 KiB
Java
|
|
package com.pictc.jdbc;
|
||
|
|
|
||
|
|
import java.sql.CallableStatement;
|
||
|
|
import java.sql.Connection;
|
||
|
|
import java.sql.PreparedStatement;
|
||
|
|
import java.sql.ResultSet;
|
||
|
|
import java.sql.SQLException;
|
||
|
|
import java.sql.Statement;
|
||
|
|
import java.util.List;
|
||
|
|
import javax.sql.DataSource;
|
||
|
|
import org.springframework.dao.DataAccessException;
|
||
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||
|
|
import org.springframework.jdbc.datasource.DataSourceUtils;
|
||
|
|
import org.springframework.jdbc.support.JdbcUtils;
|
||
|
|
import com.pictc.jdbc.model.JdbcParam;
|
||
|
|
import com.pictc.utils.CollectionUtils;
|
||
|
|
import lombok.Getter;
|
||
|
|
import lombok.Setter;
|
||
|
|
import lombok.extern.slf4j.Slf4j;
|
||
|
|
|
||
|
|
@Slf4j
|
||
|
|
@Getter
|
||
|
|
@Setter
|
||
|
|
public class JdbcContext {
|
||
|
|
|
||
|
|
public static final int DEF_STEP = 1000;
|
||
|
|
|
||
|
|
private JdbcTemplate jdbc;
|
||
|
|
|
||
|
|
private DataSource source;
|
||
|
|
|
||
|
|
private DataSource logSource;
|
||
|
|
|
||
|
|
private Connection conn;
|
||
|
|
|
||
|
|
private PreparedStatement stmt;
|
||
|
|
|
||
|
|
private CallableStatement ctmt;
|
||
|
|
|
||
|
|
private long start;
|
||
|
|
|
||
|
|
private int size = 0;
|
||
|
|
|
||
|
|
private boolean isQuery = false;
|
||
|
|
|
||
|
|
private boolean isCall = false;
|
||
|
|
|
||
|
|
private boolean datalog = false;
|
||
|
|
|
||
|
|
private String sql;
|
||
|
|
|
||
|
|
private List<JdbcParam> params;
|
||
|
|
|
||
|
|
private List<List<JdbcParam>> batchParams;
|
||
|
|
|
||
|
|
public JdbcContext(boolean isQuery) throws SQLException {
|
||
|
|
this(isQuery, false);
|
||
|
|
}
|
||
|
|
|
||
|
|
public JdbcContext(boolean isQuery,boolean datalog) throws SQLException {
|
||
|
|
super();
|
||
|
|
this.isQuery = isQuery;
|
||
|
|
this.datalog = datalog;
|
||
|
|
this.start = System.currentTimeMillis();
|
||
|
|
this.source = JdbcContextUtils.getSource();
|
||
|
|
this.logSource = JdbcContextUtils.getLogSource();
|
||
|
|
this.jdbc = JdbcContextUtils.getJdbc();
|
||
|
|
this.conn = datalog?DataSourceUtils.getConnection(this.logSource):DataSourceUtils.getConnection(this.source);
|
||
|
|
}
|
||
|
|
|
||
|
|
public JdbcContext init(String sql) throws SQLException {
|
||
|
|
this.sql = sql;
|
||
|
|
this.stmt = (PreparedStatement) getStatement(this.conn,sql);
|
||
|
|
return this;
|
||
|
|
}
|
||
|
|
|
||
|
|
public DataSource getReleaseSource() {
|
||
|
|
return datalog?logSource:source;
|
||
|
|
}
|
||
|
|
|
||
|
|
public JdbcContext initCall(String sql) throws SQLException {
|
||
|
|
this.sql = sql;
|
||
|
|
this.isCall = true;
|
||
|
|
this.ctmt = (CallableStatement) getStatement(this.conn,sql);
|
||
|
|
return this;
|
||
|
|
}
|
||
|
|
|
||
|
|
public JdbcContext addParam(int jdbc,Object val) {
|
||
|
|
if(params==null) {
|
||
|
|
params = CollectionUtils.newArrayList();
|
||
|
|
}
|
||
|
|
params.add(new JdbcParam().setJdbc(jdbc).setVal(val));
|
||
|
|
return this;
|
||
|
|
}
|
||
|
|
|
||
|
|
public JdbcContext addBatchParam(int index,int jdbc,Object val) {
|
||
|
|
if(batchParams==null) {
|
||
|
|
batchParams = CollectionUtils.newArrayList();
|
||
|
|
}
|
||
|
|
|
||
|
|
if(batchParams.size() <=index) {
|
||
|
|
batchParams.add(CollectionUtils.newArrayList());
|
||
|
|
}
|
||
|
|
List<JdbcParam> bpam = batchParams.get(index);
|
||
|
|
bpam.add(new JdbcParam().setJdbc(jdbc).setVal(val));
|
||
|
|
return this;
|
||
|
|
}
|
||
|
|
|
||
|
|
private Statement getStatement(Connection conn,String sql) throws SQLException {
|
||
|
|
Statement stmt = null;
|
||
|
|
if(this.isCall) {
|
||
|
|
stmt = conn.prepareCall(sql);
|
||
|
|
}else if(this.isQuery) {
|
||
|
|
stmt = conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
|
||
|
|
}else {
|
||
|
|
stmt = conn.prepareStatement(sql);
|
||
|
|
}
|
||
|
|
int fetchSize = jdbc.getFetchSize();
|
||
|
|
if (fetchSize >= 0) {
|
||
|
|
stmt.setFetchSize(fetchSize);
|
||
|
|
}
|
||
|
|
int maxRows = jdbc.getMaxRows();
|
||
|
|
if (maxRows >= 0) {
|
||
|
|
stmt.setMaxRows(maxRows);
|
||
|
|
}
|
||
|
|
DataSourceUtils.applyTimeout(stmt,getReleaseSource(),jdbc.getQueryTimeout());
|
||
|
|
return stmt;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void executeParams() throws SQLException {
|
||
|
|
if(params!=null) {
|
||
|
|
for (int i = 0; i < params.size(); i++) {
|
||
|
|
JdbcParam parameter = params.get(i);
|
||
|
|
int index = i+1;
|
||
|
|
if(parameter.isOut()) {
|
||
|
|
ctmt.registerOutParameter(index,parameter.getJdbc());
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
this.setParameter(index,parameter.getJdbc(),parameter.getVal());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public int executeUpdate() throws SQLException {
|
||
|
|
executeParams();
|
||
|
|
size = this._executeUpdate();
|
||
|
|
return size;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public boolean execute() throws SQLException {
|
||
|
|
executeParams();
|
||
|
|
return this._execute();
|
||
|
|
}
|
||
|
|
|
||
|
|
public int executeBatch() throws SQLException {
|
||
|
|
return executeBatch(DEF_STEP);
|
||
|
|
}
|
||
|
|
|
||
|
|
public int executeBatch(int step) throws SQLException {
|
||
|
|
int rows = 0;
|
||
|
|
step = step <=0?DEF_STEP:step;
|
||
|
|
if(batchParams!=null && !batchParams.isEmpty()) {
|
||
|
|
int j = 0;
|
||
|
|
for (List<JdbcParam> list : batchParams) {
|
||
|
|
for (int i = 0; i < list.size(); i++) {
|
||
|
|
JdbcParam parameter = list.get(i);
|
||
|
|
setParameter(i+1, parameter.getJdbc(),parameter.getVal());
|
||
|
|
}
|
||
|
|
this.addBatch();
|
||
|
|
j++;
|
||
|
|
if(j%step==0) {
|
||
|
|
rows=countRow(rows,this._executeBatch());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
rows=countRow(rows,this._executeBatch());
|
||
|
|
size = rows;
|
||
|
|
return rows;
|
||
|
|
}
|
||
|
|
|
||
|
|
public ResultSet executeQuery() throws SQLException {
|
||
|
|
executeParams();
|
||
|
|
ResultSet rset = this._executeQuery();
|
||
|
|
rset.last();
|
||
|
|
size = rset.getRow(); //获得ResultSet的总行数
|
||
|
|
rset.beforeFirst();
|
||
|
|
return rset;
|
||
|
|
}
|
||
|
|
|
||
|
|
private ResultSet _executeQuery() throws SQLException {
|
||
|
|
return getStatement().executeQuery();
|
||
|
|
}
|
||
|
|
|
||
|
|
private PreparedStatement getStatement() {
|
||
|
|
return this.isCall?ctmt:stmt;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void setParameter(int index,int jdbc,Object val) throws SQLException {
|
||
|
|
PreparedStatement _stmt = getStatement();
|
||
|
|
if(val==null) {
|
||
|
|
_stmt.setNull(index,jdbc);
|
||
|
|
}else {
|
||
|
|
_stmt.setObject(index,val,jdbc);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void addBatch() throws SQLException {
|
||
|
|
getStatement().addBatch();
|
||
|
|
}
|
||
|
|
|
||
|
|
private int[] _executeBatch() throws SQLException {
|
||
|
|
return getStatement().executeBatch();
|
||
|
|
}
|
||
|
|
|
||
|
|
private int _executeUpdate() throws SQLException {
|
||
|
|
return getStatement().executeUpdate();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
private boolean _execute() throws SQLException {
|
||
|
|
return getStatement().execute();
|
||
|
|
}
|
||
|
|
|
||
|
|
private int countRow(int rows,int[] rowArray) {
|
||
|
|
if(rowArray!=null) {
|
||
|
|
for (int i = 0; i < rowArray.length; i++) {
|
||
|
|
rows+=rowArray[i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return rows;
|
||
|
|
}
|
||
|
|
|
||
|
|
public DataAccessException createException(SQLException e) {
|
||
|
|
return jdbc.getExceptionTranslator().translate(sql,null,e);
|
||
|
|
}
|
||
|
|
|
||
|
|
public void end() {
|
||
|
|
JdbcUtils.closeStatement(getStatement());
|
||
|
|
if(conn!=null) {
|
||
|
|
DataSourceUtils.releaseConnection(conn,getReleaseSource());
|
||
|
|
}
|
||
|
|
log.info(" Statement: 【{}】",sql);
|
||
|
|
if(params!=null && !params.isEmpty()) {
|
||
|
|
log.info("Parameters: {}",params.toString());
|
||
|
|
}
|
||
|
|
long con = System.currentTimeMillis()-start;
|
||
|
|
if(!this.isQuery) {
|
||
|
|
log.info(" consuming: 【{} ms】--- 数据:【{}条】--- 效率:【{} ms/条】",con,size,size>0?(con/size):con);
|
||
|
|
}else {
|
||
|
|
log.info(" total: {}",size);
|
||
|
|
log.info(" consuming: 【{} ms】",con);
|
||
|
|
}
|
||
|
|
log.info("-----------------------------------------------------------------------------------");
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|