java原生程序mysql连接(Durid连接池和普通连接)选择问题

版权声明:虽然坑有点多,不过转载请声明原作者 https://blog.csdn.net/jyj1100/article/details/86516169

最近遇到的连接问题我准备从重构的几个程序(redis和mysql)长连接和短连接,以及连接池和单连接等问题用几篇博客来总结下。

这个问题的具体发生在java原生程序和mysql的交互中。心得和上一篇一样,不过没用好也有对连接池的不熟悉的原因,连接池本身的api和配置项,以及与一些框架的集合仍然是值得研究的问题(这次因为方向问题先回避了)。


应用场景2

java原生程序,内部写多个线程,均会产生mysql的数据输出。

开始直接使用durid连接池获取连接,但在程序的运行过程中连接会掉,且不会抛出异常,但却导致程序卡住,逻辑功能出现异常。

最开始是想通过在配置文件中配置自动连接和重连接,但是该项配置没有起作用。

尝试过的配置(失败的带研究的配置):

druid.url=jdbc:mysql://0.0.0.0:3306/test?useUnicode=yes&characterEncoding=UTF-8&autoReconnect=true

后面采用获取短连接的方式,在执行业务后关闭连接。

然后因为业务的简便性更进一步采用单连接的方式处理了该问题。其中核心仍然是不断初始化对象获取连接和关闭连接。修改后基本utils代码如下

public class JDBCUtil {
​
    //JDBC驱动
    private static String jdbcDriver = "com.mysql.jdbc.Driver";
    //数据库用户名
    private static String username = "mysql";
    //数据库密码
    private static String password = "123456";
    //数据库连接字符串
    private static String connStr = "jdbc:mysql://0.0.0.0:3306/test";
​
    private Connection conn;
​
    public JDBCUtil(){
        try {
            getConnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 连接数据库
     *
     * @throws SQLException
     */
    public Connection getConnect() throws Exception {
        Class.forName(jdbcDriver);
        conn = DriverManager.getConnection(connStr, username, password);
        return conn;
    }
​
    /**
     * 关闭数据库,释放内存
     *
     * @throws SQLException
     */
    public void close() throws SQLException {
        if (conn != null) {
            conn.close();
        }
    }
​
    /**
     * 设置PrepareStatement对象中Sql语句中的参数
     *
     * @param sql    sql语句
     * @param params 参数列表
     * @throws SQLException
     */
    @SuppressWarnings("unused")
    private PreparedStatement setPrepareStatementParams(String sql, Object[] params) throws SQLException {
        PreparedStatement pstm = conn.prepareStatement(sql);
        if (params != null) {
            for (int i = 0; i < params.length; i++){
                pstm.setObject(i + 1, params[i]);
            }
        }
        return  pstm;
    }
​
    /**
     * 执行查询
     *
     * @param sql    sql语句
     * @param params 参数列表
     * @return 返回ResultSet类型的查询结果
     * @throws SQLException
     */
    public ResultSet executeQuery(String sql, Object[] params) throws Exception {
        PreparedStatement pstm = setPrepareStatementParams(sql, params);
        ResultSet rs = pstm.executeQuery();
        return rs;
    }
​
    /**
     * 更新数据库操作
     *
     * @param sql    sql语句
     * @param params 参数列表
     * @return 执行操作的结果
     * @throws SQLException
     */
    public void executeUpdate(String sql, Object[] params) throws Exception {
        setPrepareStatementParams(sql, params).executeUpdate();
    }
}

其他问题

第一次重写方法的时候,我采用了静态类和单例模式,直接导致我两个线程之间创建连接出现冲突。这在java多线程的使用中应该值得注意。

猜你喜欢

转载自blog.csdn.net/jyj1100/article/details/86516169