Springboot项目中使用DBUtils解决由于集成Mybatis后的性能问题

谢邀,人在美国,刚下飞机,博士学位,年薪百万
之前在国内初学java时写过一篇关于DBUtil简单CRUD的帖子:
https://gitee.com/driverTu/codes/0m2e3nvo6wb89ha7tjrgp24

后来随着自身对java的深入学习了解,特别是对反射的原理、PreparedStatement、Druid有了比较深刻的印象,在新的实战项目中针对DBUtils的有了更好的集成方案,以下就是这个方案中的部分内容。其中有遇到一些坑和思考的转折点会在文中靠回忆稍微提一下。

一、依赖:

国际惯例,改造一个这种插件性质的工具先在POM.xml中添加:(demo是1.6)

<dependency>
    <groupId>commons-dbutils</groupId>
    <artifactId>commons-dbutils</artifactId>
    <version>1.6</version>
</dependency>

二、添加java.sql.Connection的一些基础资源操作类(可能不是最优解,但也够用了)

这个名字就叫BaseOperation.java好了,注意添加Slf4j,这个很重要,还用到了Druid获取数据库连接,其中要注意Druid的数据库连接配置,比如 :testOnBorrow: true、validationQuery: SELECT 1 FROM DUAL、removeAbandoned: true、removeAbandonedTimeout: 1800、keepAlive: true等配置信息。

import java.sql.Connection;
import java.sql.SQLException;
import com.alibaba.druid.pool.DruidDataSource;
import com.jade.core.common.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BaseOperation {
	// 创建一个threadlocal对象
	public static ThreadLocal<Connection> container = new ThreadLocal<Connection>();
	// 从当前线程中提取connection
	public static Connection getContainer() throws SQLException{
		Connection conn = container.get();
		if(null == conn) {
			// 获取数据库连接(共用框架内alibaba的druid)
			DruidDataSource dataSource = SpringContextHolder.getBean("dataSource");
			conn = dataSource.getConnection();
			container.set(conn);
		}
		return conn;
	}
	// 开启事务
	public static Connection startTransaction() {
		try {
			Connection conn = getContainer();
			conn.setAutoCommit(false);    // 关闭自动提交
			return conn;
		} catch (SQLException e) {
			e.printStackTrace();
			log.error("开启事务异常", e);
		}
		return null;
	}
	// 提交事务
	public static void commit() {
		try {
			Connection conn = getContainer();
			if(null != conn) 
				conn.commit();
		} catch (SQLException e) {
			e.printStackTrace();
			log.error("提交事务异常", e);
		}
	}
	// 回滚事务
	public static void rollback(){
		try {
			Connection conn = getContainer();    //检查当前线程是否存在连接
			if(conn != null) {
				conn.rollback();    //回滚事务
			}
		} catch (SQLException e) {
			e.printStackTrace();
			log.error("回滚事务异常", e);
		}
	}
	// 关闭连接
	public static void close() {
		try {
			Connection conn = getContainer();
			if (null != conn)    // 关闭连接对象
					conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
			log.error("关闭连接异常", e);
		} finally {
			container.remove();    // 从当前线程移除连接,避免造成内存泄漏
		}
	}
}

三、可以添加几个实用方法的工具类了——DBUtil

1、第一个方法是批量删除

2、第二个方法是批量增加(还有查询和修改的没用到,以后再写吧),还附带一个打印PreparedStatement的SQL的插件吧!

也就这么2个方法,哈哈哈

