Intro to Doma 2

Hello, I'm kimchheng from System development Department. I have been working with gRPC Java application Development using Spring boot framework. I think there are various frameworks and Libraries for database access that compatible with Spring boot. And In this project we choose Doma framework For Database Access. For this article I would like to introduce what is Doma framework and its features.

What is DOMA?

Doma is a data access framework for java. It is a framework that is independent of another library. So it can be used with various framework such spring framework etc.

Doma have various features :

  1. Verifies and generates source code at compile time using annotation processing.
  2. Provides type-safe Criteria API.
  3. Supports Kotlin.
  4. Uses SQL templates, called “two-way SQL”.
  5. Has no dependence on other libraries.

https://doma.readthedocs.io/en/latest/

Setup

We have been using gradle automated building tool for our projects. Gradle provide more flexibility and high performance in building process.

Gradle

Add doma-core and doma-processor to gradle dependency with Doma version:

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
  // ...
    implementation("org.seasar.doma:doma-core:2.46.0")
    annotationProcessor("org.seasar.doma:doma-processor:2.46.0")
}

Folder Structure

Folder structure for Spring boot with Doma project is defined similarly to Spring boot that implement Dao pattern. With the addition of SQL queries file in resource that is corresponded to method in Dao.

Spring-boot with Doma example: https://github.com/domaframework/doma-spring-boot/tree/master/doma-spring-boot-samples

└── src
    └── main
        ├── java
        │   └── com
        │       └── example
        │           ├── dao  
        │           │   └── CustomerDao.java
        │           ├── entity
        │           │   └── Customer.java
        │           ├── repository
        │           │  └── CustomerRepository.java
        │           ├── service
        │           │  └── CustomerService.java
        │           └── Application.java
        └── resources
        │   └── META-INF
        │       └── com
        │           └── example
        │               └── dao
        │                   └── CustomerDao
        │                       └── selectById.sql
        └── application.properties

Entity

The entity class is the class that corresponded to the table in the database or result set of SQL query. It is defined with @Entity annotation. It represents a database relation (table or SQL result set). An instance of the class represents a row.

package com.example.entity;

import lombok.Data;
import org.seasar.doma.Column;
import org.seasar.doma.Entity;
import org.seasar.doma.GeneratedValue;
import org.seasar.doma.GenerationType;
import org.seasar.doma.Id;

@Data
@Entity
public class Customer{
  
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY) 
  @Column(name = "customer_id")
  private int customerId;

  @Column(name = "customer_name")
  private String customerName;
}

Dao

Dao is Data access object interface for database access. You can use it to perform CRUD operation to table in Database. It is defined with @Dao annotation.

There are various annotation on method that indicated different CRUD Operations. Such as

  • @Select
  • @Insert
  • @Update
  • @Delete
  • @BatchInsert
  • @BatchUpdate
  • @BatchDelete
package com.example.dao;

import com.example.enity.Customer;
import java.util.List;
import org.seasar.doma.Dao;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;

@ConfigAutowireable
@Dao
public interface CustomerDao {

  @Select
  List<Customer> selectById(String cutomerId);
}

SQL query is defined in META-INF/com/example/dao/CustomerDao/selectById.sql.

select
    *
from
    customer
where
    customer_id = /* cutomerId  */1

Service

Service layer hold the business logic and call methods in the repository layer or Dao layer.

package com.example.service;

import com.example.dao.CustomerDao;
import com.example.entity.Customer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class CustomerService {
    private final CustomerDao customerDao;

    public Customer getCustomerInfomation(int customerId) {
        return customerDao.selectById(customerId);
    }
}

SQL Template

SQL template or two-way SQL is feature of Doma that allow you to define SQL queries with /* */ comment block. There are 2 usages of SQL template :

  1. To build dynamic SQL statements from the templates.
  2. To execute the templates in SQL tools as they are.

SQL template is written in sql file that correspond to Dao method.

Example: SQL file META-INF/com/example/dao/CustomerDao/selectById.sql correlate with selectById method of CustomerDao.

You can perform various operations in /* */ comment block that also called directive. It helps to construct an extensive process in SQL query. These directive are

  • Bind variable directive
  • Literal variable directive
  • Embedded variable directive
  • Condition directive
  • Loop directive
  • Expansion directive
  • Population directive

SQL templates — Doma documentation

Expression Language

Expression language is feature of doma that allow you to write expression within SQL query. It allows you to perform various expression with Syntax similar to Java. But, not all Java syntax is executable. You can refer to official site more info "Expression language — Doma documentation".

You can perform expression with :

  • Comparison operators [==, !=, <, ...]
  • Logical operators [!, &&, ||]
  • Arithmetic operators [-, +, *, /, %]
  • String concatenation operator
  • Calling instance methods
  • Accessing to instance fields
  • Calling static methods
  • Accessing to static fields
  • Using built-in functions
  • Using custom functions

Example

Here are some examples of usage of Expression language in SQL query.

-- Comparison operators --
select
    *
from
    customer
where
    customer_id = /* cutomerId */1
    /*%if costomerName != null */
       customer_name = /* costomerName */'sam'
    /*%end*/
-- built-in functions --
select
    *
from
    customer
where
    customer_name like /* @prefix(costomerName) */'sam'

Conclusion

There are various features in Doma that I think it is very helpful in development of Java application. It can help us simplify the process and improve the speed of development. We can access the Database with a simple implementation.

There are more features of Doma that I would like to explore like Criteria API and Doma CodeGen. I hope to discuss and share more about those functions and features in the future article blog.