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