转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53750584 
在之前学习了MySQL和Oracle之后,那么,如和在Java种去连接这两种数据库。在这个轻量级的工具类当中,使用了数据库连接池

去提高数据库连接的高效性,并且使用了PreparedStatement来执行对SQL的预编译,能够有效防止SQL注入问题。

一.准备在配置文件配置:配置数据库连接属性文件:在项目新建config包下建立jdbc-mysql.properties并加入以下配置

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8
jdbc.username=root
jdbc.password=root

二.准备数据库连接池对象:单例

package util;import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mchange.v2.c3p0.DataSources;import java.beans.PropertyVetoException;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;/*** 数据库连接对象* Created by yuandl on 2016-12-16.*/
public class DBConnectionPool {private static volatile DBConnectionPool dbConnection;private ComboPooledDataSource cpds;/*** 在构造函数初始化的时候获取数据库连接*/private DBConnectionPool() {try {/**通过属性文件获取数据库连接的参数值**/Properties properties = new Properties();FileInputStream fileInputStream = new FileInputStream("src/config/jdbc-mysql.properties");properties.load(fileInputStream);/**获取属性文件中的值**/String driverClassName = properties.getProperty("jdbc.driverClassName");String url = properties.getProperty("jdbc.url");String username = properties.getProperty("jdbc.username");String password = properties.getProperty("jdbc.password");/**数据库连接池对象**/cpds = new ComboPooledDataSource();/**设置数据库连接驱动**/cpds.setDriverClass(driverClassName);/**设置数据库连接地址**/cpds.setJdbcUrl(url);/**设置数据库连接用户名**/cpds.setUser(username);/**设置数据库连接密码**/cpds.setPassword(password);/**初始化时创建的连接数,应在minPoolSize与maxPoolSize之间取值.默认为3**/cpds.setInitialPoolSize(3);/**连接池中保留的最大连接数据.默认为15**/cpds.setMaxPoolSize(10);/**当连接池中的连接用完时,C3PO一次性创建新的连接数目;**/cpds.setAcquireIncrement(1);/**隔多少秒检查所有连接池中的空闲连接,默认为0表示不检查;**/cpds.setIdleConnectionTestPeriod(60);/**最大空闲时间,超过空闲时间的连接将被丢弃.为0或负数据则永不丢弃.默认为0;**/cpds.setMaxIdleTime(3000);/**因性能消耗大请只在需要的时候使用它。如果设为true那么在每个connection提交的时候都将校验其有效性。建议使用idleConnectionTestPeriod或automaticTestTable等方法来提升连接测试的性能。Default: false**/cpds.setTestConnectionOnCheckout(true);/**如果设为true那么在取得连接的同时将校验连接的有效性。Default: false **/cpds.setTestConnectionOnCheckin(true);/**定义在从数据库获取新的连接失败后重复尝试获取的次数,默认为30;**/cpds.setAcquireRetryAttempts(30);/**两次连接中间隔时间默认为1000毫秒**/cpds.setAcquireRetryDelay(1000);/** 获取连接失败将会引起所有等待获取连接的线程异常,但是数据源仍有效的保留,并在下次调用getConnection()的时候继续尝试获取连接.如果设为true,那么尝试获取连接失败后该数据源将申明已经断开并永久关闭.默认为false**/cpds.setBreakAfterAcquireFailure(true);} catch (IOException e) {e.printStackTrace();} catch (PropertyVetoException e) {e.printStackTrace();}}/*** 获取数据库连接对象,单例** @return*/public static DBConnectionPool getInstance() {if (dbConnection == null) {synchronized (DBConnectionPool.class) {if (dbConnection == null) {dbConnection = new DBConnectionPool();}}}return dbConnection;}/*** 获取数据库连接** @return 数据库连接*/public final synchronized Connection getConnection() throws SQLException {return cpds.getConnection();}/*** finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。** @throws Throwable*/protected void finalize() throws Throwable {DataSources.destroy(cpds);super.finalize();}
}

三.实现新增、修改、删除、查询操作的两个核心方法:可以实现任何复杂的SQL,而且通过数据绑定的方式不会有SQL注入问题

/*** 可以执行新增,修改,删除** @param sql      sql语句* @param bindArgs 绑定参数* @return 影响的行数* @throws SQLException SQL异常*/public static int executeUpdate(String sql, Object[] bindArgs) throws SQLException {/**影响的行数**/int affectRowCount = -1;Connection connection = null;PreparedStatement preparedStatement = null;try {/**从数据库连接池中获取数据库连接**/connection = DBConnectionPool.getInstance().getConnection();/**执行SQL预编译**/preparedStatement = connection.prepareStatement(sql.toString());/**设置不自动提交,以便于在出现异常的时候数据库回滚**/connection.setAutoCommit(false);System.out.println(getExecSQL(sql, bindArgs));if (bindArgs != null) {/**绑定参数设置sql占位符中的值**/for (int i = 0; i < bindArgs.length; i++) {preparedStatement.setObject(i + 1, bindArgs[i]);}}/**执行sql**/affectRowCount = preparedStatement.executeUpdate();connection.commit();String operate;if (sql.toUpperCase().indexOf("DELETE FROM") != -1) {operate = "删除";} else if (sql.toUpperCase().indexOf("INSERT INTO") != -1) {operate = "新增";} else {operate = "修改";}System.out.println("成功" + operate + "了" + affectRowCount + "行");System.out.println();} catch (Exception e) {if (connection != null) {connection.rollback();}e.printStackTrace();throw e;} finally {if (preparedStatement != null) {preparedStatement.close();}if (connection != null) {connection.close();}}return affectRowCount;}/*** 执行查询** @param sql      要执行的sql语句* @param bindArgs 绑定的参数* @return List<Map<String, Object>>结果集对象* @throws SQLException SQL执行异常*/public static List<Map<String, Object>> executeQuery(String sql, Object[] bindArgs) throws SQLException {List<Map<String, Object>> datas = new ArrayList<>();Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;try {/**获取数据库连接池中的连接**/connection = DBConnectionPool.getInstance().getConnection();preparedStatement = connection.prepareStatement(sql);if (bindArgs != null) {/**设置sql占位符中的值**/for (int i = 0; i < bindArgs.length; i++) {preparedStatement.setObject(i + 1, bindArgs[i]);}}System.out.println(getExecSQL(sql, bindArgs));/**执行sql语句,获取结果集**/resultSet = preparedStatement.executeQuery();getDatas(resultSet);System.out.println();} catch (Exception e) {e.printStackTrace();throw e;} finally {if (resultSet != null) {resultSet.close();}if (preparedStatement != null) {preparedStatement.close();}if (connection != null) {connection.close();}}return datas;}

四.执行新增的简化操作

 /*** 执行数据库插入操作** @param valueMap  插入数据表中key为列名和value为列对应的值的Map对象* @param tableName 要插入的数据库的表名* @return 影响的行数* @throws SQLException SQL异常*/public static int insert(String tableName, Map<String, Object> valueMap) throws SQLException {/**获取数据库插入的Map的键值对的值**/Set<String> keySet = valueMap.keySet();Iterator<String> iterator = keySet.iterator();/**要插入的字段sql,其实就是用key拼起来的**/StringBuilder columnSql = new StringBuilder();/**要插入的字段值,其实就是?**/StringBuilder unknownMarkSql = new StringBuilder();Object[] bindArgs = new Object[valueMap.size()];int i = 0;while (iterator.hasNext()) {String key = iterator.next();columnSql.append(i == 0 ? "" : ",");columnSql.append(key);unknownMarkSql.append(i == 0 ? "" : ",");unknownMarkSql.append("?");bindArgs[i] = valueMap.get(key);i++;}/**开始拼插入的sql语句**/StringBuilder sql = new StringBuilder();sql.append("INSERT INTO ");sql.append(tableName);sql.append(" (");sql.append(columnSql);sql.append(" )  VALUES (");sql.append(unknownMarkSql);sql.append(" )");return executeUpdate(sql.toString(), bindArgs);}

五.执行更新的简化操作

