我有一个带有 SQL 数据库的 java 应用程序,使用 preparedStatement 将行插入数据库。我希望程序能够根据序列号(唯一)更新行。
Connection conn = null;
Statement st = null;
try {
conn = DriverManager.getConnection ("jdbc:derby://localhost:1527/db01", "Administrator", "admin"); //run procedure getConnection to connect to the database - see below
st = conn.createStatement(); //set up a statement st to enable you to send SQL statements to the database.
} catch (SQLException ex) {
Logger.getLogger(FormTwo1.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println ("Successful Connection");
...
String query = "insert into TB01(SERIAL,BLADETYPE,STARTT1,AIRT1,FOAMT1,SCT1,FINISHT1) values (?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
pstmt.setString(1, bladeSerial);
pstmt.setString(2, itemText);
pstmt.setString(3, String.valueOf(startTime1));
pstmt.setString(4, String.valueOf(airTime1));
pstmt.setString(5, String.valueOf(foamTime1));
pstmt.setString(6, String.valueOf(scTime1));
pstmt.setString(7, String.valueOf(finishTime1));
pstmt.executeUpdate();
} catch (SQLException ex) {
// Exception handling
Logger.getLogger(FormTwo1.class.getName()).log(Level.SEVERE, null, ex);
}
其中serial、bladetype是VARCHAR,startT1、foamTime1、scTime1和finishTime1都是LocalTime变量(因此使用string.valueof进行格式化)。
数据库为db01,表为TB01
我希望程序根据序列号是否已在数据库中插入/更新记录。
代码现在可以运行了。感谢普拉尚特的回答。稍作调整后效果很好
String query = ("UPDATE TB01 SET BLADETYPE=?,STARTT1=?,AIRT1=?,FOAMT1=?,SCT1=?,FINISHT1=? WHERE SERIAL=?");
try (PreparedStatement pstmt = conn.prepareStatement(query)) {
pstmt.setString(7, bladeSerial);
pstmt.setString(1, itemText);
pstmt.setString(2, String.valueOf(startTime1));
pstmt.setString(3, String.valueOf(airTime1));
pstmt.setString(4, String.valueOf(foamTime1));
pstmt.setString(5, String.valueOf(scTime1));
pstmt.setString(6, String.valueOf(finishTime1));
pstmt.executeUpdate();
}
catch (SQLException ex) {
// Exception handling
Logger.getLogger(FormTwo1.class.getName()).log(Level.SEVERE, null, ex);
}
注意,由于 SERIAL 已移至字符串末尾,因此 setString 命令的顺序也需要更改。
public boolean updateFavoriteColorOfPersonById ( final int id , final String newFavoriteColor )
{
@Language ( "SQL" )
String sql = """
UPDATE person_
SET favorite_color_ = ?
WHERE id_ = ?
;
""";
try (
Connection connection = this.dataSource.getConnection( ) ;
PreparedStatement preparedStatement = connection.prepareStatement( sql ) ;
)
{
preparedStatement.setString( 1 , newFavoriteColor );
preparedStatement.setInt( 2 , id );
int countRows = preparedStatement.executeUpdate( );
return ( 1 == countRows );
} catch ( SQLException e )
{
throw new RuntimeException( e );
}
}
这是在 JDBC 代码中使用准备好的语句的更完整示例。
让我们追踪每个人最喜欢的颜色作为记录。
public record Person( int id , String name , String favoriteColor ) { }
在
DatabaseUtils
类中创建并填充匹配表。在实际工作中,我们会使用数据库迁移工具,例如Flyway或Liquibase。
package work.basil.example.db.updating;
import org.h2.jdbcx.JdbcDataSource;
import org.intellij.lang.annotations.Language;
import javax.sql.DataSource;
import java.sql.*;
import java.util.List;
public class DatabaseUtils
{
static DataSource obtainDataSource ( )
{
// In a real project, this would be obtained via JNDI from a naming/directory service like an LDAP server or a Microsoft Active Directory server.
// Here we fake it with a hard-coded object.
org.h2.jdbcx.JdbcDataSource ds = new JdbcDataSource( ); // Implementation of `DataSource` bundled with H2.
ds.setURL( "jdbc:h2:mem:updating_ex_db;DB_CLOSE_DELAY=-1" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
ds.setDescription( "An example database for updating a row by id." );
return ds;
}
static void createTable ( final DataSource dataSource )
{
@Language ( "SQL" )
String sql = """
CREATE TABLE person_
(
id_ INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, -- ⬅ `identity` = auto-incrementing integer number.
name_ VARCHAR NOT NULL ,
favorite_color_ VARCHAR NOT NULL
)
;
""";
try (
Connection connection = dataSource.getConnection( ) ;
Statement statement = connection.createStatement( ) ;
)
{
statement.execute( sql );
} catch ( SQLException e )
{
throw new RuntimeException( e );
}
}
static void populateTable ( final DataSource dataSource )
{
@Language ( "SQL" )
String sql = """
INSERT INTO person_ ( name_ , favorite_color_ )
VALUES ( ? , ? )
;
""";
try (
Connection connection = dataSource.getConnection( ) ;
PreparedStatement preparedStatement = connection.prepareStatement( sql ) ;
)
{
record Input( String name , String color ) { }
List < Input > inputs =
List.of(
new Input( "Alice" , "Apricot" ) ,
new Input( "Bob" , "Burgundy" ) ,
new Input( "Carol" , "Cerise" )
);
for ( Input input : inputs )
{
preparedStatement.setString( 1 , input.name );
preparedStatement.setString( 2 , input.color );
int rowCount = preparedStatement.executeUpdate( );
if ( rowCount != 1 ) throw new IllegalStateException( "Failed to insert " + input + " into database" );
}
} catch ( SQLException e )
{
throw new RuntimeException( e );
}
}
static void dumpTable ( final DataSource dataSource )
{
@Language ( "SQL" )
String sql = """
SELECT *
FROM person_
;
""";
try (
Connection connection = dataSource.getConnection( ) ;
Statement statement = connection.createStatement( ) ;
ResultSet resultSet = statement.executeQuery( sql ) ;
)
{
System.out.println( "---------| Start dump of table person_ |--------------------" );
while ( resultSet.next( ) )
{
Person person =
new Person(
resultSet.getInt( "id_" ) ,
resultSet.getString( "name_" ) ,
resultSet.getString( "favorite_color_" )
);
System.out.println( person );
}
System.out.println( "---------| End dump of table person_ |--------------------" );
} catch ( SQLException e )
{
throw new RuntimeException( e );
}
}
}
为我们的数据库访问工作定义一个
Repository
接口。
public interface Repository
{
public boolean updateFavoriteColorOfPersonById ( int id , String newFavoriteColor );
}
专门为H2数据库引擎实现该接口。请注意我们如何使用 try-with-resources 语法来自动关闭
PreparedStatement
和 Connection
对象。
package work.basil.example.db.updating;
import org.intellij.lang.annotations.Language;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class RepositoryH2 implements Repository
{
private final DataSource dataSource;
public RepositoryH2 ( final DataSource dataSource ) { this.dataSource = dataSource; }
@Override
public boolean updateFavoriteColorOfPersonById ( final int id , final String newFavoriteColor )
{
@Language ( "SQL" )
String sql = """
UPDATE person_
SET favorite_color_ = ?
WHERE id_ = ?
;
""";
try (
Connection connection = this.dataSource.getConnection( ) ;
PreparedStatement preparedStatement = connection.prepareStatement( sql ) ;
)
{
preparedStatement.setString( 1 , newFavoriteColor );
preparedStatement.setInt( 2 , id );
int countRows = preparedStatement.executeUpdate( );
return ( 1 == countRows );
} catch ( SQLException e )
{
throw new RuntimeException( e );
}
}
}
还有一个应用程序类来练习此代码。
package work.basil.example.db.updating;
import javax.sql.DataSource;
public class UpdateDemo
{
public static void main ( String[] args )
{
UpdateDemo app = new UpdateDemo( );
app.demo( );
}
private void demo ( )
{
DataSource dataSource = DatabaseUtils.obtainDataSource( );
// In a real project, this create-and-populate work would be done with a database migration tool like Flyway or Liquibase.
DatabaseUtils.createTable( dataSource );
DatabaseUtils.populateTable( dataSource );
DatabaseUtils.dumpTable( dataSource );
// Demonstrate updating.
Repository repository = new RepositoryH2( dataSource );
repository.updateFavoriteColorOfPersonById( 2 , "Chartreuse" ); // https://en.wikipedia.org/wiki/Chartreuse_(color)
// Result. We want to see "Cerise" changed to "Chartreuse".
DatabaseUtils.dumpTable( dataSource );
}
}
运行时:
---------| Start dump of table person_ |--------------------
Person[id=1, name=Alice, favoriteColor=Apricot]
Person[id=2, name=Bob, favoriteColor=Burgundy]
Person[id=3, name=Carol, favoriteColor=Cerise]
---------| End dump of table person_ |--------------------
---------| Start dump of table person_ |--------------------
Person[id=1, name=Alice, favoriteColor=Apricot]
Person[id=2, name=Bob, favoriteColor=Chartreuse]
Person[id=3, name=Carol, favoriteColor=Cerise]
---------| End dump of table person_ |--------------------
try{
String host="jdbc:derby://localhost:1527/databasename";
String user="database_user_name";
String pass="database_password";
Connection con=DriverManager.getConnection(host,user,pass);
PreparedStatement stmt=con.prepareStatement("update table_name set BLADETYPE=?,STARTT1=?,AIRT1=?,FOAMT1=?,SCT1=?,FINISHT1, where SERIAL=?");
stmt.setString(1, itemText);
stmt.setString(2, String.valueOf(startTime1));
stmt.setString(3, String.valueOf(airTime1));
stmt.setString(4, String.valueOf(foamTime1));
stmt.setString(5, String.valueOf(scTime1));
stmt.setString(6, String.valueOf(finishTime1));
stmt.setString(7, bladeSerial);
stmt.executeUpdate();
}
catch (SQLException ex) {
Logger.getLogger(FormTwo1.class.getName()).log(Level.SEVERE, null, ex);
}