关于jdbc编程的几点需要注意的地方

时间:2023-01-08 15:09:03

代码

private void logDataDb(ArrayList<ReceiveData> datas) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        String sql = "INSERT INTO MON_ALARM_LOG (TIME,TOPIC,DIMENSION,CURRENTVALUE,ALERTMAIL,ALERTPHONE,DESCRIPTION,LEVEL) "
                + " VALUES(?,?,?,?,?,?,?,?)";
        try {
            conn = DBUtils.getConnection(dbcpPath);
            conn.setAutoCommit(false);
            pstmt = conn.prepareStatement(sql);
            pstmt.clearBatch();
            Iterator<ReceiveData> ite = datas.iterator();
            while (ite.hasNext()) {
                ReceiveData data = ite.next();
                pstmt.setTimestamp(1, data.getTime());
                pstmt.setString(2, data.getTopic());
                pstmt.setString(3, data.getDimension());
                pstmt.setDouble(4, data.getValue());
                pstmt.setString(5, data.getAlertMail());
                pstmt.setString(6, data.getAlertPhone());
                pstmt.setString(7, data.getDescription());
                pstmt.setInt(8, data.getLevel());
                pstmt.addBatch();
            }
            pstmt.executeBatch();
            conn.commit();
            conn.setAutoCommit(true);
        } catch (SQLException e) {
            LOG.error("保存切片数据出错,MsgAndDbSink.logDataDb()" + e);
        }finally{
            if(pstmt!=null)
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
        }
    }

1、当一次性需要向数据库插入多条数据时,应该使用jdbc的batch操作。


2、在使用batch插入的时候,需要将connection的autoCommit设置为false,否则将会影响性能,与逐条插入无异。

 

3、在executeBatch()之后,需要进行connection.commit()因为在之前已将autoCommit设为false,需要手工commit。

 

4、在最后connection.close()之前,需要将connection的autoCommit设置为其默认的true。

     这是因为对于从连接池获取的connection而言,close()只是将其还给连接池从而达到复用的目的,如果不将autoCommit恢复到默认的true,那么之后该connection被其他

     程序取出使用的时候,将仍然是一个autoCommit=false的链接。 容易引起问题。 且由于连接池的池资源特性,该问题会成为一个不知何时会发生、难以人工重现的问题。