You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

01_model_classes.mkd 7.4KB

Model Classes

A model class represents a single table within your database. Fields within your model class represent columns in the table. The object types of your fields are reflectively mapped to SQL types by iciql at runtime.

Models can be manually written using one of two approaches: annotation configuration or interface configuration. Both approaches can be used within a project and both can be used within a single model class, although that is discouraged.

Alternatively, model classes can be automatically generated by iciql using the model generation tool. Please see the tools page for details.

Configuration Requirements and Limitations

  1. Your model class must provide a public default constructor.
  2. Only the specified types are supported. Other types such as arrays and custom types are not supported.
  3. Triggers, views, and other advanced database features are not supported.

Fully Supported Data Types

The following data types can be used for all iciql expressions.

All Databases
java.lang.String VARCHAR (length > 0) or TEXT (length == 0)
java.lang.Boolean BIT
java.lang.Byte TINYINT
java.lang.Short SMALLINT
java.lang.Integer INT
java.lang.Long BIGINT
java.lang.Float REAL
java.lang.Double DOUBLE
java.math.BigDecimal DECIMAL
java.sql.Date DATE
java.sql.Time TIME
java.sql.Timestamp TIMESTAMP
java.util.Date TIMESTAMP
java.lang.Enum.name()
default type
VARCHAR (length > 0) or TEXT (length == 0)
EnumType.NAME
java.lang.Enum.ordinal() INT
EnumType.ORDINAL
java.lang.Enum implements
com.iciql.Iciql.EnumId.enumId()
INT
EnumType.ENUMID
H2 Databases
java.util.UUID UUID

NOTE:
The reverse lookup used for model generation, SQL type -> Java type, contains more mappings.
Please consult the com.iciql.ModelUtils class for details.

Partially Supported Data Types

The following data types can be mapped to columns for all general statements BUT these field types may not be used to specify compile-time clauses or constraints.

byte [] BLOB
boolean BIT
byte TINYINT
short SMALLINT
int INT
long BIGINT
float REAL
double DOUBLE

Partially Supported Data Types Example

%BEGINCODE% class Primitives {

@IQColumn(primaryKey = true)
int id;

@IQColumn
String name;

public Primitives() {
}

public Primitives(int id, String name) {
    this.id = id;
    this.name = name;
}    

}

Primitives p = new Primitives();

// the following expressions compile, but will throw iciql runtime exceptions db.from(p).where(p.id).is(100).selectFirst(); db.from(p).where(p.id).atLeast(10).select();

// the following expressions will work as expected db.from(p).select(); db.from(p).where(“id = ?”, 100).selectFirst(); db.from(p).where(“id >= ?”, 10).select(); db.insert(new Primitives(150, “test”)); db.update(new Primitives(150, “modified”)); db.delete(new Primitives(150, “test”)); %ENDCODE%

Annotation Configuration

The recommended approach to setup a model class is to annotate the class and field declarations.

advantages

  • annotated fields may have any scope
  • annotated models support annotated field inheritance making it possible to design a single base class that defines the fields and then create table subclasses that specify the table mappings.
  • model runtime dependency is limited to the small, portable com.iciql.Iciql class file which contains the annotation definitions

disadvantages

  • more verbose model classes
  • indexes are defined using “fragile” string column names
  • compound primary keys are defined using “fragile” string column names

Example Annotated Model

%BEGINCODE% import com.iciql.Iciql.EnumType; import com.iciql.Iciql.IQColumn; import com.iciql.Iciql.IQEnum; import com.iciql.Iciql.IQIndex; import com.iciql.Iciql.IQTable;

@IQTable @IQIndexes({ @IQIndex({“productName”, “category”}), @IQIndex(name=“nameindex”, value=“productName”) }) public class Product {

@IQEnum(EnumType.ORDINAL)
public enum Availability {
    ACTIVE, DISCONTINUED;
}

@IQColumn(primaryKey = true)
public Integer productId;

@IQColumn(length = 200, trim = true)
public String productName;

@IQColumn(length = 50, trim = true)
public String category;

@IQColumn
public Double unitPrice;

@IQColumn(name = "units")
public Integer unitsInStock;

@IQColumn
private Integer reorderQuantity;

@IQColumn
private Availability availability;

public Product() {
    // default constructor
}

} %ENDCODE%

Interface Configuration (deprecated)

Alternatively, you may map your model classes using the original JaQu interface approach by implementing the com.iciql.Iciql interface.

This is a less verbose configuration style, but it comes at the expense of introducing a compile-time dependency on the logic of the iciql library. This might be a deterrent, for example, if you were serializing your model classes to another process that may not have the iciql library.

The com.iciql.Iciql interface specifies a single method, defineIQ(). In your implementation of defineIQ() you would use static method calls to set:

  • the table name (if it’s not the class name)
  • the column name (if it’s not the field name)
  • the max length of a string field
  • the primaryKey (single field or compound)
  • any indexes (single field or compound)

advantages

  • less verbose model class
  • compile-time index definitions
  • compile-time compound primary key definitions

disadvantages

  • only public fields of the model class are reflectively mapped as columns. all other scoped fields and inherited fields are ignored.
  • model runtime dependency on entire iciql library
  • defineIQ() is called from a static synchronized block which may be a bottleneck for highly concurrent systems

Example Interface Model

%BEGINCODE% import com.iciql.Iciql;

public class Product implements Iciql {

public Integer productId;
public String productName;
public String category;
public Double unitPrice;
public Integer unitsInStock;

// this field is ignored because it is not public
Integer reorderQuantity;

public Product() {
}

@Override
public void defineIQ() {
    com.iciql.Define.primaryKey(productId);
    com.iciql.Define.columnName(unitsInStock, "units");
    com.iciql.Define.length(productName, 200);
    com.iciql.Define.length(category, 50);
    com.iciql.Define.index(productName, category);
}

} %ENDCODE%