10 Must‑Know MyBatis Tricks to Supercharge Your Java Backend

Discover ten powerful MyBatis techniques—from dynamic SQL and resultMap customization to batch operations, pagination, annotation‑based mappers, caching, dynamic table names, custom type handlers, logging, and multi‑datasource configuration—that can dramatically improve Java backend development efficiency and code quality.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
10 Must‑Know MyBatis Tricks to Supercharge Your Java Backend

MyBatis is a lightweight persistence framework that many developers use, but it hides numerous powerful tricks.

1. Flexible use of dynamic SQL

Instead of concatenating SQL strings manually, MyBatis provides dynamic SQL tags such as if, choose, and foreach to build queries safely.

String sql = "SELECT * FROM user WHERE 1=1";
if (name != null) {
    sql += " AND name = '" + name + "'";
}

Using dynamic SQL eliminates manual string handling and prevents SQL injection.

<select id="findUser" resultType="User">
    SELECT * FROM user
    WHERE 1=1
    <if test="name != null and name != ''">
        AND name = #{name}
    </if>
    <if test="age != null">
        AND age = #{age}
    </if>
</select>

2. Leverage resultMap for custom result mapping

When database columns use snake_case but Java fields use camelCase, resultMap can map them correctly.

<resultMap id="userResultMap" type="User">
    <id column="id" property="id"/>
    <result column="user_name" property="userName"/>
    <result column="age" property="age"/>
</resultMap>

<select id="getUserById" resultMap="userResultMap">
    SELECT id, user_name, age FROM user WHERE id = #{id}
</select>

3. Use foreach for batch operations

The foreach tag elegantly handles IN‑clauses for a list of IDs.

<select id="findUsersByIds" resultType="User">
    SELECT * FROM user WHERE id IN
    <foreach item="id" collection="idList" open="(" separator="," close=")">
        #{id}
    </foreach>
</select>

4. MyBatis‑Plus pagination

MyBatis‑Plus provides a pagination plugin that simplifies paging logic.

Page<User> page = new Page<>(1, 10); // page 1, 10 records per page
IPage<User> userPage = userMapper.selectPage(page, null);
System.out.println("Total records: " + userPage.getTotal());
System.out.println("Current page data: " + userPage.getRecords());

5. Use @Mapper interface proxy

Pure annotation mode removes the need for XML mapper files for simple queries.

@Mapper
public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{id}")
    User getUserById(int id);

    @Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})")
    void addUser(User user);
}

6. Second‑level cache

Enabling MyBatis second‑level cache can improve performance for repeated queries.

<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>

<mapper namespace="com.example.mapper.UserMapper">
    <cache/>
    <select id="getUserById" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

7. Dynamic table name switching

For multi‑tenant scenarios, MyBatis can replace table names at runtime.

<select id="getDataFromDynamicTable" resultType="Map">
    SELECT * FROM ${tableName} WHERE id = #{id}
</select>

8. Custom typeHandler

A custom typeHandler can map database values like 0/1 to Java booleans.

@MappedTypes(Boolean.class)
@MappedJdbcTypes(JdbcType.INTEGER)
public class BooleanTypeHandler extends BaseTypeHandler<Boolean> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter ? 1 : 0);
    }

    @Override
    public Boolean getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return rs.getInt(columnName) == 1;
    }
}

9. Logging for debugging

Configuring MyBatis logging prints full SQL statements and parameters.

<configuration>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>
==>  Preparing: SELECT * FROM user WHERE id = ?
==>  Parameters: 1(Integer)
<==      Total: 1

10. Multi‑datasource support

When an application needs to connect to multiple databases, configure separate data sources and SqlSession factories.

@Configuration
@MapperScan(basePackages = "com.example.mapper", sqlSessionTemplateRef = "sqlSessionTemplate1")
public class DataSourceConfig1 {
    @Bean(name = "dataSource1")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "sqlSessionFactory1")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource1") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        return bean.getObject();
    }

    @Bean(name = "sqlSessionTemplate1")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

Conclusion

MyBatis is simple and efficient, yet many developers only use its basic features; these ten tips help unlock its full potential for more effective Java backend development.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaperformanceSQLORM
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.