Using MyBatis‑Plus‑Join Plugin for Multi‑Table Joins in Java

This article introduces the MyBatis‑Plus‑Join library that adds join capabilities to MyBatis‑Plus, explains how to install it via Maven or Gradle, shows how to extend mapper and service interfaces, and provides detailed code examples for simple three‑table queries, pagination, and advanced custom SQL usage.

Top Architect
Top Architect
Top Architect
Using MyBatis‑Plus‑Join Plugin for Multi‑Table Joins in Java

MyBatis‑Plus does not support join operations out of the box, which limits its use in many business scenarios that require multi‑table queries. The author presents a custom jar package, mybatis‑plus‑join , that enables join functionality without writing raw SQL.

Installation

Maven dependency:

<dependency>
    <groupId>com.github.yulichang</groupId>
    <artifactId>mybatis-plus-join</artifactId>
    <version>1.2.4</version>
</dependency>

Gradle:

implementation 'com.github.yulichang:mybatis-plus-join:1.2.4'

After cloning the source code, you can run mvn install and then add the dependency. Note that MyBatis‑Plus version must be ≥ 3.4.0.

Usage

Mapper must extend MPJBaseMapper (required).

Service can extend MPJBaseService (optional).

Service implementation can extend MPJBaseServiceImpl (optional).

The core classes are MPJLambdaWrapper and MPJQueryWrapper. Below are typical usage examples.

Simple three‑table query with MPJLambdaWrapper

class test {
    @Resource
    private UserMapper userMapper;

    void testJoin() {
        List<UserDTO> list = userMapper.selectJoinList(UserDTO.class,
            new MPJLambdaWrapper<UserDO>()
                .selectAll(UserDO.class)
                .select(UserAddressDO::getTel)
                .selectAs(UserAddressDO::getAddress, UserDTO::getUserAddress)
                .select(AreaDO::getProvince, AreaDO::getCity)
                .leftJoin(UserAddressDO.class, UserAddressDO::getUserId, UserDO::getId)
                .leftJoin(AreaDO.class, AreaDO::getId, UserAddressDO::getAreaId)
                .eq(UserDO::getId, 1)
                .like(UserAddressDO::getTel, "1")
                .gt(UserDO::getId, 5));
    }
}

Corresponding SQL:

SELECT
    t.id,
    t.name,
    t.sex,
    t.head_img,
    t1.tel,
    t1.address AS userAddress,
    t2.province,
    t2.city
FROM
    user t
    LEFT JOIN user_address t1 ON t1.user_id = t.id
    LEFT JOIN area t2 ON t2.id = t1.area_id
WHERE
    (t.id = ? AND t1.tel LIKE ? AND t.id > ?);

Other features of MPJLambdaWrapper include SQL functions, multi‑condition ON statements, and safe condition queries using MyBatis‑Plus native methods.

Pagination query

class test {
    @Resource
    private UserMapper userMapper;

    void testJoin() {
        IPage<UserDTO> iPage = userMapper.selectJoinPage(new Page<>(2, 10), UserDTO.class,
            new MPJLambdaWrapper<UserDO>()
                .selectAll(UserDO.class)
                .select(UserAddressDO::getTel)
                .selectAs(UserAddressDO::getAddress, UserDTO::getUserAddress)
                .select(AreaDO::getProvince, AreaDO::getCity)
                .leftJoin(UserAddressDO.class, UserAddressDO::getUserId, UserDO::getId)
                .leftJoin(AreaDO.class, AreaDO::getId, UserAddressDO::getAreaId)
                .eq(UserDO::getId, 1)
                .like(UserAddressDO::getTel, "1")
                .gt(UserDO::getId, 5));
    }
}

Corresponding SQL includes a LIMIT clause for pagination.

Using MPJQueryWrapper allows raw SQL fragments for joins and selections. Example:

class test {
    @Resource
    private UserMapper userMapper;

    void testJoin() {
        List<UserDTO> list = userMapper.selectJoinList(UserDTO.class,
            new MPJQueryWrapper<UserDO>()
                .selectAll(UserDO.class)
                .select("addr.tel", "addr.address", "a.province")
                .leftJoin("user_address addr on t.id = addr.user_id")
                .rightJoin("area a on addr.area_id = a.id")
                .like("addr.tel", "1")
                .le("a.province", "1"));
    }
}

Corresponding SQL demonstrates LEFT and RIGHT joins with conditions.

Advanced usage shows how to add custom SQL functions, aggregate functions, and sub‑queries within the wrapper, while still benefiting from MyBatis‑Plus’s safety against SQL injection.

The article concludes with a call to download the source code for further study and invites readers to join a community of architects for discussion.

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.

BackendJavaSQLORMJOINmybatis-plus
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

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.