简体   繁体   中英

JDBCTemplate + MySQL Primary Key to Foreign Key

I am new to JDBC and how it uses the database. We were shown an example, but had no database or shown any kind of working functionality. What I am trying to do is create a UserName and a User at the same time.

The username must be created first because it contains the primary key. The issue I am having is when I create the user and the username, the foreign key in the User table for Username is null.

CREATE TABLE `username` ( `UserNameId` int(11) NOT NULL AUTO_INCREMENT, `UserName` varchar(55) DEFAULT NULL,   `Password` varchar(100) DEFAULT NULL `RoleId` int(11) DEFAULT NULL,`enabled` tinyint(4) DEFAULT '1',PRIMARY KEY (`UserNameId`),KEY `fkrole_idx` (`RoleId`),CONSTRAINT `fkrole` FOREIGN KEY (`RoleId`) REFERENCES `role` (`roleId`) ON DELETE NO ACTION ON UPDATE NO ACTION ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8;


CREATE TABLE `user` (`UserID` int(11) NOT NULL AUTO_INCREMENT, `FirstName` varchar(55) DEFAULT NULL, `LastName` varchar(55) DEFAULT NULL,`BirthDate` date DEFAULT NULL,`Address` varchar(55) DEFAULT NULL,`StateId` int(11) DEFAULT NULL,`Zip` int(9) DEFAULT NULL,`EducationID` int(11) DEFAULT NULL,`UserNameID` int(11) DEFAULT NULL,`Email` varchar(55) DEFAULT NULL,`PhoneNumber` varchar(55) DEFAULT NULL,`description` varchar(500) DEFAULT NULL,`Resume` varchar(4000) DEFAULT NULL,PRIMARY KEY (`UserID`),UNIQUE KEY`UserNameID_UNIQUE` (`UserNameID`),KEY `fkstateID`(`StateId`),KEY`fkeducationID` (`EducationID`),KEY `fkusername` (`UserID`),KEY `fkusernameID_idx` (`UserNameID`),CONSTRAINT `fkeducationID` FOREIGN KEY(`EducationID`) REFERENCES `education` (`EducationId`) ON DELETE NO ACTION ON UPDATE NO ACTION,CONSTRAINT `fkstateID` FOREIGN KEY (`StateId`) REFERENCES `state` (`StateId`) ON DELETE NO ACTION ON UPDATE NO ACTION,CONSTRAINT `fkusernameID` FOREIGN KEY (`UserNameID`) REFERENCES `username` (`UserNameId`) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE=InnoDB AUTO_INCREMENT=144 DEFAULT CHARSET=utf8;

private static final String INSERT_USER = "INSERT INTO USER (`firstName`, `lastName`, `birthdate`,`address`,`stateid`,`zip`,`educationId`,`userNameId`,`email`,`phoneNumber`,`description`) VALUES (?,?,?,?,?,?,?,?,?,?,?);";
private static final String INSERT_USERNAME = "INSERT INTO USERNAME (`userName`, `password`, `roleId`,`enabled`) VALUES (?,?,?,?)";


@Override
public void add(UserName userName) {
    this.jdbcTemplate.update(INSERT_USERNAME, 
            userName.getUserName(),
            userName.getPassword(),
            userName.getRole().getRoleId(),
            userName.isEnabled());
}

@Override
public void add(User user) {
    this.jdbcTemplate.update(INSERT_USER,user.getFirstName(),
            user.getLastName(),user.getBirthdate(),user.getAddress(),user.getState().getStateId(),
            user.getZip(),user.getEducation().getEducationId(),user.getUserName().getUserNameId(),user.getEmail(),user.getPhoneNumber(),
            user.getDescription());
}
public class UserNameRowMapper implements RowMapper<UserName> {

private static final int USERNAMEID_FIELD = 1;
private static final int USERNAME_USERNAME_FIELD = 2;
private static final int USERNAME_PASSWORD_FIELD = 3;
private static final int USERNAME_ROLE_FIELD = 4;
private static final int USERNAME_ENABLED_FIELD = 5;

@Override
public UserName mapRow(ResultSet rs, int rowNum) throws SQLException {
    UserName userName = new UserName();
    userName.setUserNameId(rs.getInt(USERNAMEID_FIELD));
    userName.setUserName(rs.getString(USERNAME_USERNAME_FIELD));
    userName.setPassword(rs.getString(USERNAME_PASSWORD_FIELD));
    Role role = new Role();
        role.setRoleId(rs.getInt(USERNAME_ROLE_FIELD));
    userName.setRole(role);
    userName.setEnabled(rs.getBoolean(USERNAME_ENABLED_FIELD));
    return userName;
}

public class UserRowMapper implements RowMapper<User> {

private static final int USERID_FIELD = 1;
private static final int USER_FIRSTNAME_FIELD = 2;
private static final int USER_LASTNAME_FIELD = 3;
private static final int USER_BIRTHDATE_FIELD = 4;
private static final int USER_ADDRESS_FIELD = 5;
private static final int USER_STATE_FIELD = 6;
private static final int USER_ZIP_FIELD = 7;
private static final int USER_EDUCATION_FIELD = 8;
private static final int USERNAME_FIELD = 9;
private static final int USER_EMAIL_FIELD = 10;
private static final int USER_PHONENUMBER_FIELD = 11;
private static final int USER_DESCRIPTION_FIELD = 12;

@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
    User user = new User();
        user.setUserId(rs.getInt(USERID_FIELD));
        user.setFirstName(rs.getString(USER_FIRSTNAME_FIELD));
        user.setLastName(rs.getString(USER_LASTNAME_FIELD));
        user.setBirthdate(rs.getDate(USER_BIRTHDATE_FIELD));
        user.setAddress(rs.getString(USER_ADDRESS_FIELD));
        State state = new State();
            state.setStateId(USER_STATE_FIELD);
        user.setState(state);
        user.setZip(rs.getInt(USER_ZIP_FIELD));
        Education education = new Education();
        education.setEducationId(rs.getInt(USER_EDUCATION_FIELD));
            user.setEducation(education);
        Integer userNameID = rs.getInt(USERNAME_FIELD);
          if (userNameID != 0) {
              UserName username = new UserName();
              username.setUserNameId(userNameID);
              user.setUserName(username);

          }
        user.setEmail(rs.getString(USER_EMAIL_FIELD));
        user.setPhoneNumber(rs.getString(USER_PHONENUMBER_FIELD));
        user.setDescription(rs.getString(USER_DESCRIPTION_FIELD));

    return user;
}

@Override
public void add(User user) {
    user.getUserName().setPassword(encoder.encode(user.getUserName().getPassword()));
    unDao.add(user.getUserName());

    userDao.add(user);

}

Since the username id is generated at the database side (using AUTO_INCREMENT )

`UserNameId` int(11) NOT NULL AUTO_INCREMENT

you'll need to make use of a GeneratedKeyHolder to retrieve the generated primary key value first. The downside of this is that you'll need to write some crude JDBC code too. You need to change the add(UserName un) method as follows. You can optionally make it return the primary key too.

@Override
public Number add(UserName userName) {
    KeyHolder holder = new GeneratedKeyHolder();
    this.jdbcTemplate.update(
        new PreparedStatementCreator() {
          public PreparedStatement createPreparedStatement(Connection connection)
                                                            throws SQLException {
            PreparedStatement pstmt = connection.prepareStatement(
                                      INSERT_USERNAME, new String[] {"UserNameId"});
            pstmt.setString(1, userName.getUserName());
            pstmt.setString(2, userName.getPassword());
            pstmt.setInt(3, userName.getRole().getRoleId());
            pstmt.setBoolean(4, userName.isEnabled());
            return pstmt;
          }
        }, holder);
    Number key = holder.getKey();
    userName.setUserNameId(key.intValue());
    return key;
}

Since, the userName object passed to the method gets updated too, the subsequent userDao.add(user); statement should start working as it is.

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