/*** 执行更新操作** @param tableName 表名* @param valueMap  要更改的值* @param whereMap  条件* @return 影响的行数* @throws SQLException SQL异常*/public static int update(String tableName, Map<String, Object> valueMap, Map<String, Object> whereMap) throws SQLException {/**获取数据库插入的Map的键值对的值**/Set<String> keySet = valueMap.keySet();Iterator<String> iterator = keySet.iterator();/**开始拼插入的sql语句**/StringBuilder sql = new StringBuilder();sql.append("UPDATE ");sql.append(tableName);sql.append(" SET ");/**要更改的的字段sql,其实就是用key拼起来的**/StringBuilder columnSql = new StringBuilder();int i = 0;List<Object> objects = new ArrayList<>();while (iterator.hasNext()) {String key = iterator.next();columnSql.append(i == 0 ? "" : ",");columnSql.append(key + " = ? ");objects.add(valueMap.get(key));i++;}sql.append(columnSql);/**更新的条件:要更改的的字段sql,其实就是用key拼起来的**/StringBuilder whereSql = new StringBuilder();int j = 0;if (whereMap != null && whereMap.size() > 0) {whereSql.append(" WHERE ");iterator = whereMap.keySet().iterator();while (iterator.hasNext()) {String key = iterator.next();whereSql.append(j == 0 ? "" : " AND ");whereSql.append(key + " = ? ");objects.add(whereMap.get(key));j++;}sql.append(whereSql);}return executeUpdate(sql.toString(), objects.toArray());}

六.执行删除的简化操作

/*** 执行删除操作** @param tableName 要删除的表名* @param whereMap  删除的条件* @return 影响的行数* @throws SQLException SQL执行异常*/public static int delete(String tableName, Map<String, Object> whereMap) throws SQLException {/**准备删除的sql语句**/StringBuilder sql = new StringBuilder();sql.append("DELETE FROM ");sql.append(tableName);/**更新的条件:要更改的的字段sql,其实就是用key拼起来的**/StringBuilder whereSql = new StringBuilder();Object[] bindArgs = null;if (whereMap != null && whereMap.size() > 0) {bindArgs = new Object[whereMap.size()];whereSql.append(" WHERE ");/**获取数据库插入的Map的键值对的值**/Set<String> keySet = whereMap.keySet();Iterator<String> iterator = keySet.iterator();int i = 0;while (iterator.hasNext()) {String key = iterator.next();whereSql.append(i == 0 ? "" : " AND ");whereSql.append(key + " = ? ");bindArgs[i] = whereMap.get(key);i++;}sql.append(whereSql);}return executeUpdate(sql.toString(), bindArgs);}

七.查询的4种玩法

  • 1.执行sql通过 Map

import util.DBUtil;import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** Created by yuandl on 2016-12-16.*/
public class DBTest {public static void main(String[] args) {System.out.println("数据库的原数据");testQuery3();testInsert();System.out.println("执行插入后的数据");testQuery3();testUpdate();System.out.println("执行修改后的数据");testQuery3();testDelete();System.out.println("执行删除后的数据");testQuery3();System.out.println("带条件的查询1");testQuery2();System.out.println("带条件的查询2");testQuery1();}/*** 测试插入*/private static void testInsert() {Map<String, Object> map = new HashMap<>();map.put("emp_id", 1013);map.put("name", "JDBCUtil测试");map.put("job", "developer");map.put("salary", 10000);map.put("hire_date", new java.sql.Date(System.currentTimeMillis()));try {int count = DBUtil.insert("emp_test", map);} catch (SQLException e) {e.printStackTrace();}}/*** 测试更新*/private static void testUpdate() {Map<String, Object> map = new HashMap<>();map.put("name", "测试更新");Map<String, Object> whereMap = new HashMap<>();whereMap.put("emp_id", "1013");try {int count = DBUtil.update("emp_test", map, whereMap);} catch (SQLException e) {e.printStackTrace();}}/*** 测试删除*/private static void testDelete() {Map<String, Object> whereMap = new HashMap<>();whereMap.put("emp_id", 1013);whereMap.put("job", "developer");try {int count = DBUtil.delete("emp_test", whereMap);} catch (SQLException e) {e.printStackTrace();}}/*** 查询方式一*/public static void testQuery1() {Map<String,Object> whereMap=new HashMap<>();whereMap.put("salary","10000");try {DBUtil.query("emp_test",whereMap);} catch (SQLException e) {e.printStackTrace();}}/*** 查询方式二*/public static void testQuery2() {String where = "job = ?  AND salary = ? ";String[] whereArgs = new String[]{"clerk", "3000"};try {List<Map<String, Object>> list = DBUtil.query("emp_test", where, whereArgs);} catch (SQLException e) {e.printStackTrace();}}/*** 查询方式三*/public static void testQuery3() {try {List<Map<String, Object>> list = DBUtil.query("emp_test", false, null, null, null, null, null, null, null);} catch (SQLException e) {e.printStackTrace();}}
}

  • 打印结果
