Java学习

Java使用DBCP连接池操作MySQL

2020-09-11  本文已影响0人  xiaogp

摘要:DBCPBasicDataSourceMySQLStatementPreparedStatement

DBCP简介

DBCP(DataBase connection pool)数据库连接池是 apache 上的一个Java连接池项目。实际开发中获得连接释放资源是非常消耗系统资源的两个过程。DBCP通过连接池预先同数据库建立一些连接放在内存中(即连接池中),应用程序需要建立数据库连接时直接到从接池中申请一个连接使用,用完后由连接池回收该连接,从而达到连接复用减少资源消耗的目的。

DBCP依赖

<dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.36</version>
        </dependency>

DBCP连接池参数说明

创建DBCP连接池单例对象

创建连接池单例对象,如果应用需要调用多个不同的mysql服务器的连接池,创建一个Mapname得到连接池。

import org.apache.commons.dbcp.BasicDataSource;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class MySQLUtils {
    private static BasicDataSource mysqlConn = null;
    private static final Map<String, BasicDataSource> mysqlConnMap = new HashMap<>();

    public static BasicDataSource getConnPool(Properties prop) {
        if (mysqlConn == null) {
            synchronized (MySQLUtils.class) {
                if (mysqlConn == null) {
                    mysqlConn = new BasicDataSource();
                    mysqlConn.setDriverClassName(prop.getProperty("jdbc.driver"));
                    mysqlConn.setUrl(prop.getProperty("jdbc.url"));
                    mysqlConn.setUsername(prop.getProperty("jdbc.user"));
                    mysqlConn.setPassword(prop.getProperty("jdbc.passwd"));
                    mysqlConn.setMaxActive(4);
                    mysqlConn.setMaxIdle(4);
                    mysqlConn.setMinIdle(2);
                    mysqlConn.setInitialSize(4);
                    mysqlConn.setMaxWait(10000);
                    mysqlConn.setTestWhileIdle(true);
                    mysqlConn.setValidationQuery("select 1");
                    mysqlConn.setValidationQueryTimeout(10000);
                    mysqlConn.setTimeBetweenEvictionRunsMillis(10000);
                }
            }
        }
        return mysqlConn;
    }

    public static BasicDataSource getConnPool(Properties prop, String name) {
        if (!mysqlConnMap.containsKey(name)) {
            synchronized (MySQLUtils.class) {
                if (!mysqlConnMap.containsKey(name)) {
                    BasicDataSource tmpConn = new BasicDataSource();
                    tmpConn.setDriverClassName(prop.getProperty("jdbc.driver"));
                    tmpConn.setUrl(prop.getProperty("jdbc." + name + ".url"));
                    tmpConn.setUsername(prop.getProperty("jdbc." + name + ".user"));
                    tmpConn.setPassword(prop.getProperty("jdbc." + name + ".passwd"));
                    tmpConn.setMaxActive(4);
                    tmpConn.setMaxIdle(4);
                    tmpConn.setMinIdle(2);
                    tmpConn.setInitialSize(4);
                    tmpConn.setMaxWait(10000);
                    tmpConn.setTestWhileIdle(true);
                    tmpConn.setValidationQuery("select 1");
                    tmpConn.setValidationQueryTimeout(10000);
                    tmpConn.setTimeBetweenEvictionRunsMillis(10000);
                    mysqlConnMap.put(name, tmpConn);
                }
            }
        }
        return mysqlConnMap.get(name);
    }
}

DBCP连接池操作MySQL

从连接池单例中拿到BasicDataSource对象,如果BasicDataSource不为空,初始化Connection和查询对象,包括StatementPreparedStatement,区别如下:

使用Statement进行简单查询

