简体   繁体   中英

Multiply table insert using JDBC

I'm trying insert into three tables, using JDBC. My code query rans well in MySQL Workbench, but when I run it using PreparedStatement , I run into error saying

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use

My query looks like

BEGIN; 
INSERT INTO user_authentication (enabled, password, username) values (1,'password','username');
SET @userId = LAST_INSERT_ID();
INSERT INTO account(is_active, balance, user_id) values(1,0.0,@userId); 
INSERT INTO user_information (email, firstname, lastname, user_id) values ('OLeg@mail.com','Oleg','Oleg',@userId); 
INSERT INTO user_authorization (role, user_id) values ('ROLE_USER', @userId); 
COMMIT; 

It seems that error is due to that BEGIN; statement. How can I run multiply insert query using JDBC and PreparedStatement ?

Whole method looks like

@Override
public void save(User user) {
    Connection conn = null;
    Account account = user.getAccount();
    UserInformation information = user.getUserInformation();
    Set<UserAuthorization> roles = user.getRoles();
    String insertUserQuery = "INSERT INTO user_authentication (enabled, password, username) values (?,?,?);";
    String insertAccountQuery = "INSERT INTO account(is_active, balance, user_id) values(?,?,@userId);";
    String insertInformationQuery = "INSERT INTO user_information (email, firstname, lastname, user_id) values (?,?,?,@userId);";
    String insertRolesQuery = "INSERT INTO user_authorization (role, user_id) values (?, @userId);";
    String query = "BEGIN;" + insertUserQuery
            + " SET @userId = LAST_INSERT_ID(); " + insertAccountQuery
            + insertInformationQuery + insertRolesQuery + "COMMIT;";
    try {
        conn = dataSource.getConnection();
        PreparedStatement statement = conn.prepareStatement(query);
        statement.setBoolean(1, true);
        statement.setString(2, user.getPassword());
        statement.setString(3, user.getUsername());
        statement.setBoolean(4, true);
        statement.setDouble(5, account.getBalance());
        statement.setString(6, information.getEmail());
        statement.setString(7, information.getFirstName());
        statement.setString(8, information.getLastName());
        for (UserAuthorization role : roles) {
            statement.setString(9, role.getRole().toString());
        }
        statement.executeUpdate();

    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

You are mixing up terms a bit here. You are trying to execute a transaction, which consists of multiple statements/queries.

You cannot simply concatenate all the strings. You have 4 different inserts. Therefore, you must create 4 (prepared) statement objects in java for these inserts. You will need an additional statement to retrieve the generated id (for the foreign keys).

Regarding BEGIN and COMMIT: You should use the 'commit()' method of the PreparedStatement object. See this Oracle JDBC tutorial

Please also note the line con.setAutoCommit(false); in the example. JDBC has autocommit enabled by default, so you need to turn it off first.

And it seems unnaturally three times trigger database from one java method invocation.

If you run your script from mysql workbench you still execute multiple statements/queries. Your (workbench) sample code 'triggers' the db 7 times, which means there are 7 round-trips workbench <-> database.

yes, but I need that local variable '@userId', to insert foreign keys.

Better to read the generated key back into you program ie 'select LAST_INSERT_ID()' or better see this question or even better that question . Then use it as a parameter for inserting the other rows.

for (UserAuthorization role : roles) {
    statement.setString(9, role.getRole().toString());
}
statement.executeUpdate();

Won't give you the expected result. You are (re-)setting the parameter over and over again (just in your program, not in the db). See the top section of the tutorial, where the benefits of PreparedStatment are explained.

Hope this clears things up a bit ....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM