A Quick Start into Apache Cayenne

By Dassi Orleando, Alibaba Cloud Community Blog author.

Apache Cayenne is an open-source Java tool distributed under the Apache license. It provides such features as a powerful modeling utility, an object-relational mapping (ORM) for persistence operations and remote services.

In this article, you’ll be interacting with a MySQL database using Apache Cayenne’s object-relational mapping (ORM) feature from a small Java project build with Maven.

Setting up the Project

Maven is one of the most used tools for building Java applications. In this section, we’re going to set up our project dependencies (this being on the assumption that your system is empty).

As the first step, let’s add the following dependencies to add Apache Cayenne and MYSQL connector (specifically, the JDBC driver):

The modeler plugin should be defined into the pom.xml as well. It is a maven command used to start the Apache Cayenne Modeler plugin from the command line when you open the mapping file of the current project:

Generally speaking, the modeler is the preferred and recommended way for designing and setting up mappings between your database and the actual Java model classes.

It’s available for download from this page. You’ll probably need to download the version made for your specific OS or, alternatively, you can just use the cross-platform version (JAR) included as a Maven plugin-which should works just fine for your OS, too. The latest stable version at the time of writing this article is version 4.1. Note that this version requires Java 1.8 or later.

Next, as the next leg of this setup, let’s build your project with the mvn clean install command and launch the modeler GUI with the command mvn cayenne-modeler:run to get as output this screen:

The configurations are database dependent, because, even the JDBC driver will need to be changed if you’re using something other than MySQL. Here’s the full list along with corresponding drivers.

Mapping and Database Design

Let’s suppose you’ve got an existing database called cayenne_blog that showcases an one-to-many relationship between two tables, in which the following parameters are defined as so:

  • author: id (PK) and name
  • article: id (PK), title, content, and author_id (FK)

Now, consider the SQL commands referring to this example DB:

Just import the [db.sql](https://github.com/dassiorleando/apache-cayenne/blob/master/db.sql) file into your phpMyAdmin or, alternatively, this command from the MYSQL server in the terminal: mysql < db.sql.

Now let’s add another plugin, cayenne-maven-plugin, our modeler plugin configuration into pom.xml:

Here we specify where the ORM should save the data from (<data source>) and where it must save the mapping file (<map>). From this configuration, we can see that the database name is cayenne_blog, the user database credentials in use are root:root (make sure to update these to match the one of your MYSQL server) and the default package should be the one from your project structure (the package where the models classes are going to be created).

Finally, from the command line into our project we use cbimport command: mvn cayenne:cdbimport. Note that cdbimport synchronizes our XML map file with the existing database, we should get some logs looking like these:

Let’s generate the Java classes: mvn cayenne:cgen

Now, you should immediately see the changes into your project structure, your persistent objects should have been successfully generated into the package specified. Here, we’re talking about _Article.java and _Author.java (both files extend CayenneDataObject). The same configurations (XML format) can be seen as being put into the resources/blog.map.xml file.

Next, you’ll want to launch the modeler by typing the command mvn cayenne-modeler:run. From there, click New Project, then go to the next page where you'll want to specify the Data Domain Nam (blog) for your mapping file, which will be called cayenne-blog.xml. Now, you'll want to save it into the same folder of the map file that we generated up here.

Then click File > Import Datamap to access the UI allowing use to link it to the datamap.

Once the cayenne-blog.xml and blog.map.xml are both linked, you can also update your model from the modeler for the changes to get applied into our classes. Here's how it will look like:

Apache Cayenne supports three kind of primary key strategies, which are:

  • Cayenne-Generated: it manages the PK generation
  • Database-Generated: the PK is managed by the database engine
  • Custom Sequence: a custom logic needs to be implemented here

In the following screenshot, the author table has an id which is an auto-incremented Integer managed by the database:

Note: Make sure that you create a DataNode with our exact database configurations as illustrated in the following image:

Into the resources directory of our Maven project, you'll now have a special XML file called cayenne-blog with the following content:

XMLPoolingDataSourceFactory is responsible for loading JDBC connection information from an XML resource associated to the DataNodeDescriptor.

Mapping Structure

Apache Cayenne has its own syntax to describe the models, here are the available tags:

  • DataNode(<node>): the database's model. It contains all information necessary to get connected to a database, such as the name of the database, the driver and the database user credentials.
  • DataMap(<data-map>): It's a container of persistent entities with their relations.
  • DbAttribute(<db-attribute>): represents a column in a database table.
  • DbEntity(<db-entity>): the model of a single database table or view. It can have DbAttributes and relationships.
  • ObjEntity(<obj-entity>): the model of a single persistent java class, which is made of ObjAttributes that correspond to entity class properties and ObjRelationships that are properties that have a type of another entity.
  • Embeddable(<embeddable>): the model of a Java class that acts as a property of an ObjEntity, but it corresponds to multiple columns in the database.
  • Procedure(<procedure>): to register stored procedure in the database.
  • Query(<query>): the model of a query, which is used to mapped query in configuration file without forget that we can also do it in the code.

You can read this following guide for more information.

Applying CRUD on Models

In this section you’ll be applying some basic operations on our models (Article and Author). ObjectSelect class has some statics methods useful to query our database but for the insertions and updates we should use the server's context(ObjectContext) which is used to commit the changes.

Here’s how to get the server context relative to our project:

Note: cayenne-blog.xml file is located into the project resources folder.

Creating an Object

You can create an object with the following query:

Reading an Object

You can read an object with the following query:

Finding all Records of a Class

It’s possible to query all the authors saved so far by using the following query:

Updating an Object

You can update an object with the following query:

Attach Relationship to an Object

Here’s how we can link an author with an article he wrote:

Deleting an Object

You can delete an object with the following query:

Deleting all records of a Class

Apache Cayenne’s API allows us to drop all the records of a table using SQLTemplate, here we just provide the basic SQL delete query along with the target class:

Expression and ExpressionFactory

There are many possibilities for building advanced queries with Apache Cayenne. But, most of the time we’re using Expression and ExpressionFactory classes, here are some examples of these:

  • likeExp: used for building the LIKE expression.
  • likeIgnoreCaseExp: used to build the LIKE_IGNORE_CASE expression.
  • containsExp: an expression used for a LIKE query with the pattern matching anywhere in the string.
  • containsIgnoreCaseExp: similar to the containsExp but uses a case-insensitive approach.
  • startsWithExp: the pattern should match the beginning of the string.
  • startsWithIgnoreCaseExp: similar to the startsWithExp but it uses a case-insensitive approach.
  • endsWithExp: an expression that matches the end of a string.
  • endsWithIgnoreCaseExp: an expression that matches the end of a string that uses a case-insensitive approach.
  • expTrue: used for boolean true expressions.
  • expFalse: used for boolean false expressions.
  • andExp: used to chain two expressions with the and operator.
  • orExp: to chain two expressions using the or operator.

Conclusion

In this tutorial, you’ve learned how to setup Apache Cayenne’s object-relational mapping (ORM) feature for a MySQL database along with some basic CRUD operations as query examples with an one-to-many relationship. The full source code for this article can be found on Github.

Original Source

Follow me to keep abreast with the latest technology news, industry insights, and developer trends.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store