Active Record CRUD Made Easy

CRUD methods

CRUD is an abbreviation of four common operations of data acess: create, read, update and delete. CRUD is easy with Scooter Framework's ActiveRecord.

Create

Create a record in database:

ActiveRecord post = Post.newRecord();
post.setData("title", "Happy Java Programming");
post.setData("body", "Java programming is fun.");
post.create();

The above code snippet is equivalent to the following sql statement:

INSERT INTO posts (title, body) VALUES ('Happy Java Programming', 'Java programming is fun.');

It will create a new record in a posts table.

Read

For a single ActiveRecord instance, it can refresh itself with the latest data in database:

ActiveRecord post = ...;
post.reload();

The last line above is equivalent to the following sql statement, assuming 8 is the primary key value of the record:

SELECT * FROM posts WHERE id = 8;

More READ examples:

//read in all records
List posts = Post.findAll();

//read in all records with a condition
List posts3 = Post.where("id in (100, 101, 102)").getRecords();

//read in all records by SQL query
List posts = Post.findAllBySQL("SELECT * FROM posts");

//find the record with its id, assuming id is a column in the posts table
ActiveRecord post100 = Post.findById(100);

//find the record with its primary key regardless the primary-key column name (id or postid or abc)
ActiveRecord post100 = Post.findByPK("100");

//find the record with its primary key assuming comments table has a composite primary key
ActiveRecord comment12OfPost100 = Comment.findByPK("100-12");

Update

Update a record in database:

ActiveRecord post = Post.where("title='Happy Java Programming'").getRecord();
post.setData("title", "Scooter Rocks!");
post.update();

The last line above is equivalent to the following sql statement:

UPDATE posts SET title='Happy Java Programming',
                 body='Java programming is fun.'
WHERE id=8;

It will update the title of the record with id 8--assuming 8 is the value of the primary key, in the posts table.

The update() method will list all columns of the posts table in the update statement. Since we only edited the title column, we can use updateChanged():

ActiveRecord post = Post.where("title='Happy Java Programming'").getRecord();
post.setData("title", "Scooter Rocks!");
post.updateChanged();

The last line above is equivalent to the following sql statement which uses only those columns whose data are changed:

UPDATE posts SET title='Happy Java Programming'
WHERE id=8;

Scooter Framework's ActiveRecord is smart enough to track which fields are changed and only use those fields in the update sql statement.

Delete

Delete a record in database:

ActiveRecord post100 = Post.deleteById(100);

The last line above is equivalent to the following sql statement:

DELETE FROM posts WHERE id=8;

Delete a record in database gracefully:

ActiveRecord post100 = Post.findById(100);
post.delete();

Unlike using deleteById, the delete() method here may cascade the deletion to its associated comments if cascade is specified in the relation between post and comment models.

The last line above is equivalent to the following sql statements:

DELETE FROM posts WHERE id=8;
DELETE FROM comments WHERE post_id=8;

More convenience methods

Retrieve meta info

//all columns
List<ColumnInfo> columns = Post.columns();

//all column names
List<String> columnNames = Post.columnNames();

//primary key column names
List<String> pkNames = Post.primaryKeyNames();

//readonly column names
List<String> rNames = Post.readOnlyColumnNames();

//rowInfo
RowInfo rowInfo = Post.rowInfo();

//table name
String table = Post.tableName();

Calculation

//count all records
long result = Post.count();

//find the average value of a column
Object result = Post.average("salary");

//find the max value of a column
Object result = Post.maximum("salary");

//find the min value of a column
Object result = Post.minimum("salary");

//find the sum of a column
Object result = Post.sum("salary");

Dynamic Retrieval

You can simulate Ruby On Rails' dynamic finder by using ActiveRecord's findFirstBy(), findLastBy() and findAllBy() methods.

//The class
class Employee extends ActiveRecord {}

//retrieve the employee whose first name is John, last name is Doe
ActiveRecord john = Employee.findFirstBy("firstName_and_lastName", {"John", "Doe"});

//retrieve the employee whose first name is John, last name is Doe and age is 29.
ActiveRecord john = Employee.findFirstBy("firstName_and_lastName_and_age", {"John", "Doe", new Integer(29)});

//retrieve all employees who live in LA
List employees = Employee.findAllBy("city", {"LA"});

More on ActiveRecord

Specifying table name directly

You can set the corresponding table name of an ActiveRecord class directly as follows:

public class Post extends ActiveRecord {
    public String getTableName() {
        return "entries";
    }
}

Enforcing a specific database

You can set the corresponding db connection name of an ActiveRecord class directly as follows:

public class Post extends ActiveRecord {
    public String getConnectionName() {
        return "blog_development";
    }
}

All posts records are now associated with the database connection named blog_development which is defined in the WEB-INF/config/database.properties file.

Using non-database fields

ActiveRecord implicitly pulls fields of a model from database. Therefore, you do not need to list database table fields in the class. However, what if you want to have some non-database fields in the model only? This kind of fields is called extraField in ActiveRecord. You can deal with them as follows:

public class User extends ActiveRecord {
    protected void declaresExtraFields() {
        //declare two extra fields
        setExtraFields("nickName, formerName");
    }
}

//Then you can use them as you use any other fields
ActiveRecord david = new User();
david.setData("nickName", "Dave");
System.out.println(david.getField("nickName"));

The values of this kind of fields are transient which means that they are lost once the reference to the object is gone.

Using protected fields

Protected fields are those table columns that you do not want users to change in an application. They can only be changed through database tools. For example, you may declare username and password as protected fields. Once they are entered in database, you would not allow users to change them.

public class User extends ActiveRecord {
    protected void declaresProtectedFields() {
        //declare two protected fields
        setProtectedFields("username, password");
    }
}

//Then operations like clearAndSetData() and setData() will have no effects on
//the protected fields
ActiveRecord david = new User();
david.setData("username", "IJustChangedYou");
System.out.println(david.getField("username"));//should still print out unchanged database record.