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.
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.
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.
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.
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.
