Overview

iciql is...

iciql is not...

fluent, type-safe SQL DSL with rich object mapping

Born from the unfinished JaQu subproject of H2 in August 2011, Iciql has advanced the codebase & DSL greatly. It supports more SQL syntax, more SQL data types, and all standard JDBC object types.

try (Db db = Db.open("jdbc:h2:mem:iciql")) {

    db.insertAll(Product.getList());
    Product p = new Product();
    List<Product> restock = db.from(p).where(p.unitsInStock).is(0).select();
    List<Product> all = db.executeQuery(Product.class, "select * from products");
    
}

dynamic, annotated DAO with standard crud operations

Inspired by JDBI, Iciql offers a similar DAO feature. There are some clear benefits to using SQL directly rather than SQL-through-a-DSL so use each one where it makes the mose sense.

// Define your DAO with SQL annotations and optional type adapters
public interface MyDao extends Dao {

    @SqlQuery("select * from Product where unitsInStock = 0")
    Product[] getProductsOutOfStock();

    @SqlQuery("select * from Product where productId = :id")
    Product getProduct(@Bind("id") long id);
 
    // retrieve a custom type from the matched row in the Invoices table
    @SqlQuery("select invoice from Invoices where id = :arg0")
    @InvoiceAdapter
    Invoice getInvoice(long id);

    // retrieve a custom type from the matched row in the Invoices table
    @SqlQuery("select invoice from Invoices where id = :p.invoiceId")
    @InvoiceAdapter
    Invoice getInvoice(@BindBean("p") Product product);

    // update a custom type for the matched row in the Invoices table
    @SqlStatement("update Invoices set invoice = :2 where id = :1")
    boolean updateInvoice(long id, @InvoiceAdapter Invoice invoice);

}

// Define a type adapter annotation for the Invoice object
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
@TypeAdapter(InvoiceAdapterImpl.class)
public @interface InvoiceAdapter { }

// Create a DAO instance with your Db and work more clearly
try (Db db = Db.open("jdbc:h2:mem:iciql")) {

    MyDao dao = db.open(MyDao.class);
    dao.insertAll(Product.getList());
    Product[] outofstock = dao.getProductsOutOfStock();
    Product p = dao.getProduct(1);
    Invoice i123 = dao.getInvoice(123);
    i123.approved = true;
    dao.updateInvoice(123, i123);
    
    // use the underlying Db instance for full-power
    dao.db().dropTable(Product.class);

}

flexible field data types

The Data Type Adapter feature allows you to customize how your SQL column data types map to/from Java objects.

This is very useful for mapping your field domain models to SQL without having to flatten them out to additional columns within your table. In other words, you can use your database as an object store at the column level by implementing a @TypeAdapter (de)serialization step.

You might use this to take advantage of the underlying database's type system. For example, PostgreSQL ships with the compelling JSON/JSONB/XML data types. Iciql provides String and Object adapters to facilitate use of those data types.

runtime mode support

Mode support allows you to tweak the behavior of your @TypeAdapter and DAO implementations to adapt to runtime conditions such as developing on a different database than you deploy on.

Supported Databases (Unit-Tested)

Support for others is possible and may only require creating a simple "dialect" class.

Java Runtime Requirement

iciql requires a Java 6 Runtime Environment (JRE) or a Java 6 Development Kit (JDK).

License

iciql is distributed under the terms of the Apache Software Foundation license, version 2.0