数据库的原数据
SELECT  * FROM emp_test
成功查询到了14行数据
第1行:{DEPT_TEST_ID=10, EMP_ID=1001, SALARY=10000, HIRE_DATE=2010-01-12, BONUS=2000, MANAGER=1005, JOB=Manager, NAME=张无忌}
第2行:{DEPT_TEST_ID=10, EMP_ID=1002, SALARY=8000, HIRE_DATE=2011-01-12, BONUS=1000, MANAGER=1001, JOB=Analyst, NAME=刘苍松}
第3行:{DEPT_TEST_ID=10, EMP_ID=1003, SALARY=9000, HIRE_DATE=2010-02-11, BONUS=1000, MANAGER=1001, JOB=Analyst, NAME=李翊}
第4行:{DEPT_TEST_ID=10, EMP_ID=1004, SALARY=5000, HIRE_DATE=2010-02-11, BONUS=null, MANAGER=1001, JOB=Programmer, NAME=郭芙蓉}
第5行:{DEPT_TEST_ID=20, EMP_ID=1005, SALARY=15000, HIRE_DATE=2008-02-15, BONUS=null, MANAGER=null, JOB=President, NAME=张三丰}
第6行:{DEPT_TEST_ID=20, EMP_ID=1006, SALARY=5000, HIRE_DATE=2009-02-01, BONUS=400, MANAGER=1005, JOB=Manager, NAME=燕小六}
第7行:{DEPT_TEST_ID=20, EMP_ID=1007, SALARY=3000, HIRE_DATE=2009-02-01, BONUS=500, MANAGER=1006, JOB=clerk, NAME=陆无双}
第8行:{DEPT_TEST_ID=30, EMP_ID=1008, SALARY=5000, HIRE_DATE=2009-05-01, BONUS=500, MANAGER=1005, JOB=Manager, NAME=黄蓉}
第9行:{DEPT_TEST_ID=30, EMP_ID=1009, SALARY=4000, HIRE_DATE=2009-02-20, BONUS=null, MANAGER=1008, JOB=salesman, NAME=韦小宝}
第10行:{DEPT_TEST_ID=30, EMP_ID=1010, SALARY=4500, HIRE_DATE=2009-05-10, BONUS=500, MANAGER=1008, JOB=salesman, NAME=郭靖}
第11行:{DEPT_TEST_ID=null, EMP_ID=1011, SALARY=null, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=于泽成}
第12行:{DEPT_TEST_ID=null, EMP_ID=1012, SALARY=null, HIRE_DATE=2011-08-10, BONUS=null, MANAGER=null, JOB=null, NAME=amy}
第13行:{DEPT_TEST_ID=null, EMP_ID=1014, SALARY=8000, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=张无忌}
第14行:{DEPT_TEST_ID=20, EMP_ID=1015, SALARY=null, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=刘苍松}INSERT INTO emp_test (name,hire_date,job,salary,emp_id )  VALUES (JDBCUtil测试,2016-12-17,developer,10000,1013 )
成功新增了1行执行插入后的数据
SELECT  * FROM emp_test
成功查询到了15行数据
第1行:{DEPT_TEST_ID=10, EMP_ID=1001, SALARY=10000, HIRE_DATE=2010-01-12, BONUS=2000, MANAGER=1005, JOB=Manager, NAME=张无忌}
第2行:{DEPT_TEST_ID=10, EMP_ID=1002, SALARY=8000, HIRE_DATE=2011-01-12, BONUS=1000, MANAGER=1001, JOB=Analyst, NAME=刘苍松}
第3行:{DEPT_TEST_ID=10, EMP_ID=1003, SALARY=9000, HIRE_DATE=2010-02-11, BONUS=1000, MANAGER=1001, JOB=Analyst, NAME=李翊}
第4行:{DEPT_TEST_ID=10, EMP_ID=1004, SALARY=5000, HIRE_DATE=2010-02-11, BONUS=null, MANAGER=1001, JOB=Programmer, NAME=郭芙蓉}
第5行:{DEPT_TEST_ID=20, EMP_ID=1005, SALARY=15000, HIRE_DATE=2008-02-15, BONUS=null, MANAGER=null, JOB=President, NAME=张三丰}
第6行:{DEPT_TEST_ID=20, EMP_ID=1006, SALARY=5000, HIRE_DATE=2009-02-01, BONUS=400, MANAGER=1005, JOB=Manager, NAME=燕小六}
第7行:{DEPT_TEST_ID=20, EMP_ID=1007, SALARY=3000, HIRE_DATE=2009-02-01, BONUS=500, MANAGER=1006, JOB=clerk, NAME=陆无双}
第8行:{DEPT_TEST_ID=30, EMP_ID=1008, SALARY=5000, HIRE_DATE=2009-05-01, BONUS=500, MANAGER=1005, JOB=Manager, NAME=黄蓉}
第9行:{DEPT_TEST_ID=30, EMP_ID=1009, SALARY=4000, HIRE_DATE=2009-02-20, BONUS=null, MANAGER=1008, JOB=salesman, NAME=韦小宝}
第10行:{DEPT_TEST_ID=30, EMP_ID=1010, SALARY=4500, HIRE_DATE=2009-05-10, BONUS=500, MANAGER=1008, JOB=salesman, NAME=郭靖}
第11行:{DEPT_TEST_ID=null, EMP_ID=1011, SALARY=null, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=于泽成}
第12行:{DEPT_TEST_ID=null, EMP_ID=1012, SALARY=null, HIRE_DATE=2011-08-10, BONUS=null, MANAGER=null, JOB=null, NAME=amy}
第13行:{DEPT_TEST_ID=null, EMP_ID=1014, SALARY=8000, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=张无忌}
第14行:{DEPT_TEST_ID=20, EMP_ID=1015, SALARY=null, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=刘苍松}
第15行:{DEPT_TEST_ID=null, EMP_ID=1013, SALARY=10000, HIRE_DATE=2016-12-17, BONUS=null, MANAGER=null, JOB=developer, NAME=JDBCUtil测试}UPDATE emp_test SET name = 测试更新  WHERE emp_id = 1013
成功修改了1行执行修改后的数据
SELECT  * FROM emp_test
成功查询到了15行数据
第1行:{DEPT_TEST_ID=10, EMP_ID=1001, SALARY=10000, HIRE_DATE=2010-01-12, BONUS=2000, MANAGER=1005, JOB=Manager, NAME=张无忌}
第2行:{DEPT_TEST_ID=10, EMP_ID=1002, SALARY=8000, HIRE_DATE=2011-01-12, BONUS=1000, MANAGER=1001, JOB=Analyst, NAME=刘苍松}
第3行:{DEPT_TEST_ID=10, EMP_ID=1003, SALARY=9000, HIRE_DATE=2010-02-11, BONUS=1000, MANAGER=1001, JOB=Analyst, NAME=李翊}
第4行:{DEPT_TEST_ID=10, EMP_ID=1004, SALARY=5000, HIRE_DATE=2010-02-11, BONUS=null, MANAGER=1001, JOB=Programmer, NAME=郭芙蓉}
第5行:{DEPT_TEST_ID=20, EMP_ID=1005, SALARY=15000, HIRE_DATE=2008-02-15, BONUS=null, MANAGER=null, JOB=President, NAME=张三丰}
第6行:{DEPT_TEST_ID=20, EMP_ID=1006, SALARY=5000, HIRE_DATE=2009-02-01, BONUS=400, MANAGER=1005, JOB=Manager, NAME=燕小六}
第7行:{DEPT_TEST_ID=20, EMP_ID=1007, SALARY=3000, HIRE_DATE=2009-02-01, BONUS=500, MANAGER=1006, JOB=clerk, NAME=陆无双}
第8行:{DEPT_TEST_ID=30, EMP_ID=1008, SALARY=5000, HIRE_DATE=2009-05-01, BONUS=500, MANAGER=1005, JOB=Manager, NAME=黄蓉}
第9行:{DEPT_TEST_ID=30, EMP_ID=1009, SALARY=4000, HIRE_DATE=2009-02-20, BONUS=null, MANAGER=1008, JOB=salesman, NAME=韦小宝}
第10行:{DEPT_TEST_ID=30, EMP_ID=1010, SALARY=4500, HIRE_DATE=2009-05-10, BONUS=500, MANAGER=1008, JOB=salesman, NAME=郭靖}
第11行:{DEPT_TEST_ID=null, EMP_ID=1011, SALARY=null, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=于泽成}
第12行:{DEPT_TEST_ID=null, EMP_ID=1012, SALARY=null, HIRE_DATE=2011-08-10, BONUS=null, MANAGER=null, JOB=null, NAME=amy}
第13行:{DEPT_TEST_ID=null, EMP_ID=1014, SALARY=8000, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=张无忌}
第14行:{DEPT_TEST_ID=20, EMP_ID=1015, SALARY=null, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=刘苍松}
第15行:{DEPT_TEST_ID=null, EMP_ID=1013, SALARY=10000, HIRE_DATE=2016-12-17, BONUS=null, MANAGER=null, JOB=developer, NAME=测试更新}DELETE FROM emp_test WHERE job = developer  AND emp_id = 1013
成功删除了1行执行删除后的数据
SELECT  * FROM emp_test
成功查询到了14行数据
第1行:{DEPT_TEST_ID=10, EMP_ID=1001, SALARY=10000, HIRE_DATE=2010-01-12, BONUS=2000, MANAGER=1005, JOB=Manager, NAME=张无忌}
第2行:{DEPT_TEST_ID=10, EMP_ID=1002, SALARY=8000, HIRE_DATE=2011-01-12, BONUS=1000, MANAGER=1001, JOB=Analyst, NAME=刘苍松}
第3行:{DEPT_TEST_ID=10, EMP_ID=1003, SALARY=9000, HIRE_DATE=2010-02-11, BONUS=1000, MANAGER=1001, JOB=Analyst, NAME=李翊}
第4行:{DEPT_TEST_ID=10, EMP_ID=1004, SALARY=5000, HIRE_DATE=2010-02-11, BONUS=null, MANAGER=1001, JOB=Programmer, NAME=郭芙蓉}
第5行:{DEPT_TEST_ID=20, EMP_ID=1005, SALARY=15000, HIRE_DATE=2008-02-15, BONUS=null, MANAGER=null, JOB=President, NAME=张三丰}
第6行:{DEPT_TEST_ID=20, EMP_ID=1006, SALARY=5000, HIRE_DATE=2009-02-01, BONUS=400, MANAGER=1005, JOB=Manager, NAME=燕小六}
第7行:{DEPT_TEST_ID=20, EMP_ID=1007, SALARY=3000, HIRE_DATE=2009-02-01, BONUS=500, MANAGER=1006, JOB=clerk, NAME=陆无双}
第8行:{DEPT_TEST_ID=30, EMP_ID=1008, SALARY=5000, HIRE_DATE=2009-05-01, BONUS=500, MANAGER=1005, JOB=Manager, NAME=黄蓉}
第9行:{DEPT_TEST_ID=30, EMP_ID=1009, SALARY=4000, HIRE_DATE=2009-02-20, BONUS=null, MANAGER=1008, JOB=salesman, NAME=韦小宝}
第10行:{DEPT_TEST_ID=30, EMP_ID=1010, SALARY=4500, HIRE_DATE=2009-05-10, BONUS=500, MANAGER=1008, JOB=salesman, NAME=郭靖}
第11行:{DEPT_TEST_ID=null, EMP_ID=1011, SALARY=null, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=于泽成}
第12行:{DEPT_TEST_ID=null, EMP_ID=1012, SALARY=null, HIRE_DATE=2011-08-10, BONUS=null, MANAGER=null, JOB=null, NAME=amy}
第13行:{DEPT_TEST_ID=null, EMP_ID=1014, SALARY=8000, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=张无忌}
第14行:{DEPT_TEST_ID=20, EMP_ID=1015, SALARY=null, HIRE_DATE=null, BONUS=null, MANAGER=null, JOB=null, NAME=刘苍松}带条件的查询1
SELECT  * FROM emp_test WHERE job = clerk  AND salary = 3000
成功查询到了1行数据
第1行:{DEPT_TEST_ID=20, EMP_ID=1007, SALARY=3000, HIRE_DATE=2009-02-01, BONUS=500, MANAGER=1006, JOB=clerk, NAME=陆无双}带条件的查询2
SELECT  * FROM emp_test WHERE salary = 10000
成功查询到了1行数据
第1行:{DEPT_TEST_ID=10, EMP_ID=1001, SALARY=10000, HIRE_DATE=2010-01-12, BONUS=2000, MANAGER=1005, JOB=Manager, NAME=张无忌}
1

