10, The extension of POJO

Keywords: Programming Java github

Complete tutorial: https://jooq.diamondfsd.com/

POJO s generated by jOOQ are generated for fields of a single table. In association queries, we usually store the data of multiple tables in one class. In this case, we can create a class by ourselves to add the multi table field member variables we need

For this kind of common situation, it is very tedious to create a class manually. We can create a blank class that inherits the original POJO while generating POJO. When we need to add fields, we can directly add other table fields on the generated class

To achieve the above effect, we still need to customize the code generator and add the creation code logic for these inherited classes (called Entity first here). According to the previous requirement analysis, these codes need to be modified by ourselves after creation, so they can only be generated once. When the files exist, they cannot be overwritten or deleted by the code generator

All generated entities need to be placed in the target package parallel parent package configured by jOOQ. In this way, when jOOQ empties the package contents of the specified directory before generating code, our own package will not be affected. In the generation logic, it is necessary to determine whether the target Entity file already exists, and if so, ignore it

Through these logic, when we add the member variables of the associated table for the Entity, they will not be overwritten or deleted by the code generator of jOOQ. We can safely add code and implement the logic we want

Entity generation

An initial Entity is very simple. You only need to inherit the POJO generated by jOOQ

package com.diamondfsd.jooq.learn.entity;

import com.diamondfsd.jooq.learn.jooq.tables.pojos.S1UserPojo;

public class S1User extends S1UserPojo {

}

To achieve this, I added the following to the custom code generator, the custom Java generator

First, the parent's generatePojo method is overridden. After generating the original POJO, the user-defined generateEntity method is called to create the Entity

@Override
protected void generatePojo(TableDefinition table) {
    super.generatePojo(table);
    // After generating POJO, generate Entity
    generateEntity(table);
}

For the specific implementation content of generateEntity, you can view the Source code , which is relatively simple, because it's just string splicing

After the creation of Entity, we also need to adjust the generated DAO, replacing the POJO class in the original generic with the Entity class through the replacement string. For details, you can see in the generateDao method in the source code

After adjustment, take the S1 ﹣ user table as an example, the final DAO content generated is as follows, replacing the type of the generic and the target POJO in the constructor

// ...
import com.diamondfsd.jooq.learn.entity.S1User;
// ...

@Repository
public class S1UserDao extends ExtendDAOImpl<S1UserRecord, S1User, Integer> { 
    public S1UserDao() {
        super(TS1User.S1_USER, S1User.class);
    }

    @Autowired
    public S1UserDao(Configuration configuration) {
        super(TS1User.S1_USER, S1User.class, configuration);
    }
    // ...
}

After this operation, the return values of all our DAO methods are all our custom Entity classes, which is convenient for extension

For example, we need to query the S2 user message table Association S1 user to find out the user name of the user whose message belongs to. You can directly add fields to the Entity S2UserMessage we generated, and then, when querying, enter to this class

public class S2UserMessage extends S2UserMessagePojo {
    String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}
@Test
void leftJoinUsernameTest() {
    List<S2UserMessage> userMessageList = userMessageDao.create()
       .select(S2_USER_MESSAGE.ID, S2_USER_MESSAGE.MESSAGE_TITLE, S1_USER.USERNAME)
       .from(S2_USER_MESSAGE)
       .leftJoin(S1_USER).on(S1_USER.ID.eq(S2_USER_MESSAGE.USER_ID))
       .fetchInto(S2UserMessage.class);

    assertTrue(userMessageList.size() > 0);
    List<String> usernameList = userMessageList.stream()
            .map(S2UserMessage::getUsername)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
    assertEquals(userMessageList.size(), usernameList.size());
}

Content summary

Source code of this chapter: https://github.com/k55k32/learn-jooq/tree/master/section-10

This chapter is relatively short, mainly to tell you that you can do some other expansion operations through the custom code generator. Using the characteristics of code generator, it is convenient and general to generate arbitrary code. If it is in the company's project, these can be separated as an extension package for each service to reference. The basic project framework generated by generator is not only more efficient than manual creation, but also not easy to make mistakes, and it can also have a good code structure

Posted by tripc1 on Wed, 26 Feb 2020 03:36:25 -0800