===第一个方法:
// 批量删除数据(condition:Json型条件参数,tableName:数据库表名)
public static String deleteBatch(String tableName, JSONObject condition) {
//	DELETE FROM Table_name WHERE ID = ?
	// 将Json型条件组装成and语句
	int num = 0;
	PreparedStatement pst = null;
	try {
		StringBuilder sb = new StringBuilder();
		String andStr = " AND ";
		String conditionStr = "";
		if(condition != null) {
			// 取值,强行手动添加
			for (String key : condition.keySet()) {
				sb.append(key + " = " + condition.get(key) + andStr);
			}
			// 去掉末尾的and
			conditionStr = sb.substring(0, sb.length() - andStr.length());
		}
		String sql = String.format("DELETE FROM %s WHERE %s", tableName, conditionStr); 
		log.info("=##========"+sql);
        pst = BaseOperation.startTransaction().prepareStatement(sql);
        num = pst.executeUpdate();
        BaseOperation.commit();
        pst.clearBatch();
    } catch (Exception e) {
        e.printStackTrace();
        BaseOperation.rollback();
        log.error("批量执行异常", e);            
    } finally {
        if(null != pst) {
	        try {
				DbUtils.close(pst);
			} catch (SQLException e) {
				e.printStackTrace();
				log.error("关闭PreparedStatement异常", e);
			}
        }
        BaseOperation.close();
	}
    return "受影响记录数为:" + num;
}
===第2个方法:
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.DbUtils;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSONObject;
import com.jade.core.common.utils.BaseResultCode;
import com.jade.core.common.utils.BaseReturn;
import com.jade.core.common.utils.SessionUser;
import com.jade.core.common.utils.SessionUserUtils;
import com.jade.core.common.utils.dbutil.BaseOperation;
import com.jade.core.common.utils.dbutil.DBUtilPropertyJade;
import com.jade.core.common.utils.excel.ExcelPropertyJade;
import com.jade.core.utils.DateUtil;

/**
 * 批量插入数据【未关闭资源】
 * @param tablename		表名
 * @param seqName		序列名(插入新数据,Oracle需要给一个序列用来主键自增)
 * @param paramList		字段名--对应数据值【键值对】,【反射】实现,需要给一个注解给实体属性
 * @param typeMap		字段名--对应beantype类型【键值对】
 */
private static BaseReturn doInsertBatch(String tablename, String seqName,
		List<Map<String, Object>> paramList, 
		Map<String, String> typeMap
		) {
	PreparedStatement pst = null;
    int num = 0;
    // 预处理SQL语句
    StringBuilder n = new StringBuilder();
    StringBuilder v = new StringBuilder();
    for (String k : paramList.get(0).keySet()) {
        v.append("?,");
        n.append(k + ",");
    }
    SessionUser sessionUser = SessionUserUtils.getCurrentUser();
	Long currUserOid = sessionUser==null?null:sessionUser.getUserOid();
	String currUserName = sessionUser==null?null:sessionUser.getUserName();
    String sql = String.format("INSERT INTO %s (OID, CREATED_DATE, NUMBER, %s) "
    		+ "VALUES(%s.NEXTVAL, s%, %d, %s)",
    		tablename,
    		n.toString().subSequence(0, n.length() - 1),
    		seqName,
    		"to_date('" + DateUtil.formatTime(new Date()) + "','yyyy-mm-dd hh24:mi:ss')",
    		0,
    		v.toString().subSequence(0, v.length() - 1)
    		); 
    try {
    	pst = BaseOperation.startTransaction().prepareStatement(sql);
    	// 这是打印pst中的SQL语句的
    	// pst = new LoggableStatement(BaseOperation.startTransaction(), sql); 
        for (Map<String, Object> param : paramList) {
        	int i = 0;
        	for (String key : param.keySet()) {
        		Object valueObj = param.get(key);
        		String typeObj = typeMap.get(key);
        		// 因为java中的日期与数据库日期引用库不同,所以根据javaBeanType来做下转换,避免出现无效的列类型
        		if("String".equals(typeObj)){
            		// 转义单引号
            		String str = valueObj==null?"":String.valueOf(valueObj);
            		pst.setString(++i, str);
        		}else if("Date".equals(typeObj)) {
					java.sql.Date date = new java.sql.Date(((Date)valueObj).getTime());
					pst.setDate(++i, date);
				}else if("Long".equals(typeObj)){
					pst.setLong(++i, (long)valueObj);
				}else if("Double".equals(typeObj)){
					pst.setDouble(++i, (double)valueObj);
				}else if("boolean".equals(typeObj)){
					pst.setBoolean(++i, (boolean)valueObj);
				}else {
					pst.setObject(++i, valueObj);
				}
			}
        	// 打印实际执行的SQL语句
        	// System.out.println("Executing SQL: "+((LoggableStatement)pst).getQueryString());
            pst.addBatch();
            num ++;
            // 已验证最佳效率:一万五
            if(num % 15000 == 0) {
            	log.info("=##========pst.executeBatch():" + num);
            	pst.executeBatch();
            	pst.clearBatch();
            	System.gc();
            }
		}
        pst.executeBatch();
        // BaseOperation.commit();
        pst.clearBatch();
        // num = pst.executeUpdate();
        return new BaseReturn("受影响记录数为:" + num);
    } catch (Exception e) {
    	num = -1;
        e.printStackTrace();
        BaseOperation.rollback();
        log.error("批量执行异常", e);
        return new BaseReturn(BaseResultCode.ERROR_CODE_500, "业务执行异常" + e.getMessage());
    } finally {
    	if(null != pst) {
        	try {
				DbUtils.close(pst);
			} catch (SQLException e) {
				e.printStackTrace();
				log.error("关闭PreparedStatement异常", e);
			}
    	}
    	// BaseOperation.close();
    	System.gc();
	}
}

