Consideration on Java Persistence Framework 2017 (2) Doma2

Previous post

-Discussion on Java Persistence Framework for 2017 (1)

Preface

Since I am writing using the gap time, I would appreciate it if you could point out any parts with poor accuracy. First, exclude those that are EOL. We will consider paid functions, but we will not actually use them, due to the problem of pockets. The DB used is fixed to Postgre for a stupid reason such as "Well, maybe Postgre can be used even if it is not specified."

environment

Table structure

table_1.png

Correspondence range

ORM Transaction Data Model DSL
× ×

○: Correspondence ×: Not supported

Impressions

  1. Annotation is strong
  2. Image that requires a lot of knowledge when going deep, I want to use it with a structure that hangs multiple developers for one Doma2 expert
  3. A style that spoils everything before execution, annotation processing is strong
  4. Since SQL is externalized, it is possible to test and acquire execution plans for individual SQL.

sample

Single table search

Primary key search

SelectByIdTest.java


EmployeeDao dao = new EmployeeDaoImpl();
AppConfig.singleton().getTransactionManager().required(() -> {
    Employee e1 = dao.selectById(BigDecimal.ZERO);
});

Stream search

SelectByFirstNameAsStreamTest.java


EmployeeDao dao = new EmployeeDaoImpl();
AppConfig.singleton().getTransactionManager().required(() -> {
    // EmployeeDao#selectByFirstNameAsStream(String)Is a manually added signature
    Employee e1 = dao.selectByFirstNameAsStream("John");
});

EmployeeDao.java


//Argument names and parameters used in the SQL file must have the same name
@Select
Stream<Employee> selectByFirstNameAsStream(String first_name);

META-INF/~/EmployeeDao/selectByFirstNameAsStream.sql


select
  /*%expand*/*
from
  employee
where
  first_name = /* first_name */1

Callback style

SelectByFirstNameForCountTest.java


EmployeeDao dao = new EmployeeDaoImpl();
AppConfig.singleton().getTransactionManager().required(() -> {
    System.out.println(
        // EmployeeDao#selectByFirstNameForCount(String, Function<Stream<Employee>, AtomicInteger>)Is a manually added signature
        dao.selectByFirstNameForCount(
            "Taro",
            e -> new AtomicInteger((int)e.count())));
});

EmployeeDao.java


//I didn't think it wouldn't accept IntFunction
@Select(strategy = SelectType.STREAM)
AtomicInteger selectByFirstNameForCount(String first_name, Function<Stream<Employee>, AtomicInteger> mapper);

META-INF/~/EmployeeDao/selectByFirstNameForCountTest.sql


select
  /*%expand*/*
from
  employee
where
  first_name = /* first_name */1

Table join

EmployeeWithPost.java


@Entity(naming = NamingType.SNAKE_LOWER_CASE)
public class EmployeeWithPost {
    /** */
    @Id
    @Column(name = "id")
    BigDecimal id;

    /** */
    @Column(name = "first_name")
    String firstName;

    /** */
    @Column(name = "middle_name")
    String middleName;

    /** */
    @Column(name = "last_name")
    String lastName;

    /** */
    @Id
    @Column(name = "post_id")
    BigDecimal postId;

    /** */
    @Column(name = "name")
    String name;

    public void setId(BigDecimal id) {
        this.id = id;
    }

