DtoQuery

DtoQuery is where we use SQL and map it into plain beans. These plain beans are just ordinary beans with public constructor(s) and public getters/setters.

public static class CustomerDto {

  Integer id;
  String name;

  ... // getters & setters
}
// using positioned parameters

List<CustomerDto> beans =
  ebeanServer.findDto(CustomerDto.class, "select id, name from customer where name = ?")
  .setParameter(1, "Rob")
  .findList();
// using named parameters

List<CustomerDto> beans =
  ebeanServer.findDto(CustomerDto.class, "select id, name from customer where name = :name")
  .setParameter("name", "Rob")
  .findList();

Mapping

When mapping the SQL resultSet to the DTO beans the following is used.

  • Firstly we look for a constructor with the same number of arguments as columns in the resultSet. If we have such a constructor we use it for mapping (assuming the correct types).
  • Secondly see if there are more columns in the resultSet than our largest constructor. If so we the largest constructor to read the first columns and then look to use setter methods to map the renaming columns.
  • Finally we use the default constructor and setter methods.

Note that we perform the mapping using MethodHandles rather than reflection. That does mean it expects the Constructor and Setter methods to have public access.

firstRow / maxRows

We can apply firstRows/maxRows to the sql query.

String sql = "select id, name from customer where name like ?";

List<CustomerDto> robs = server().findDto(CustomerDto.class, sql)
  .setParameter(1, "Rob%")
  .setMaxRows(10)
  .findList();

The appropriate sql will be added to apply firstRows/maxRows for the database platform.

select id, name from o_customer where name like ?
limit 10

RelaxedMode

By default when performing the mapping, if we are not able to map a column to a property (setter method) then an exception is thrown.

Instead we can set relaxed mode on the query via query.setRelaxedMode() and that means it will effectively ignore/skip any column that it can't map.

This is expected to be useful when there is potentially a large existing query and there is a desire to only map some of the columns into bean properties.

findEach

We use findEach when processing a large query where we do not wish to hold all the beans in a list but instead process them one at a time.

String sql = "select id, name from o_customer where id > :id order by id desc";

ebeanServer.findDto(CustomerDto.class, sql)
  .setParameter("id", 0)
  .findEach(customer -> {

    log.debug("got " + customer.getId() + " " + customer.getName());
    ...

  });

Edit Page