十.GitHub

JDBC批处理使用起来要小心

转自:https://blog.csdn.net/xly_971223/article/details/83284003

看下面的方法
Connection conn = getConnection();PreparedStatement ps = null;try {conn.setAutoCommit(false);ps = conn.prepareStatement("insert into t_user(username, password) values(?,?)");Random r = new Random();for(int i = 0; i < 1000; i++){ps.setString(1, String.valueOf(r.nextInt(Integer.MAX_VALUE)));ps.setString(2, String.valueOf(r.nextInt()));ps.executeUpdate();[color=red]conn.commit(); //每次都提交[/color]
            }} catch (SQLException e) {conn.rollback();throw e;}finally{ps.close();conn.close();}

循环每次都开启一个事务 插入一千条数据 耗时 29078 ms

Connection conn = getConnection();PreparedStatement ps = null;try {conn.setAutoCommit(false);ps = conn.prepareStatement("insert into t_user(username, password) values(?,?)");Random r = new Random();for(int i = 0; i < 1000; i++){ps.setString(1, String.valueOf(r.nextInt(Integer.MAX_VALUE)));ps.setString(2, String.valueOf(r.nextInt()));ps.executeUpdate();}conn.commit(); //只提交一次} catch (SQLException e) {conn.rollback();throw e;}finally{ps.close();conn.close();}

只开启一次事务 耗时 703 ms
但这不是推荐用法,jdbc有一个批处理方法 专门处理这种批量操作的 ps.addBatch();

Connection conn = getConnection();PreparedStatement ps = null;try {conn.setAutoCommit(false);ps = conn.prepareStatement("insert into t_user(username, password) values(?,?)");Random r = new Random();for(int i = 0; i < 1000; i++){ps.setString(1, String.valueOf(r.nextInt(Integer.MAX_VALUE)));ps.setString(2, String.valueOf(r.nextInt()));ps.addBatch();//加入批处理//ps.executeUpdate();不能与addBatch()同时用
}int[] results = ps.executeBatch();//执行批处理
            conn.commit();} catch (SQLException e) {conn.rollback();throw e;}finally{ps.close();conn.close();}

批处理方式 耗时 781 ms

跟只开启一次事务效率差不多

这里要着重指出addBatch()和executeUpdate()不要同时用否则会导致记录插入两次
本来1000条记录 会插入2000条,本人在开始就翻了这个错误

第一种方法与第二 三种方法性能差别达 40倍 看来事务真是性能杀手啊 能少开尽量少开啦

转载于:https://www.cnblogs.com/wynjauu/articles/10669957.html

玩转JDBC打造数据库操作万能工具类JDBCUtil,加入了高效的数据库连接池,利用了参数绑定有效防止SQL注入...相关推荐

  1. 玩转JDBC打造数据库操作万能工具类JDBCUtil,加入了高效的数据库连接池,利用了参数绑定有效防止SQL注入

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53750584 本文出自[DylanAndroid的博客] 玩转JDBC打造数据 ...

  2. JAVA高效率 (秒级) 将千万条数据导入数据库 (已封装工具类)【详解】【一看就懂】

    该gif做了加速处理,便于观看~  今天在将一个500w+条数据的文件导入至数据库时,遇到一个异常,相信做大数据应该都有遇到.500w条数据说多不多,说少也不少.既然问题出现了,那么就一定要解决. 异 ...

  3. 第十三天 - 封装JDBC操作Hive工具类 - HWI配置与使用 - JavaWeb结合Hive

    第十三天 - 封装JDBC操作Hive工具类 - HWI配置与使用 - JavaWeb结合Hive 第十三天 - 封装JDBC操作Hive工具类 - HWI配置与使用 - JavaWeb结合Hive ...

  4. Java操作大数据量Excel导入导出万能工具类(完整版)

    Java操作大数据量Excel导入导出万能工具类(完整版) 转载自:https://blog.csdn.net/JavaWebRookie/article/details/80843653 更新日志: ...

  5. java中文件操作的工具类

    代码: package com.lky.pojo;import java.io.BufferedReader; import java.io.BufferedWriter; import java.i ...

  6. android文件读取工具类,Android 下读取Assets Properties操作封装工具类

    Android 下读取Assets Properties操作封装工具类 发布时间:2018-06-03作者:laosun阅读(2081) 为了方便使用,首先创建BaseApplication类,如下所 ...

  7. 自己封装的poi操作Excel工具类

    在上一篇文章<使用poi读写Excel>中分享了一下poi操作Excel的简单示例,这次要分享一下我封装的一个Excel操作的工具类. 该工具类主要完成的功能是:读取Excel.汇总Exc ...

  8. java操作svn工具类

    依赖包 <dependency><groupId>org.tmatesoft.svnkit</groupId><artifactId>svnkit< ...

  9. C#万能工具类部分代码

    C#万能工具类 class Utils {//获取路径public static string GetImagePath(){string personImgPath = Path.GetDirect ...

最新文章

  1. Linux 学习手记(1):命令行BASH的基本操作
  2. 【Redis】18.缓存预热、缓存雪崩、缓存击穿、缓存穿透、性能指标监控等企业级解决方案
  3. C++:编译实验之递归下降分析器
  4. MYSQL定时创建表分区
  5. win11虚拟机如何安装 Windows11虚拟机安装步骤教程
  6. 动态切换tableView中的cell的种类
  7. java class getfields_JAVA反射中的getFields()方法和getDeclaredFields ()方法的区别
  8. PickerView的使用
  9. 计算机考试vb试题英语成绩,计算机二级考试vb试题_vb试题及参考答案
  10. Java零基础学习-API每日单词(日更)
  11. css数字怎么换行,css实现连续的英文或数字自动换行的方法
  12. 浏览器点击复制内容并打开微信
  13. 转: 学习开源项目的若干建议(infoq)
  14. module github.com/jinzhu/gorm/dialects/mysql: git ls-remote -q origin in E:\go_gin\pkg\mod\cache\vcs
  15. android灯光蜂鸣器控制节点指令代码,北斗手机app -北斗手机appV1.5.48
  16. js-获取子节点--具体节点调用
  17. 最具影响力的机器人公司
  18. 电脑如何查看及开启虚拟化
  19. 杜克大学计算机数据科学,杜克大学的数据科学专业解析
  20. 【蓝桥杯选拔赛真题45】Scratch猫鼠游戏 少儿编程scratch蓝桥杯选拔赛真题讲解

热门文章

  1. 如何更改CSDN博客皮肤
  2. 常见登录密码加密方式
  3. Unity Game Cloud
  4. ASP.NET Razor 简介
  5. OPA 论坛为流程控制设备接口扩展了开放性、互操作性标准 - 第一部分
  6. img标签 src路径正确 但图片不显示
  7. 流媒体学习之路(WebRTC)——GCC分析(2)
  8. 【前端笔记】Ant Design Form组件 resetFields() 与 setFieldsValue() 之比较
  9. PicPick Pro v7.0.0 屏幕截图编辑工具解锁全功能单文件版
  10. Three.js从入门到放弃