    public BigDecimal getId() {
        return this.id;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setMiddleName(String middleName) {
        this.middleName = middleName;
    }

    public String getMiddleName() {
        return this.middleName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setPostId(BigDecimal postId) {
        this.postId = postId;
    }

    public BigDecimal getPostId() {
        return this.postId;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    public String toString() {
        return "EmployeeWithPost["
                + this.id
                + ":"
                + this.firstName.trim()
                + "/"
                + this.middleName.trim()
                + "/"
                + this.lastName.trim()
                + " "
                + this.postId
                + "-"
                + this.name.trim()
                + "]";
    }
}

EmployeeWithPostDao.java


@Dao(config = ORMConfig.class)
public interface EmployeeWithPostDao {
    @Select
    public List<EmployeeWithPost> selectByEmployeeId(BigDecimal employeeId);
}

META-INF/(package name)/EmployeeWithPostDao/selectByEmployeeId.sql


select
  employee.id AS id,
  employee.first_name AS first_name,
  employee.middle_name AS middle_name,
  employee.last_name AS last_name,
  post.id AS post_id,
  post.name AS name
from
  employee
  INNER JOIN
    post
  ON
    post.employee_id = employee.id
where
  employee_id = /* employeeId */1

The point

  1. Coverage is ORM + DB access library + transaction (partial) --Transactions only support local transactions --If you want to use global transactions, you need to install the JTA implementation library.
  2. Annotation processing reveals SQL and DAO mapping deficiencies at compile time --Although you can use your own expression language for SQL, its validation is also done at compile time.
  3. With automatic generation of Entity --Primary key search is automatically generated for SQL files
  4. When storing the table join result, create your own as a custom Entity --Similarly, DAO is also created by yourself, but DAO is Interface, and the implementation class is automatically generated from the linked SQL file.
  5. DAO and SQL mapping is based on the naming convention of method name → file name 1: 1.
  6. There is a cache for search results, and the lifetime is in transaction
  7. Search results can be returned as java.util.stream.Stream --Note that you need to be careful about the life cycle when passing java.util.stream.Stream ――However, Doma2 gives a warning about that point.

Addictive points

  1. Suddenly ignore the sample and die safely without getting the class from the source source
  2. AppConfig (* config class) also ignores the sample, a difference appears in the generated code and it dies safely --The behavior of the automatically generated DaoImpl argumentless constructor differs depending on the presence or absence of @ Singleton.
  3. If there is @ Singleton, use the instance obtained by ʻAppConfig.singleton ()`
  4. If there is no @Singleton, use the instance obtained bynew AppConfig () --Sample is with @ Singleton, created is without @ Singleton, test code is as sample, result did not work --The reason why it didn't work is because TransactionManager is managed in AppConfig.
  5. If you use the test code with @ Singleton with the code without @ Singleton, DAO and AppConfig will be separate transactions from the above specifications.
  6. Doma2 manages transactions within TransactionManager methods
  7. Transactions from DAO and AppConfig occur
  8. Trying to operate a DAO transaction within an AppConfig transaction
  9. Death
  10. Create a "META-INF / (package name)" structure directly under the source directory and place the SQL file. --Some projects and companies may not be able to use it with aggregation tools --Unconfirmed whether the placement destination can be changed

After post

-Guessing about the 2017 Java Persistence Framework (3) Reladomo -Discussion on Java Persistence Framework for 2017 (4) jOOQ

Reference article

-10 things you value in the development of Doma

Recommended Posts

Consideration on Java Persistence Framework 2017 (2) Doma2
Consideration on Java Persistence Framework 2017 (Summary) -1
Consideration on Java Persistence Framework 2017 (6) Ebean
Consideration on Java Persistence Framework 2017 (5) Iciql
Consideration on the 2017 Java Persistence Framework (1)
Consideration on Java Persistence Framework 2017 (8) Hibernate5
java framework
Guess about the 2017 Java Persistence Framework (3) Reladomo
Java framework comparison
[Java] Collection framework
Play Framework2.5 (Java) Tips
Let's touch on Java
[Java] SpringBoot + Doma2 + H2
[Development] Java framework comparison
Learning Java framework # 1 (Mac version)
Java version control on macOS
Install OpenJDK7 (JAVA) on ubuntu 14.04
Downgrade Java on openSUSE Linux
Reflection on Java string manipulation
On passing Java Gold SE 8
Oracle Java 8 on Docker Ubuntu
Java Collections Framework Review Notes
Install Java on WSL Ubuntu 18.04
Run java applet on ubuntu
Put Oracle Java 8 on CircleCI 2
Java version change on CentOS
Install java 1.8.0 on Amazon linux2