问题
When generating test data, I want a field in new rows to default to a value of gibberish generated by lorem, a Lorem Ipsum generator for Java.
Calling the lorem tool in Java looks like this:
String lorem = LoremIpsum.getInstance().getWords( 100 , 120 );
I tried this SQL as my table definition:
String sql =
"""
CREATE ALIAS LOREM FOR "com.thedeanda.lorem.LoremIpsum.getInstance().getWords( 100 , 120 )";
CREATE TABLE IF NOT EXISTS thing_
(
nonsense_ text NOT NULL ,
row_created_ TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP() ,
id_ uuid NOT NULL DEFAULT RANDOM_UUID() ,
CONSTRAINT thing_pkey_ PRIMARY KEY ( id_ )
)
;
""";
But that throws:
org.h2.jdbc.JdbcSQLSyntaxErrorException: The public static Java method was not found: "getInstance().getWords(100,120) (com.thedeanda.lorem.LoremIpsum)"; SQL statement:
CREATE ALIAS LOREM FOR "com.thedeanda.lorem.LoremIpsum.getInstance().getWords( 100 , 120 )"; [90139-200]
Is there some way to wrap a call to a Java method to be used as a function within SQL for H2?
回答1:
I don't think you can include the parameters, and you can't invoke an instance method. You need to make a single static method:
public class Whatever {
public static String generateLorem() {
return LoremIpsum.getInstance().getWords(100, 120);
}
}
and then
CREATE ALIAS LOREM FOR "com.foo.Whatever.generateLorem";
回答2:
The Answer by rzwitserloot is correct.
In addition, here is a complete example app demonstrating the approach seen in that Answer.
To run this code, replace the file path argument in the call to ds.setURL
to name and place the database file to your liking. Then run the main
method.
package work.basil.example;
import com.thedeanda.lorem.LoremIpsum;
import org.h2.jdbcx.JdbcDataSource;
import javax.sql.DataSource;
import java.sql.*;
import java.time.*;
import java.util.Objects;
import java.util.UUID;
public class FiftyMillion
{
DataSource dataSource;
public static String generateLorem ( )
{
return LoremIpsum.getInstance().getWords( 100 , 120 );
}
public static void main ( String[] args )
{
FiftyMillion app = new FiftyMillion();
app.prepareDatabase();
app.makeRow();
app.dumpRows();
// app.populateDatabase();
// app.exportDatabaseToCsv();
}
// Constructor
public FiftyMillion ( )
{
// DataSource
org.h2.jdbcx.JdbcDataSource ds = Objects.requireNonNull( new JdbcDataSource() ); // Implementation of `DataSource` bundled with H2.
ds.setURL( "jdbc:h2:/Volumes/blue_disc/fifty_million;" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
ds.setDescription( "An example database showing ResultSet access to 50 million records." );
this.dataSource = ds;
}
private void prepareDatabase ( )
{
String lorem = LoremIpsum.getInstance().getWords( 100 , 120 );
String sql =
"""
CREATE ALIAS IF NOT EXISTS LOREM FOR "work.basil.example.FiftyMillion.generateLorem" ;
CREATE TABLE IF NOT EXISTS thing_
(
nonsense_ text NOT NULL DEFAULT LOREM() ,
row_created_ TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP() ,
id_ uuid NOT NULL DEFAULT RANDOM_UUID() ,
CONSTRAINT thing_pkey_ PRIMARY KEY ( id_ )
)
;
""";
try (
Connection conn = dataSource.getConnection() ;
Statement stmt = conn.createStatement() ;
)
{
System.out.println( "INFO - Running `prepareDatabase` method." );
stmt.executeUpdate( sql );
}
catch ( SQLException e )
{
e.printStackTrace();
}
}
private void makeRow ( )
{
try
(
Connection conn = this.dataSource.getConnection() ;
Statement stmt = conn.createStatement() ;
)
{
// String lorem = LoremIpsum.getInstance().getWords( 100 , 120 );
String sql =
"""
INSERT INTO thing_ ()
VALUES ()
;
""";
stmt.executeUpdate( sql );
}
catch ( SQLException e )
{
e.printStackTrace();
}
}
private void dumpRows ( )
{
try
(
Connection conn = this.dataSource.getConnection() ;
Statement stmt = conn.createStatement() ;
)
{
String sql =
"""
TABLE thing_
;
""";
stmt.executeQuery( sql );
ResultSet rs = stmt.executeQuery( sql );
while ( rs.next() )
{
String nonsense = rs.getString( "nonsense_" );
Instant whenCreated = rs.getObject( "row_created_" , OffsetDateTime.class ).toInstant();
UUID id = rs.getObject( "id_" , UUID.class );
System.out.println( "whenCreated = " + whenCreated + " | " + "id : " + id + " | " + "nonsense = " + nonsense );
}
}
catch ( SQLException e )
{
e.printStackTrace();
}
}
private void populateDatabase ( )
{
}
private void exportDatabaseToCsv ( )
{
}
}
来源:https://stackoverflow.com/questions/64960344/generate-default-values-for-new-rows-in-h2-database-by-calling-a-java-method