tl;博士
- 将 Java 中的
null JDBC 代码作为参数传递给 PreparedStatement::set… 会导致数据库行中出现 NULL 值。
- 例外:如果你用
NOT NULL定义你的列,那么这样的提交当然会被数据库系统拒绝。
在 Java 中传递 null
您的问题不完整,应根据发布的 cmets 重写。
但我可以展示一些通用示例代码供您阅读。通过 JDBC 在 Java 中传递 null 将导致您的数据库中出现空值。
pstmt.setString( 1 , "John Doe" );
pstmt.setObject( 2 , null ); // <-- Passing `null` into the SQL prepared statement.
pstmt.executeUpdate();
这是一个使用H2 Database Engine 的完整示例应用程序。 H2 是关系数据库的纯 Java 实现,可以像任何其他依赖项一样被拉入示例应用程序。
我希望在 Postgres 上运行相同类型的代码。
package work.basil.example;
import java.sql.*;
import java.time.LocalDate;
import java.time.Month;
import java.util.Objects;
import java.util.UUID;
import org.h2.jdbcx.JdbcDataSource;
public class ExampleH2App
{
public static void main ( String[] args )
{
ExampleH2App app = new ExampleH2App();
app.doIt();
}
private void doIt ( )
{
JdbcDataSource dataSource = Objects.requireNonNull( new JdbcDataSource() ); // Implementation of `DataSource` bundled with H2.
// The `mem` in URL means "in-memory-only".
// Set `DB_CLOSE_DELAY` to `-1` to keep in-memory database in existence after connection closes.
dataSource.setURL( "jdbc:h2:mem:h2_example_db;DB_CLOSE_DELAY=-1" );
dataSource.setUser( "scott" );
dataSource.setPassword( "tiger" );
try (
Connection conn = dataSource.getConnection() ;
// Set `DB_CLOSE_DELAY` to `-1` to keep in-memory database in existence after connection closes.
Statement stmt = conn.createStatement() ;
)
{
String sql =
"""
CREATE TABLE person_ (
pkey_ UUID NOT NULL DEFAULT RANDOM_UUID() PRIMARY KEY ,
name_ VARCHAR NOT NULL ,
birthdate_ DATE
);
""";
stmt.execute( sql );
// Insert row.
sql = """
INSERT INTO person_( name_ , birthdate_ )
VALUES( ? , ? )
;
""";
try (
PreparedStatement pstmt = conn.prepareStatement( sql , Statement.RETURN_GENERATED_KEYS ) ;
)
{
pstmt.setString( 1 , "Margaret Hamilton" ); // https://en.wikipedia.org/wiki/Margaret_Hamilton_(software_engineer)
pstmt.setObject( 2 , LocalDate.of( 1936 , Month.AUGUST , 17 ) );
pstmt.executeUpdate();
pstmt.setString( 1 , "John Doe" );
pstmt.setObject( 2 , null ); // <-- Passing `null` into the SQL prepared statement.
pstmt.executeUpdate();
ResultSet rs = pstmt.getGeneratedKeys();
System.out.println( "INFO - Reporting generated keys." );
while ( rs.next() )
{
UUID uuid = rs.getObject( 1 , UUID.class );
System.out.println( "generated keys: " + uuid );
}
}
// Dump all rows.
System.out.println( "INFO - Reporting all rows in table `person_`." );
sql = "SELECT * FROM person_";
try ( ResultSet rs = stmt.executeQuery( sql ) ; )
{
while ( rs.next() )
{
UUID pkey = rs.getObject( "pkey_" , UUID.class );
String name = rs.getString( "name_" );
LocalDate birthdate = rs.getObject( "birthdate_" , LocalDate.class );
System.out.println( "Person: " + pkey + " | " + name + " | " + birthdate );
}
}
}
catch ( SQLException e )
{
e.printStackTrace();
}
}
}
运行时:
INFO - Reporting generated keys.
generated keys: 386460f8-c2d4-4207-9291-e5aa7eb51471
INFO - Reporting all rows in table `person_`.
Person: ad05fb5e-e731-4a61-ae03-9ed8d9ede100 | Margaret Hamilton | 1936-08-17
Person: 386460f8-c2d4-4207-9291-e5aa7eb51471 | John Doe | null
提示:避免使用诸如date 之类的关键字来命名数据库中的列或其他对象。不幸的是,各种数据库系统中有超过一千个关键字和保留字。因此,避免所有这些都是棘手的。我的解决方案:我用一个尾随下划线命名我的所有数据库对象。 SQL 规范明确承诺在任何命名中绝不使用尾随下划线。
顺便说一句,不需要将年龄存储在表中。给定存储的日期,您可以在 SQL 查询或 Java 代码中即时计算年龄。