我想在数据库中插入一个记录(在我的情况下是Microsoft SQL Server)使用Java中的JDBC。同时,我想获取插入ID。我如何使用JDBC API实现这一点?
当前回答
在我的例子中是>
ConnectionClass objConnectionClass=new ConnectionClass();
con=objConnectionClass.getDataBaseConnection();
pstmtGetAdd=con.prepareStatement(SQL_INSERT_ADDRESS_QUERY,Statement.RETURN_GENERATED_KEYS);
pstmtGetAdd.setString(1, objRegisterVO.getAddress());
pstmtGetAdd.setInt(2, Integer.parseInt(objRegisterVO.getCityId()));
int addId=pstmtGetAdd.executeUpdate();
if(addId>0)
{
ResultSet rsVal=pstmtGetAdd.getGeneratedKeys();
rsVal.next();
addId=rsVal.getInt(1);
}
其他回答
使用Hibernate的NativeQuery,您需要返回一个ResultList而不是SingleResult,因为Hibernate修改了一个本机查询
INSERT INTO bla (a,b) VALUES (2,3) RETURNING id
like
INSERT INTO bla (a,b) VALUES (2,3) RETURNING id LIMIT 1
如果你试图得到一个单一的结果,这将导致大多数数据库(至少PostgreSQL)抛出一个语法错误。然后,您可以从列表中获取结果id(通常只包含一个项)。
在我的例子中是>
ConnectionClass objConnectionClass=new ConnectionClass();
con=objConnectionClass.getDataBaseConnection();
pstmtGetAdd=con.prepareStatement(SQL_INSERT_ADDRESS_QUERY,Statement.RETURN_GENERATED_KEYS);
pstmtGetAdd.setString(1, objRegisterVO.getAddress());
pstmtGetAdd.setInt(2, Integer.parseInt(objRegisterVO.getCityId()));
int addId=pstmtGetAdd.executeUpdate();
if(addId>0)
{
ResultSet rsVal=pstmtGetAdd.getGeneratedKeys();
rsVal.next();
addId=rsVal.getInt(1);
}
我只是想回答这个帖子,而不是评论。
接口java.sql.PreparedStatement
columnIndexes « You can use prepareStatement function that accepts columnIndexes and SQL statement. Where columnIndexes allowed constant flags are Statement.RETURN_GENERATED_KEYS1 or Statement.NO_GENERATED_KEYS[2], SQL statement that may contain one or more '?' IN parameter placeholders. SYNTAX « Connection.prepareStatement(String sql, int autoGeneratedKeys) Connection.prepareStatement(String sql, int[] columnIndexes) Example: PreparedStatement pstmt = conn.prepareStatement( insertSQL, Statement.RETURN_GENERATED_KEYS );
columnNames«列出columnNames,如'id', 'uniqueID', ....在包含应返回的自动生成键的目标表中。如果SQL语句不是INSERT语句,驱动程序将忽略它们。 语法« 连接。prepareStatement(String sql, String[] columnNames) 例子: String columnNames[] = new String[] {"id"}; PreparedStatement pstmt = conn.prepareStatement(insertSQL, columnNames);
完整的例子:
public static void insertAutoIncrement_SQL(String UserName, String Language, String Message) {
String DB_URL = "jdbc:mysql://localhost:3306/test", DB_User = "root", DB_Password = "";
String insertSQL = "INSERT INTO `unicodeinfo`( `UserName`, `Language`, `Message`) VALUES (?,?,?)";
//"INSERT INTO `unicodeinfo`(`id`, `UserName`, `Language`, `Message`) VALUES (?,?,?,?)";
int primkey = 0 ;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection conn = DriverManager.getConnection(DB_URL, DB_User, DB_Password);
String columnNames[] = new String[] { "id" };
PreparedStatement pstmt = conn.prepareStatement( insertSQL, columnNames );
pstmt.setString(1, UserName );
pstmt.setString(2, Language );
pstmt.setString(3, Message );
if (pstmt.executeUpdate() > 0) {
// Retrieves any auto-generated keys created as a result of executing this Statement object
java.sql.ResultSet generatedKeys = pstmt.getGeneratedKeys();
if ( generatedKeys.next() ) {
primkey = generatedKeys.getInt(1);
}
}
System.out.println("Record updated with id = "+primkey);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
当使用Statement时遇到“不支持的功能”错误。RETURN_GENERATED_KEYS,试试这个:
String[] returnId = { "BATCHID" };
String sql = "INSERT INTO BATCH (BATCHNAME) VALUES ('aaaaaaa')";
PreparedStatement statement = connection.prepareStatement(sql, returnId);
int affectedRows = statement.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating user failed, no rows affected.");
}
try (ResultSet rs = statement.getGeneratedKeys()) {
if (rs.next()) {
System.out.println(rs.getInt(1));
}
rs.close();
}
其中BATCHID是自动生成的id。
如果它是一个自动生成的键,那么你可以使用Statement#getGeneratedKeys()。您需要在与INSERT使用的语句相同的Statement上调用它。首先需要使用statement创建语句。RETURN_GENERATED_KEYS通知JDBC驱动程序返回密钥。
这里有一个基本的例子:
public void create(User user) throws SQLException {
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL_INSERT,
Statement.RETURN_GENERATED_KEYS);
) {
statement.setString(1, user.getName());
statement.setString(2, user.getPassword());
statement.setString(3, user.getEmail());
// ...
int affectedRows = statement.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating user failed, no rows affected.");
}
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
if (generatedKeys.next()) {
user.setId(generatedKeys.getLong(1));
}
else {
throw new SQLException("Creating user failed, no ID obtained.");
}
}
}
}
注意,您依赖于JDBC驱动程序来决定它是否工作。目前,最后的大多数版本都可以工作,但如果我是正确的,Oracle JDBC驱动程序在这方面仍然有些麻烦。MySQL和DB2已经支持它很多年了。PostgreSQL不久前开始支持它。我不能评论MSSQL,因为我从未使用过它。
对于Oracle,您可以在同一个事务中的INSERT语句后直接调用带有RETURNING子句或SELECT CURRVAL(sequencename)(或任何特定于db的语法)的CallableStatement来获得最后生成的密钥。看看这个答案。
推荐文章
- 比较两个SQL Server数据库(模式和数据)的最佳工具是什么?
- 如何在java中格式化持续时间?(如格式H:MM:SS)
- 在SQL中,如何在范围中“分组”?
- urlencoder .encode(字符串)已弃用,我应该使用什么代替?
- javax.transaction.Transactional vs . org.springframework.transaction.annotation.Transactional
- Java 8接口方法中不允许“同步”的原因是什么?
- 选项(RECOMPILE)总是更快;为什么?
- 设置数据库从单用户模式到多用户
- 如何找到Java堆大小和内存使用(Linux)?
- oracle中的RANK()和DENSE_RANK()函数有什么区别?
- 的类型不能用作索引中的键列
- SQL逻辑运算符优先级:And和Or
- 使用Enum实现单例(Java)
- 如何检查一个表是否存在于给定的模式中
- RabbitMQ与通道和连接之间的关系