Daobab ORM



Tables and Columns

The main Daobab ORM idea is: every column, identified by name and value type, has own interface.

public interface CustomerId extends ColumnRelationMap {


    default BigDecimal getCustomerId(){return getColumnParam("customerId");}
    default E setCustomerId(BigDecimal val){setColumnParam("customerId",val); return (E)this;}

    default Column<E,BigDecimal,CustomerId> colCustomerId(){
        return new Column<>() {

            @Override
            public String getColumnName() {
                return "customer_id";
            }

            @Override
            public E getThisEntity(){
                return getEntity();
            }

            @Override
            public Class<BigDecimal> getColumnClass(){
                return  BigDecimal.class;
            }

            @Override
            public BigDecimal getColumnValue(CustomerId entity){
                return  entity.getCustomerId();
            }

            @Override
            public void setColumnValue(CustomerId entity, BigDecimal param){
                entity.setCustomerId(param);
            }
        };
    }

}

Interface collects informations like column name and value type. Provides also getter and setter for the value.

By implementing interfaces into entities, Daobab collects the complete informations about tables, columns, value types, and relations between tables.

public class Customer extends Table implements
	CustomerId<Customer>,
	Name<Customer>,
	PrimaryKey<Customer,BigDecimal,CustomerId>{

	@Override
	public String getEntityName() {
		return "CUSTOMER";
	}

	@Override
    public List<Column<?,?,?>> columns() {
        return Arrays.asList(
		colCustomerId(),
		colName()
		);
	}

	@Override
	public Column<Customer,BigDecimal,CustomerId> colID() {
		return colCustomerId();
	}

}

Every table implements as many interfaces as many column has.

Table name information, provided in dedicated method.

Optional PrimaryKey information, is delivered by another interface.

Table each parameter has getter and setter, however instead of fields, entity has map, and everything is stored backgroundly into this map.

PK gneration key process, described into annotation.

So that Daobab collects the complete of informations about tables, column, value types, keys and by inheritance of common interfaces - relations between tables.

Targets

Daobab can execute queries not only on the specific database, but also into memory or remotelly(near future).

Table isn't related to one specific database.

So that, for every operation you need to point out the target.

As mentionned before, it can be datasource, but not necessairly. It's only an abstract destination to the query

So that Daobab is able to execute query anywhere - just provide a connection.

SELECT name FROM pizza where name like '%PEPPERONI%';

JPA? Unfortunatelly won't help us...we need to write String command like this:

SELECT name FROM pizza where name like '%PEPPERONI%';

... and hide it into a few-line method:

public List<String> findPepperoni();


JPA Pitfalls:

  • incorect references - type "nsme" instead of "name" and IDE won't detect it as an error.
  • problematic refactoring - find all references and fix it one by one. IDE will not help you with this.
  • object type problem - you don't really know what type has column name. IDE won't detect an error, when column type is changed from VARCHAR to NUMBER.
  • Logic hidden into public method - method body modification is dangerous to other parts of code using it. Is the method name tell us about 'like' inside?
  • code duplications - many similar "find*" methods for many similar cases... in one place
  • strong links between entities - JPA assumes strong, hard to understand, annotation based relatons between Entities. And here is a problem when you don't need it every time... or when you don't need always lazy loading... isn't?



  • How about Daobab?

    Daobab is JPA extension library, fully compatibile with any JPA engine.

    Daobab query is a single line of code. Instantly, we see what's about:

    List<String> list=
    Select.fieldList(dao.colName()).where(dao.colName(),Operator.LIKE,"%Pepperoni%").result();

    Daobab benefits:

  • Queries visibled as a Java code.
  • Safe for modifications
  • Safe parameter types.
  • Safe return types.
  • Easy refactoring both Java code and dataBase schema.
  • Enties trully reflects.
  • Easy relations between tables.
  • Smart joins.

  • Deeper Daobab usage brings more benefits:

  • Trully ORM (no IDs)
  • Deadly fast queries over in-memory buffers.
  • Much faster relations between entities
  • Easy projections
  • faster lazy-loading