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:
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:
package com.example.mapper;
import com.example.entity.Account;import com.mybatisflex.core.BaseMapper;import org.apache.ibatis.annotations.Mapper;
@Mapperpublic 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:
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.*;
@SpringBootTestclass AccountMapperTest {
@Autowired private AccountMapper accountMapper;
@Test void testInsert() { Account account = new Account(); account.setUserName("testuser"); account.setAge(25);
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:
// 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 @Columnprivate Integer age; // age -> ageprivate String email; // email -> emailMyBatis-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