Active Record query interface

Why static methods are used

An ActiveRecord instance represents a particular row in a database table. Thus to specify methods which operate on the whole table, it makes sense to use class-level methods which are static methods in a Java class.

TypeDBJavaExample
static
methods
table Class
//retrieve all posts
List posts = Post.findAll();

//retrieve 10 posts containing word Java
List posts = Post.where("content like '%Java%'").limit(10).getRecords();
instance
methods
row instance
//reload a record: sync memory data with database data
post.reload();

//save a record: store memory data to database
post.save();

Chainable query methods

Scooter provides the following chainable query interface methods.

  • where(): specifies where clause in the SQL query
  • groupBy(): specifies group-by clause in the SQL query
  • having(): specifies having clause in the SQL query
  • orderBy(): specifies order-by clause in the SQL query
  • limit(): specifies number of records for each retrieval
  • offset(): specifies number of records to skip in a retrieval
  • page(): specifies the starting page in a pagination
  • includes(): specifies models to eager loaded. See below for more details.

Record retrieval methods

The following two methods stop the chain and fire query constructed to the database.

  • public List getRecords(): returns a list of records.
  • public ActiveRecord getRecord(): returns a specific record.

Notice that plural form of the method is used to return a list of result.

Examples

In the following example, we are going to use the Pet Clinic application as an example. We assume that we are going to use MySQL database.

The Pet Clinic application has the following models:

  • Owner
  • Pet
  • Visit
  • Type
  • Vet
  • Specialty

See the Pet Clinic application page for model details.

Here are some examples. Please notice that the singular form getRecord() returns an ActiveRecord instance, while the plural form getRecords() returns a list of ActiveRecord instances. This is what we have called Convention Over Configuration.

To retrieve a pet named Leo:

ActiveRecord Leo = Pet.where("name='Leo'").getRecord();

The SQL equivalent of the above is:

SELECT * FROM pets WHERE name = 'Leo'

To retrieve a list of pets with a limit of 3 records per page:

List pets = Pet.limit(3).getRecords();

The SQL equivalent of the above is:

SELECT * FROM pets LIMIT 3

To retrieve a list of pets with a limit of 3 records per page and skips the first 5 records:

List pets = Pet.limit(3).offset(5).getRecords();

The SQL equivalent of the above is:

SELECT * FROM pets LIMIT 3 OFFSET 5

To retrieve a list of pets with a limit of 3 records per page and skips the first 5 records and order the result by pet name:

List pets = Pet.limit(3).offset(5).orderBy("name").getRecords();

The SQL equivalent of the above is:

SELECT * FROM pets LIMIT 3 OFFSET 5 ORDER BY name

To retrieve all pets owned by owners with id 6 and 10, order by latest birth date:

List pets = Pet.where("owner_id IN (6, 10)").orderBy("birth_date DESC").getRecords();

The SQL equivalent of the above is:

SELECT * FROM pets WHERE owner_id IN (6, 10) ORDER BY birth_date DESC

To retrieve a pet owner along with all the pets he/she has and each pet's type in one query (eager loading):

ActiveRecord owner6 = Owner.where("owners.id=6").includes("pets=>visits, pets=>type").getRecord();

The SQL equivalent of the above is:

SELECT OWNERS.ID AS OWNERS_ID, OWNERS.FIRST_NAME AS OWNERS_FIRST_NAME,
    OWNERS.LAST_NAME AS OWNERS_LAST_NAME, OWNERS.ADDRESS AS OWNERS_ADDRESS,
    OWNERS.CITY AS OWNERS_CITY, OWNERS.TELEPHONE AS OWNERS_TELEPHONE,
    PETS.ID AS PETS_ID, PETS.NAME AS PETS_NAME, PETS.BIRTH_DATE AS PETS_BIRTH_DATE,
    PETS.TYPE_ID AS PETS_TYPE_ID, PETS.OWNER_ID AS PETS_OWNER_ID,
    VISITS.ID AS VISITS_ID, VISITS.PET_ID AS VISITS_PET_ID,
    VISITS.VISIT_DATE AS VISITS_VISIT_DATE, VISITS.DESCRIPTION AS VISITS_DESCRIPTION,
    OWNERS_PETS.ID AS OWNERS_PETS_ID, OWNERS_PETS.NAME AS OWNERS_PETS_NAME,
    OWNERS_PETS.BIRTH_DATE AS OWNERS_PETS_BIRTH_DATE,
    OWNERS_PETS.TYPE_ID AS OWNERS_PETS_TYPE_ID,
    OWNERS_PETS.OWNER_ID AS OWNERS_PETS_OWNER_ID,
    TYPES.ID AS TYPES_ID, TYPES.NAME AS TYPES_NAME
FROM OWNERS LEFT OUTER JOIN PETS ON OWNERS.ID=PETS.OWNER_ID
            LEFT OUTER JOIN VISITS ON PETS.ID=VISITS.PET_ID
            LEFT OUTER JOIN PETS OWNERS_PETS ON OWNERS.ID=OWNERS_PETS.OWNER_ID
            LEFT OUTER JOIN TYPES ON OWNERS_PETS.TYPE_ID=TYPES.ID
WHERE OWNERS.ID = 6