/**
 * 批量插入数据
 * @param tableName	数据待插入的数据库表名
 * @param seqName	待插入数据给定使用的数据库索引名
 * @param dataList	传入的数据,哪些要插入哪些不要可以通过实体属性上的注解来决定【反射】
 * @param handDefaultColumnValue 【此方式会被datalist内同名变量值覆盖】
 * handDefaultColumnValue内有一个一一对应的beantype,获取方式为数据库字段名+后缀
 * 也可设置手动属性isHandOperat=false,来通过反射控制
 */
@SuppressWarnings("hiding")
public static <T> BaseReturn insertBatch(String tableName, String seqName, 
		List<T> dataList, JSONObject handDefaultColumnValue){
	// rejectValueToMap
	// 将属性中的值加工成SQL能用的值(beanName-value的键值对)
	// 原理:根据代码生成器的规则,可以由属性反推属性对应字段名应该是什么
	
	try {
		Field[] fields = dataList.get(0).getClass().getDeclaredFields();
		
		List<String> keyColumnNameList = new ArrayList<String>();
		List<String> fieldNameList = new ArrayList<String>();
		
		Map<String, String> columnTypeValueModel = new HashMap<String, String>();
		for (Field field : fields) {
			ExcelProperty epj = field.getAnnotation(ExcelProperty.class);
			DBUtilProperty dbupj = field.getAnnotation(DBUtilProperty.class);
			if (dbupj != null && dbupj.isHandOperat()) {
				// 手动添加部分属性-值的键值对(手动给没有配置@ExcelProperty的isImport属性的值及父类basePojo的一些值)
			} else if(null == epj || !epj.isImport()) {
				// 排除部分不导入数据
				continue;
			}
			field.setAccessible(true);
			// key
			String columnName = getColumnNameStr(field.getName());
			keyColumnNameList.add(columnName);
			// fieldName
			fieldNameList.add(field.getName());
			// fieldType
			String beanTypeStr = field.getType().toString();
			beanTypeStr = beanTypeStr.substring(beanTypeStr.lastIndexOf(".")+1);
			columnTypeValueModel.put(columnName, beanTypeStr);
		}
		if(CollectionUtils.isEmpty(keyColumnNameList)) {
			return new BaseReturn(BaseResultCode.ERROR_CODE_500,
					"实体属性无ExcelProperty或DBUtilProperty注解配置");
		}
		// 强行手动给默认值的
		Map<String, Object> columnNameValueModel = new HashMap<String, Object>();
		if(handDefaultColumnValue != null) {
			// 取值,强行手动添加
			for (String key : handDefaultColumnValue.keySet()) {
				// 这里需要对handDefaultColumnValue进行规则验证:要
				if(key.endsWith("_TYPETT")) {
					continue;
				}
				if(null != handDefaultColumnValue.get(key) && null == handDefaultColumnValue.get(key+"_TYPETT")) {
					return new BaseReturn(BaseResultCode.ERROR_CODE_500,
							"手动传入的值必须带各自的类型beantype");
				}
				columnNameValueModel.put(key, handDefaultColumnValue.get(key));
				columnTypeValueModel.put(key, String.valueOf(handDefaultColumnValue.get(key+"_TYPETT")));
			}
		}
		List<Map<String, Object>> listColumnNameValue = new ArrayList<Map<String,Object>>();
		
		for (T t : dataList) {
			// 自动扫描入参对象类的导入数据属性-值的键值对
			Map<String, Object> columnNameValue = new HashMap<String, Object>();
			columnNameValue.putAll(columnNameValueModel);
			for (int j = 0; j < keyColumnNameList.size(); j++) {
				Object obj = getFieldValue(fieldNameList.get(j), t);
				columnNameValue.put(keyColumnNameList.get(j), obj);
			}
//			for (String handKey : handList) {
//				columnNameValue.put(getColumnValueStr(handKey), getFieldValue(handKey, t));
//			}
			listColumnNameValue.add(columnNameValue);
		}
		// 可能多余
		if(CollectionUtils.isEmpty(listColumnNameValue)) {
			return new BaseReturn(BaseResultCode.ERROR_CODE_500,
					"暂时不允许插入空或无效数据");
		}
		BaseReturn retMsg = doInsertBatch(tableName, seqName, listColumnNameValue, columnTypeValueModel);
		return retMsg;
	} catch (Exception e ) {
		e.printStackTrace();
	}
	return new BaseReturn(BaseResultCode.ERROR_CODE_500, "批量操作错误");
}

