Skip to content

How to Define Entities and Mappers in MyBatis-Flex: Annotations and BaseMapper Explained

I was setting up a new project with MyBatis-Flex and needed to create entity classes and mapper interfaces. Coming from MyBatis-Plus, I expected a similar pattern but wanted to understand the exact annotations and conventions MyBatis-Flex uses.

The Problem: Mapping Java Classes to Database Tables

I had a simple tb_account table in my database and needed to create a Java entity that maps to it. The table had columns like id, user_name, and created_at. The challenge was figuring out which annotations to use and when they’re actually necessary.

Defining the Entity Class

Here’s how I defined my Account entity:

Account.java
package com.example.entity;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.util.Date;
@Table("tb_account")
public class Account {
@Id(keyType = KeyType.Auto)
private Long id;
@Column("user_name")
private String userName;
private Integer age;
private String email;
@Column("created_at")
private Date createdAt;
// Getters and setters omitted for brevity
}

The @Table("tb_account") annotation binds this class to the database table. Without it, MyBatis-Flex would default to using the class name (lowercase) as the table name.

For the primary key, @Id(keyType = KeyType.Auto) tells MyBatis-Flex that id is auto-incremented. Other options include KeyType.UUID and KeyType.Sequence depending on your database strategy.

The @Column annotation is only needed when the Java field name doesn’t match the database column name. My userName field maps to user_name, and createdAt maps to created_at. The age and email fields don’t need @Column because they match exactly.

Creating the Mapper Interface

With the entity defined, I needed a mapper to perform database operations:

AccountMapper.java
package com.example.mapper;
import com.example.entity.Account;
import com.mybatisflex.core.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface AccountMapper extends BaseMapper<Account> {
}

That’s it. By extending BaseMapper<Account>, I get built-in CRUD operations without writing any SQL. The generic type parameter specifies the entity class this mapper works with.

Using the Mapper in Tests

I wrote a quick test to verify everything works:

AccountMapperTest.java
package com.example.mapper;
import com.example.entity.Account;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class AccountMapperTest {
@Autowired
private AccountMapper accountMapper;
@Test
void testInsert() {
Account account = new Account();
account.setUserName("testuser");
account.setAge(25);
account.setEmail("[email protected]");
int rows = accountMapper.insert(account);
assertEquals(1, rows);
assertNotNull(account.getId()); // Auto-generated ID
}
@Test
void testSelectById() {
Account account = accountMapper.selectOneById(1L);
assertNotNull(account);
assertEquals("testuser", account.getUserName());
}
@Test
void testUpdate() {
Account account = accountMapper.selectOneById(1L);
account.setAge(26);
int rows = accountMapper.update(account);
assertEquals(1, rows);
}
@Test
void testDelete() {
int rows = accountMapper.deleteById(1L);
assertEquals(1, rows);
}
}

The insert, selectOneById, update, and delete methods all come from BaseMapper. No XML files, no handwritten SQL for basic operations.

When You Need @Column

I initially added @Column to every field, thinking it was required. But looking at the documentation, it’s only necessary when there’s a naming mismatch between Java and the database:

ColumnUsage.java
// These need @Column
@Column("user_name")
private String userName; // userName -> user_name
@Column("created_at")
private Date createdAt; // createdAt -> created_at
// These don't need @Column
private Integer age; // age -> age
private String email; // email -> email

MyBatis-Flex automatically converts camelCase to snake_case for mapping, but only @Column lets you specify a completely different column name.

Summary

In this post, I walked through defining entities with @Table, @Id, and @Column annotations in MyBatis-Flex, and creating mapper interfaces by extending BaseMapper. The key insight is that @Column is optional when field names follow camelCase and match snake_case columns. The BaseMapper inheritance provides a complete set of CRUD operations without any SQL boilerplate.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments