com.ninja_squad.dbsetup.operation
Class Insert

java.lang.Object
  extended by com.ninja_squad.dbsetup.operation.Insert
All Implemented Interfaces:
Operation

@Immutable
public final class Insert
extends java.lang.Object
implements Operation

Operation which inserts one or several rows into a table. Example usage:

   Insert insert =
       Insert.into("CLIENT")
             .columns("CLIENT_ID", "FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "CLIENT_TYPE")
             .values(1L, "John", "Doe", "1975-07-19", ClientType.NORMAL)
             .values(2L, "Jack", "Smith", "1969-08-22", ClientType.HIGH_PRIORITY)
             .withDefaultValue("DELETED", false)
             .withDefaultValue("VERSION", 1)
             .withBinder(new ClientTypeBinder(), "CLIENT_TYPE")
             .build();
 
The above operation will insert two rows inside the CLIENT table. For each row, the column DELETED will be set to false and the column VERSION will be set to 1. For the column CLIENT_TYPE, instead of using the Binder associated to the type of the column found in the metadata of the table, a custom binder will be used.

Instead of specifying values as an ordered sequence which must match the sequence of column names, some might prefer passing a map of column/value associations. This makes things more verbose, but can be more readable in some cases, when the number of columns is high. This also allows not specifying any value for columns that must stay null. The map can be constructed like any other map and passed to the builder, or it can be added using a fluent builder. The following snippet:

   Insert insert =
       Insert.into("CLIENT")
             .columns("CLIENT_ID", "FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "CLIENT_TYPE")
             .row().column("CLIENT_ID", 1L)
                   .column("FIRST_NAME", "John")
                   .column("LAST_NAME", "Doe")
                   .column("DATE_OF_BIRTH", "1975-07-19")
                   .end()
             .row().column("CLIENT_ID", 2L)
                   .column("FIRST_NAME", "Jack")
                   .column("LAST_NAME", "Smith")
                   .end() // null date of birth, because it's not in the row
             .build();
 
is thus equivalent to:
   Map<String, Object> johnDoe = new HashMap<String, Object>();
   johnDoe.put("CLIENT_ID", 1L);
   johnDoe.put("FIRST_NAME", "John");
   johnDoe.put("LAST_NAME", "Doe");
   johnDoe.put("DATE_OF_BIRTH", "1975-07-19");

   Map<String, Object> jackSmith = new HashMap<String, Object>();
   jackSmith.put("CLIENT_ID", 2L);
   jackSmith.put("FIRST_NAME", "Jack");
   jackSmith.put("LAST_NAME", "Smith");

   Insert insert =
       Insert.into("CLIENT")
             .columns("CLIENT_ID", "FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "CLIENT_TYPE")
             .values(johnDoe)
             .values(jackSmith)
             .build();
 
When building the Insert using column/value associations, it might seem redundant to specify the set of column names before inserting the rows. Remember, though, that all the rows of an Insert are inserted using the same parameterized SQL query. We thus need a robust and easy way to know all the columns to insert for every row of the insert. To be able to spot errors easily and early, and to avoid complex rules, the rule is thus simple: the set of columns (excluding the generated ones) is specified either by columns(), or by the columns of the first row. All the subsequent rows may not have additional columns. And null is inserted for all the absent columns of the subsequent rows. The above example can thus be written as
   Insert insert =
       Insert.into("CLIENT")
             .row().column("CLIENT_ID", 1L)
                   .column("FIRST_NAME", "John")
                   .column("LAST_NAME", "Doe")
                   .column("DATE_OF_BIRTH", "1975-07-19")
                   .end()
             .row().column("CLIENT_ID", 2L)
                   .column("FIRST_NAME", "Jack")
                   .column("LAST_NAME", "Smith")
                   .end() // null date of birth, because it's not in the row
             .build();
 
but the following will throw an exception, because the DATE_OF_BIRTH column is not part of the first row:
   Insert insert =
       Insert.into("CLIENT")
             .row().column("CLIENT_ID", 2L)
                   .column("FIRST_NAME", "Jack")
                   .column("LAST_NAME", "Smith")
                   .column("CLIENT_TYPE", ClientType.HIGH_PRIORITY)
                   .end()
             .row().column("CLIENT_ID", 1L)
                   .column("FIRST_NAME", "John")
                   .column("LAST_NAME", "Doe")
                   .column("DATE_OF_BIRTH", "1975-07-19")
                   .column("CLIENT_TYPE", ClientType.NORMAL)
                   .end()
             .build();
 


Nested Class Summary
static class Insert.Builder
          A builder used to create an Insert operation.
static class Insert.RowBuilder
          A row builder, constructed with Insert.Builder.row().
 
Method Summary
 boolean equals(java.lang.Object obj)
           
 void execute(java.sql.Connection connection, BinderConfiguration configuration)
          Inserts the values and generated values in the table.
 int getRowCount()
          Gets the number of rows that are inserted in the database table when this insert operation is executed.
 int hashCode()
           
static Insert.Builder into(java.lang.String table)
          Creates a new Builder instance, in order to build an Insert operation into the given table
 java.lang.String toString()
           
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Method Detail

execute

public void execute(java.sql.Connection connection,
                    BinderConfiguration configuration)
             throws java.sql.SQLException
Inserts the values and generated values in the table. Unless useMetadata has been set to false, the given configuration is used to get the appropriate binder. Nevertheless, if a binder has explicitely been associated to a given column, this binder will always be used for this column.

Specified by:
execute in interface Operation
Parameters:
connection - the connection used to execute the operation
configuration - the binder configuration, used to get appropriate binders based on the metadata of the prepared statements
Throws:
java.sql.SQLException - if the execution throws a SQLException

getRowCount

public int getRowCount()
Gets the number of rows that are inserted in the database table when this insert operation is executed.


toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

hashCode

public int hashCode()
Overrides:
hashCode in class java.lang.Object

equals

public boolean equals(java.lang.Object obj)
Overrides:
equals in class java.lang.Object

into

public static Insert.Builder into(@Nonnull
                                  java.lang.String table)
Creates a new Builder instance, in order to build an Insert operation into the given table

Parameters:
table - the name of the table to insert into
Returns:
the created Builder