// 通过反射获取要填充的数据值
@SuppressWarnings("hiding")
private static <T> Object getFieldValue(String fieldName, T t) {
	Method m = null;
	try {
    	fieldName = fieldName.replaceFirst(
    			fieldName.substring(0, 1), 
    			fieldName.substring(0, 1).toUpperCase());
    	m = t.getClass().getMethod("get"+fieldName);
    	return m.invoke(t);
	} catch (NoSuchMethodException e) {
//			e.printStackTrace();
		try {
			m = t.getClass().getMethod("is"+fieldName);
			return (Boolean)m.invoke(t);
		} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
			e1.printStackTrace();
		}
	} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
		e.printStackTrace();
	} catch (Exception e) {
		e.printStackTrace();
	}
	return null;
}

// 获取属性对应的数据库字段名称(考录项目限定规则)
private static String getColumnNameStr(String fieldName) {
	int len = fieldName.length();
	StringBuilder sb = new StringBuilder();
	
	for (int i = 0; i < len; i++) {
		char curr = fieldName.charAt(i);
		// 反推字段名称
		if (Character.isUpperCase(curr)) {
			// 如果是大写就在前面加下划线(考录项目限定规则)
			sb.append("_");
		}
		sb.append(Character.toUpperCase(curr));
	}
	return sb.toString();
}

PreparedStatement的SQL的插件:

package com.jade.core.common.utils;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;    
    
/**  
 * 项目名称:CFR      
 * 类名称:LoggableStatement      
 * 类描述:扩展PreparedStatement,以便输出执行的sql语句,即sql日志   
 */    
public class LoggableStatement implements PreparedStatement {    
    
    /** used for storing parameter values needed for producing log */    
    private ArrayList parameterValues;    
    
    /** the query string with question marks as parameter placeholders */    
    private String sqlTemplate;    
    
    /** a statement created from a real database connection */    
    private PreparedStatement wrappedStatement;    
    
    public LoggableStatement(Connection connection, String sql)    
            throws SQLException {    
        // use connection to make a prepared statement    
        wrappedStatement = connection.prepareStatement(sql);    
        sqlTemplate = sql;    
        parameterValues = new ArrayList();    
    }    
    
