POJO s generated by jOOQ are generated for fields in a single table.In Association queries, we usually store data from multiple tables in one class.In this case, we can create our own class to add the multitable field member variables we need
Creating classes manually is cumbersome for this common situation. We can create a blank class that inherits the original POJO while generating POJO. When we need to add fields, we can add other table fields directly to the class we generate.
To do this, we still need to customize the code generator and add the creation code logic for these inherited classes, which we call Entity first.Through previous requirement analysis, these codes need to be modified by us after they are created, so they can only be generated once and cannot be overwritten or deleted by the Code Generator when the file exists.
All generated Entities need to be placed in parent packages parallel to the target packages of the jOOQ configuration.This way, when jOOQ empties the package contents of the specified directory before generating code, our own packages will not be affected.And in the generation logic, you need to determine if the target Entity file already exists and ignore it if it exists
With these logic, when we add member variables of related tables to Entity, they are not overwritten or deleted by the code generator of jOQ.It's safe to add code and implement the logic we want
Entity Generation
An initial Entity is simple, just 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 CustomJavaGenerator
First override the parent's generatePojo method, after generating the original POJO, call the custom generateEntity method to create the Entity
@Override protected void generatePojo(TableDefinition table) { super.generatePojo(table); // Generate Entity after POJO generation generateEntity(table); }
Specific implementation of generateEntity You can view the CustomJavaGenerator file's Source code , relatively simple, because it's just a splice of strings
After Entity is created, we also need to adjust the generated DAO by replacing the POJO class in the original generic with the Entity class by replacing the string, as you can see in the generateDao method in the source code
After adjustment, taking the s1_user table as an example, the resulting DAO is as follows, replacing the type of target POJO within the generic and 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); } // ... }
By doing so, all our DAO methods return values that are our custom Entity class for easy expansion
For example, if we need to query the s2_user_message table Association s1_user to find out the user name of the user to which the user message belongs, we can add a field directly to the Entity S2UserMessage we generated, and then in the query, we can
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 for this chapter: https://github.com/k55k32/learn-jooq/tree/master/section-10
This chapter is short, mainly tells you that you can do some other extensions through the custom code generator.By using the characteristics of the code generator, you can generate arbitrary code quickly and easily, which is convenient and universal.If it's in a company project, these can be pulled out individually to be referenced by each service as an extension package.Generating the underlying project framework through the generator is not only more efficient than creating it manually, but also less prone to errors and a good code structure