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.
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: 110. 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