    private void saveQueryParamValue(int position, Object obj) {    
        String strValue;    
        if (obj instanceof String || obj instanceof Date) {    
            // if we have a String, include '' in the saved value    
            strValue = "'" + obj + "'";    
        } else {    
            if (obj == null) {    
                // convert null to the string null    
                strValue = "null";    
            } else {    
                // unknown object (includes all Numbers), just call toString    
                strValue = obj.toString();    
            }    
        }    
        // if we are setting a position larger than current size of    
        // parameterValues, first make it larger    
        while (position >= parameterValues.size()) {    
    
            parameterValues.add(null);    
        }    
        // save the parameter    
        parameterValues.set(position, strValue);    
    }    
    
    // 这一步是对ArrayList与sql进行处理,输出完整的sql语句    
    public String getQueryString() {    
        int len = sqlTemplate.length();    
        StringBuffer t = new StringBuffer(len * 2);    
    
        if (parameterValues != null) {    
            int i = 1, limit = 0, base = 0;    
    
            while ((limit = sqlTemplate.indexOf('?', limit)) != -1) {    
                t.append(sqlTemplate.substring(base, limit));    
                t.append(parameterValues.get(i));    
                i++;    
                limit++;    
                base = limit;    
            }    
            if (base < len) {    
                t.append(sqlTemplate.substring(base));    
            }    
        }    
        return t.toString();    
    }    
    
    public void addBatch() throws SQLException {    
        wrappedStatement.addBatch();    
    }    
    
    public void clearParameters() throws SQLException {    
        wrappedStatement.clearParameters();    
    }    
    
    public boolean execute() throws SQLException {    
        return wrappedStatement.execute();    
    }    
    
    public ResultSet executeQuery() throws SQLException {    
        return wrappedStatement.executeQuery();    
    }    
    
    public int executeUpdate() throws SQLException {    
        return wrappedStatement.executeUpdate();    
    }    
    
    public ResultSetMetaData getMetaData() throws SQLException {    
        return wrappedStatement.getMetaData();    
    }    
    
    public ParameterMetaData getParameterMetaData() throws SQLException {    
        return wrappedStatement.getParameterMetaData();    
    }    
    
    public void setArray(int i, Array x) throws SQLException {    
        wrappedStatement.setArray(i, x);    
        saveQueryParamValue(i, x);    
    }    
    
