【问题标题】:PreparedStatement execute() doesn't affect the databasePreparedStatement execute() 不影响数据库
【发布时间】:2016-11-11 14:42:03
【问题描述】:

我在使用 jdbc 将数据插入 mysql 数据库时遇到问题。 向数据库添加新用户时,我得到一个新连接,创建一个准备好的语句并执行查询。但是,数据库中没有显示任何结果。

例如,假设我使用 MySql 查询浏览器在数据库中手动添加了一个新用户。

  • 我添加了一个新用户 --> name = Stefano,pin = 1010
  • 会生成一个自动递增的 id:id = 1。

假设我决定以编程方式添加一个新用户:

  • 我调用方法addUser(String username, int pin) --> addUser("pippo", 7636);
  • 没有错误发生
  • 我打开 MySql 查询浏览器并没有添加任何用户。

最后我手动添加了一个新用户: 名称 = 冥王星,引脚 = 3434。

现在我的表格结果:

id name pin
1 stefano 1010
3 pluto 3434

id=2 丢失。所以pippo已经加了但是我看不到。

怎么了?

这里简化了我的java代码:

package simpleexample;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SimpleExample {

public static void addUser(String username, int pin) {
    
    Connection conn = null;
    PreparedStatement preparedStmt = null;
    String insertSQL = "insert into users(name, pin) values (?, ?)";

    try {

        conn = DBConnectionPool.getConnection();

        preparedStmt = conn.prepareStatement(insertSQL);
        preparedStmt.setString(1, username);
        preparedStmt.setInt(2, pin);
        preparedStmt.execute();

    } catch (SQLException ex) {
        Logger.getLogger(SimpleExample.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        if (conn != null) {
            DBConnectionPool.releaseConnection(conn);
        }
    }
}

public static void main(String[] args) {
    
    addUser("pippo", 7636);
}
}

这里是 DBConnectionPool 类:

package simpleexample;

import java.util.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;

/**
  * This class simulates a db connection pool
  */
 public class DBConnectionPool {

/*
 * This code prepare the db connection pool. In particular, it creates the
 * free connections queue and defines the db properties.
 */
static {
    freeDbConnections = new ArrayList<Connection>();
    try {
        DBConnectionPool.loadDbProperties();
        DBConnectionPool.loadDbDriver();
    } catch (ClassNotFoundException e) {
        System.out.println("DB DRIVER NOT FOUND!");
        System.exit(1);
    } catch (IOException e) {
        System.out.println("DB CONNECTION POOL ERROR!");
        System.exit(2);
    }
}

/**
 * The db properties (driver, url, login, and password)
 */
private static Properties dbProperties;

/**
 * The free connection queue
 */
private static List<Connection> freeDbConnections;

/**
 * Returns a free db connection accessing to the free db connection queue.
 * If the queue is empty a new db connection will be created.
 *
 * @return A db connection
 * @throws SQLException
 */
public static synchronized Connection getConnection() throws SQLException {
    Connection connection;

    if (!freeDbConnections.isEmpty()) {
        // Extract a connection from the free db connection queue
        connection = freeDbConnections.get(0);
        DBConnectionPool.freeDbConnections.remove(0);

        try {
            // If the connection is not valid, a new connection will be
            // analyzed
            if (connection.isClosed()) {
                connection = DBConnectionPool.getConnection();
            }
        } catch (SQLException e) {
            connection = DBConnectionPool.getConnection();
        }
    } else // The free db connection queue is empty, so a new connection will
    // be created
    {
        connection = DBConnectionPool.createDBConnection();
    }

    return connection;
}

/**
 * Releases the connection represented by <code>pReleasedConnection</code>
 * parameter
 *
 * @param pReleasedConnection The db connection to release
 */
public static synchronized void releaseConnection(
        Connection pReleasedConnection) {

    // Add the connection to the free db connection queue
    DBConnectionPool.freeDbConnections.add(pReleasedConnection);
}

/**
 * Creates a new db connection
 *
 * @return A db connection
 * @throws SQLException
 */
private static Connection createDBConnection() throws SQLException {
    Connection newConnection = null;

    // Create a new db connection using the db properties
    // newConnection = DriverManager.getConnection(
    //    "jdbc:mysql://localhost/resources", "root", "");
    newConnection = DriverManager.getConnection(
            DBConnectionPool.dbProperties.getProperty("url"),
            DBConnectionPool.dbProperties.getProperty("username"),
            DBConnectionPool.dbProperties.getProperty("password"));

    newConnection.setAutoCommit(false);

    return newConnection;
}

private static void loadDbDriver() throws ClassNotFoundException {
    Class.forName(DBConnectionPool.dbProperties.getProperty("driver"));
}

/**
 * Loads the db properties
 *
 * @throws IOException
 */
private static void loadDbProperties() throws IOException {
    InputStream fileProperties = new FileInputStream("database.properties");
    DBConnectionPool.dbProperties = new Properties();

    DBConnectionPool.dbProperties.load(fileProperties);
}

}

注意:我在项目中有一个文件 Database.properties

  • driver=org.gjt.mm.mysql.Driver
  • url=jdbc:mysql://localhost/name_db
  • 用户名=root
  • 密码='密码'

我已经在其他项目中使用过 DBConnectionPool 类,而且它一直运行良好。所以我不明白出了什么问题。也许关于交易?

【问题讨论】:

    标签: java mysql database jdbc


    【解决方案1】:

    您在连接池中禁用了自动提交(说真的:不要自己动手,使用现有的,他们会做得比这更好)。

    您永远不会在代码中的任何地方调用 commit,因此永远不会提交结果(最终当连接真正关闭或以其他方式丢失时,更改将被回滚)。

    我的建议:

    1. 完成工作单元后,请致电commit()(或rollback())。
    2. 开始使用真正的连接池,例如 HikariCP、DBCP 或 c3p0

    【讨论】:

    • 是的,你说得对:大错特错!!!!谢谢,我真的忘记提交更改了。
    【解决方案2】:

    你需要使用 executeUpdate() 而不是 execute()。

    https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#executeUpdate(java.lang.String)

    int executeUpdate(String sql) 抛出 SQLException

    执行给定的 SQL 语句,可能是 INSERT、UPDATE 或 DELETE 语句或不返回任何内容的 SQL 语句,例如 SQL DDL 语句。

    https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#execute(java.lang.String)

    布尔执行(字符串 sql) 抛出 SQLException

    execute方法执行一条SQL语句,表示形式 第一个结果。然后您必须使用方法 getResultSet 或 getUpdateCount 检索结果,getMoreResults 移动到 任何后续结果。

    【讨论】:

    • 调用execute 而不是executeUpdate 会起作用(我确信一些JDBC 实现实际上是从executeUpdate 调用它们的execute 实现)。
    • 我也试过用 executeUpdate(),但结果是一样的:/
    猜你喜欢
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多