public static void easySearch(Properties prop) {
        BasicDataSource connPool = MySQLUtils.getConnPool(prop);
        if (connPool != null) {
            Connection conn = null;
            Statement statement = null;
            try {
                conn = connPool.getConnection();
                statement = conn.createStatement();
                ResultSet res = statement.executeQuery("select name, score from student_info");
                while (res.next()) {
                    System.out.println("name => " + res.getString("name"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (statement != null) {
                        statement.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                }catch (Exception e) {
                    System.out.println();
                    e.printStackTrace();
                }
            }
        }
    }

in条件查询

public static void inSearch(Properties prop) {
        BasicDataSource connPool = MySQLUtils.getConnPool(prop);
        if (connPool != null) {
            Connection conn = null;
            Statement statement = null;
            try {
                conn = connPool.getConnection();
                statement = conn.createStatement();
                List<String> param = Arrays.asList("gp", "wf");
                String param2 = param.stream().map(s -> "\"" + s + "\"").collect(Collectors.joining(","));
                ResultSet res = statement.executeQuery(String.format("select name, score from student_info where name in (%s)", param2));
                while (res.next()) {
                    System.out.println("name:" + res.getString("name"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (statement != null) {
                        statement.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

使用PreparedStatement将语句预编译再查询,将固定部分先编译,再使用将传参部分作为占位符,使用setString传参,默认位置从1开始。

public static void prepareStatementTest(Properties prop, String query) {
        BasicDataSource connPool = MySQLUtils.getConnPool(prop);
        if (connPool != null) {
            Connection conn = null;
            PreparedStatement preparedStatement = null;
            try {
                conn = connPool.getConnection();
                preparedStatement = conn.prepareStatement("select score from student_info where name = ?");
                preparedStatement.setString(1, query);
                ResultSet res = preparedStatement.executeQuery();
                while (res.next()) {
                    System.out.println(res.getString("score"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (preparedStatement != null) {
                        preparedStatement.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

在in查询中使用PreparedStatement,有多少个参数就传多少个占位符

public static void prepareStatementTest2(Properties prop, Collection<String> collections) {
        BasicDataSource connPool = MySQLUtils.getConnPool(prop);
        if (connPool != null) {
            Connection conn = null;
            PreparedStatement preparedStatement = null;
            try {
                conn = connPool.getConnection();
                String param = collections.stream().map(s -> "?").collect(Collectors.joining(","));
                preparedStatement = conn.prepareStatement(String.format("select score from student_info where name in (%s)", param));
                int index = 1;
                for (String s : collections) {
                    preparedStatement.setString(index, s);
                    index += 1;
                }
                ResultSet res = preparedStatement.executeQuery();
                while (res.next()) {
                    System.out.println(res.getString("score"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (preparedStatement != null) {
                        preparedStatement.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

使用PreparedStatement预编译插入语句,调用addBatchexecuteBatch进行批量插入

    public static void batchInsertTest(Properties prop) {
        BasicDataSource connPool = MySQLUtils.getConnPool(prop);
        if (connPool != null) {
            Connection conn = null;
            PreparedStatement preparedStatement = null;
            try {
                conn = connPool.getConnection();
                preparedStatement = conn.prepareStatement("insert into student_info (name,score)  values (?,?)");
                conn.setAutoCommit(false);
                for (int i = 1; i <= 10; i++) {
                    preparedStatement.setString(1, "gp" + i);
                    preparedStatement.setString(2, String.valueOf(i));
                    preparedStatement.addBatch();
                    if(i % 5 == 0){
                        preparedStatement.executeBatch();
                        conn.commit();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (preparedStatement != null) {
                        preparedStatement.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

删除数据,使用execute执行sql语句。

public static void deleteData(Properties prop, String string) {
        BasicDataSource connPool = MySQLUtils.getConnPool(prop);
        if (connPool != null) {
            Connection conn = null;
            Statement statement = null;
            try {
                conn = connPool.getConnection();
                statement = conn.createStatement();
                statement.execute(String.format("delete from student_info where name = '%s'", string));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (statement != null) {
                        statement.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

update修改数据,使用execute语句

public static void alterData(Properties prop) {
        BasicDataSource connPool = MySQLUtils.getConnPool(prop);
        if (connPool != null) {
            Connection conn = null;
            Statement statement = null;
            try {
                conn = connPool.getConnection();
                statement = conn.createStatement();
                statement.execute("update student_info set score = 5 where name = \"zzb\"");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (statement != null) {
                        statement.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

测试多个连接池对象,使用Map获得对应的连接池。

public static void mapPoolTest(Properties prop, String poolName) {
        BasicDataSource connPool = MySQLUtils.getConnPool(prop, poolName);
        if (connPool != null) {
            Connection conn = null;
            Statement statement = null;
            try {
                conn = connPool.getConnection();
                statement = conn.createStatement();
                ResultSet res = statement.executeQuery("select name, score from student_info");
                while (res.next()) {
                    System.out.println("name => " + res.getString("name"));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (statement != null) {
                        statement.close();
                    }
                    if (conn != null) {
                        conn.close();
                    }
                }catch (Exception e) {
                    System.out.println();
                    e.printStackTrace();
                }
            }
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读