    public void setAsciiStream(int parameterIndex, InputStream x, int length)    
            throws SQLException {    
        wrappedStatement.setAsciiStream(parameterIndex, x, length);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setBigDecimal(int parameterIndex, BigDecimal x)    
            throws SQLException {    
        wrappedStatement.setBigDecimal(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setBinaryStream(int parameterIndex, InputStream x, int length)    
            throws SQLException {    
        wrappedStatement.setBinaryStream(parameterIndex, x, length);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setBlob(int i, Blob x) throws SQLException {    
        wrappedStatement.setBlob(i, x);    
        saveQueryParamValue(i, x);    
    }    
    
    public void setBoolean(int parameterIndex, boolean x) throws SQLException {    
        wrappedStatement.setBoolean(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, new Boolean(x));    
    }    
    
    public void setByte(int parameterIndex, byte x) throws SQLException {    
        wrappedStatement.setByte(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, new Byte(x));    
    }    
    
    public void setBytes(int parameterIndex, byte[] x) throws SQLException {    
        wrappedStatement.setBytes(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setCharacterStream(int parameterIndex, Reader reader, int length)    
            throws SQLException {    
        wrappedStatement.setCharacterStream(parameterIndex, reader, length);    
        saveQueryParamValue(parameterIndex, reader);    
    }    
    
    public void setClob(int i, Clob x) throws SQLException {    
        wrappedStatement.setClob(i, x);    
        saveQueryParamValue(i, x);    
    }    
    
    public void setDate(int parameterIndex, Date x) throws SQLException {    
        wrappedStatement.setDate(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setDate(int parameterIndex, Date x, Calendar cal)    
            throws SQLException {    
        wrappedStatement.setDate(parameterIndex, x, cal);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setDouble(int parameterIndex, double x) throws SQLException {    
        wrappedStatement.setDouble(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, new Double(x));    
    }    
    
    public void setFloat(int parameterIndex, float x) throws SQLException {    
        wrappedStatement.setFloat(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, new Float(x));    
    }    
    
    public void setInt(int parameterIndex, int x) throws SQLException {    
        wrappedStatement.setInt(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, new Integer(x));    
    }    
    
    public void setLong(int parameterIndex, long x) throws SQLException {    
        wrappedStatement.setLong(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, new Long(x));    
    }    
    
    public void setNull(int parameterIndex, int sqlType) throws SQLException {    
        wrappedStatement.setNull(parameterIndex, sqlType);    
        saveQueryParamValue(parameterIndex, new Integer(sqlType));    
    }    
    
    public void setNull(int paramIndex, int sqlType, String typeName)    
            throws SQLException {    
        wrappedStatement.setNull(paramIndex, sqlType, typeName);    
        saveQueryParamValue(paramIndex, new Integer(sqlType));    
    }    
    
    public void setObject(int parameterIndex, Object x) throws SQLException {    
        wrappedStatement.setObject(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setObject(int parameterIndex, Object x, int targetSqlType)    
            throws SQLException {    
        wrappedStatement.setObject(parameterIndex, x, targetSqlType);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setObject(int parameterIndex, Object x, int targetSqlType,    
            int scale) throws SQLException {    
        wrappedStatement.setObject(parameterIndex, x, targetSqlType, scale);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setRef(int i, Ref x) throws SQLException {    
        wrappedStatement.setRef(i, x);    
        saveQueryParamValue(i, x);    
    }    
    
    public void setShort(int parameterIndex, short x) throws SQLException {    
        wrappedStatement.setShort(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, new Short(x));    
    }    
    
    public void setString(int parameterIndex, String x) throws SQLException {    
        wrappedStatement.setString(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setTime(int parameterIndex, Time x) throws SQLException {    
        wrappedStatement.setTime(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setTime(int parameterIndex, Time x, Calendar cal)    
            throws SQLException {    
        wrappedStatement.setTime(parameterIndex, x, cal);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setTimestamp(int parameterIndex, Timestamp x)    
            throws SQLException {    
        wrappedStatement.setTimestamp(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal)    
            throws SQLException {    
        wrappedStatement.setTimestamp(parameterIndex, x, cal);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setURL(int parameterIndex, URL x) throws SQLException {    
        wrappedStatement.setURL(parameterIndex, x);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void setUnicodeStream(int parameterIndex, InputStream x, int length)    
            throws SQLException {    
        wrappedStatement.setUnicodeStream(parameterIndex, x, length);    
        saveQueryParamValue(parameterIndex, x);    
    }    
    
    public void addBatch(String sql) throws SQLException {    
        wrappedStatement.addBatch(sql);    
    }    
    
    public void cancel() throws SQLException {    
        wrappedStatement.cancel();    
    }    
    
    public void clearBatch() throws SQLException {    
        wrappedStatement.clearBatch();    
    }    
    
    public void clearWarnings() throws SQLException {    
        wrappedStatement.clearWarnings();    
    }    
    
    public void close() throws SQLException {    
        wrappedStatement.close();    
    }    
    
    public boolean execute(String sql) throws SQLException {    
        return wrappedStatement.execute(sql);    
    }    
    
    public boolean execute(String sql, int autoGeneratedKeys)    
            throws SQLException {    
        return wrappedStatement.execute(sql, autoGeneratedKeys);    
    }    
    
    public boolean execute(String sql, int[] columnIndexes) throws SQLException {    
        return wrappedStatement.execute(sql, columnIndexes);    
    }    
    
    public boolean execute(String sql, String[] columnNames)    
            throws SQLException {    
        return wrappedStatement.execute(sql, columnNames);    
    }    
    
    public int[] executeBatch() throws SQLException {    
        return wrappedStatement.executeBatch();    
    }    
    
    public ResultSet executeQuery(String sql) throws SQLException {    
        return wrappedStatement.executeQuery(sql);    
    }    
    
    public int executeUpdate(String sql) throws SQLException {    
        return wrappedStatement.executeUpdate(sql);    
    }    
    
    public int executeUpdate(String sql, int autoGeneratedKeys)    
            throws SQLException {    
        return wrappedStatement.executeUpdate(sql, autoGeneratedKeys);    
    }    
    
    public int executeUpdate(String sql, int[] columnIndexes)    
            throws SQLException {    
        return wrappedStatement.executeUpdate(sql, columnIndexes);    
    }    
    
    public int executeUpdate(String sql, String[] columnNames)    
            throws SQLException {    
        return wrappedStatement.executeUpdate(sql, columnNames);    
    }    
    
    public Connection getConnection() throws SQLException {    
        return wrappedStatement.getConnection();    
    }    
    
    public int getFetchDirection() throws SQLException {    
        return wrappedStatement.getFetchDirection();    
    }    
    
    public int getFetchSize() throws SQLException {    
        return wrappedStatement.getFetchSize();    
    }    
    
    public ResultSet getGeneratedKeys() throws SQLException {    
        return wrappedStatement.getGeneratedKeys();    
    }    
    
    public int getMaxFieldSize() throws SQLException {    
        return wrappedStatement.getMaxFieldSize();    
    }    
    
    public int getMaxRows() throws SQLException {    
        return wrappedStatement.getMaxRows();    
    }    
    
    public boolean getMoreResults() throws SQLException {    
        return wrappedStatement.getMoreResults();    
    }    
    
    public boolean getMoreResults(int current) throws SQLException {    
        return wrappedStatement.getMoreResults(current);    
    }    
    
    public int getQueryTimeout() throws SQLException {    
        return wrappedStatement.getQueryTimeout();    
    }    
    
    public ResultSet getResultSet() throws SQLException {    
        return wrappedStatement.getResultSet();    
    }    
    
    public int getResultSetConcurrency() throws SQLException {    
        return wrappedStatement.getResultSetConcurrency();    
    }    
    
    public int getResultSetHoldability() throws SQLException {    
        return wrappedStatement.getResultSetHoldability();    
    }    
    
    public int getResultSetType() throws SQLException {    
        return wrappedStatement.getResultSetType();    
    }    
    
    public int getUpdateCount() throws SQLException {    
        return wrappedStatement.getUpdateCount();    
    }    
    
    public SQLWarning getWarnings() throws SQLException {    
        return wrappedStatement.getWarnings();    
    }    
    
    public void setCursorName(String name) throws SQLException {    
        wrappedStatement.setCursorName(name);    
    }    
    
    public void setEscapeProcessing(boolean enable) throws SQLException {    
        wrappedStatement.setEscapeProcessing(enable);    
    }    
    
    public void setFetchDirection(int direction) throws SQLException {    
        wrappedStatement.setFetchDirection(direction);    
    }    
    
    public void setFetchSize(int rows) throws SQLException {    
        wrappedStatement.setFetchSize(rows);    
    }    
    
    public void setMaxFieldSize(int max) throws SQLException {    
        wrappedStatement.setMaxFieldSize(max);    
    }    
    
    public void setMaxRows(int max) throws SQLException {    
        wrappedStatement.setMaxFieldSize(max);    
    }    
    
    public void setQueryTimeout(int seconds) throws SQLException {    
        wrappedStatement.setQueryTimeout(seconds);    
    }  
  
    public void setAsciiStream(int parameterIndex, InputStream x)  
            throws SQLException {  
    }  
  
    public void setAsciiStream(int parameterIndex, InputStream x, long length)  
            throws SQLException {  
    }  
  
    public void setBinaryStream(int parameterIndex, InputStream x)  
            throws SQLException {  
    }  
  
    public void setBinaryStream(int parameterIndex, InputStream x, long length)  
            throws SQLException {  
    }  
  
    public void setBlob(int parameterIndex, InputStream inputStream)  
            throws SQLException {  
    }  
  
    public void setBlob(int parameterIndex, InputStream inputStream, long length)  
            throws SQLException {  
    }  
  
    public void setCharacterStream(int parameterIndex, Reader reader)  
            throws SQLException {  
    }  
  
    public void setCharacterStream(int parameterIndex, Reader reader,  
            long length) throws SQLException {  
    }  
  
    public void setClob(int parameterIndex, Reader reader) throws SQLException {  
    }  
  
    public void setClob(int parameterIndex, Reader reader, long length)  
            throws SQLException {  
    }  
  
    public void setNCharacterStream(int parameterIndex, Reader value)  
            throws SQLException {  
    }  
  
    public void setNCharacterStream(int parameterIndex, Reader value,  
            long length) throws SQLException {  
    }  
  
    public void setNClob(int parameterIndex, NClob value) throws SQLException {  
    }  
  
    public void setNClob(int parameterIndex, Reader reader) throws SQLException {  
    }  
  
    public void setNClob(int parameterIndex, Reader reader, long length)  
            throws SQLException {  
    }  
  
    public void setNString(int parameterIndex, String value)  
            throws SQLException {  
    }  
  
    public void setRowId(int parameterIndex, RowId x) throws SQLException {  
    }  
  
    public void setSQLXML(int parameterIndex, SQLXML xmlObject)  
            throws SQLException {  
    }  
  
    public boolean isClosed() throws SQLException {  
        return false;  
    }  
  
    public boolean isPoolable() throws SQLException {  
        return false;  
    }  
  
    public void setPoolable(boolean poolable) throws SQLException {  
    }  
  
    public boolean isWrapperFor(Class<?> iface) throws SQLException {  
        return false;  
    }  
  
    public <T> T unwrap(Class<T> iface) throws SQLException {  
        return null;  
    }

	@Override
	public void closeOnCompletion() throws SQLException {
	}

	@Override
	public boolean isCloseOnCompletion() throws SQLException {
		return false;
	}    
}    

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 是一个基于 Spring 框架的快速开发框架,它可以帮助开发者快速搭建基于 Spring 的应用程序,而 DBUtils 是一个开源的 JDBC 工具库,它简化了 JDBC 编码的过程,可以帮助开发者更方便地使用 JDBC 来操作数据库。 结合使用 Spring Boot 和 DBUtils 可以让开发者更方便地使用 Java 进行数据库开发。在 Spring Boot ,我们可以使用注解来配置数据源和事务管理器,并且也可以通过注入 DBUtils 的 QueryRunner 对象来方便地执行 SQL 语句。 下面是一个使用 Spring Boot 和 DBUtils 进行数据库操作的例子: 1. 添加依赖 在 pom.xml 文件添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils</artifactId> <version>1.7</version> </dependency> ``` 2. 配置数据源和事务管理器 在 application.properties 文件添加以下配置: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.tomcat.initial-size=5 spring.datasource.tomcat.max-active=20 spring.datasource.tomcat.max-idle=10 spring.datasource.tomcat.min-idle=5 spring.datasource.tomcat.test-on-borrow=true spring.datasource.tomcat.test-while-idle=true spring.datasource.tomcat.validation-query=SELECT 1 spring.datasource.platform=mysql spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect ``` 3. 创建数据访问对象(DAO) ```java @Repository public class UserDao { @Autowired private JdbcTemplate jdbcTemplate; private QueryRunner queryRunner = new QueryRunner(); public User getUserById(int id) throws SQLException { String sql = "SELECT * FROM user WHERE id = ?"; return queryRunner.query(jdbcTemplate.getDataSource().getConnection(), sql, new BeanHandler<>(User.class), id); } } ``` 4. 使用 DAO 进行数据库操作 ```java @RestController public class UserController { @Autowired private UserDao userDao; @GetMapping("/user/{id}") public User getUserById(@PathVariable int id) throws SQLException { return userDao.getUserById(id); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值