### Install SpringBoot3 Starter Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/quickstart/install2.md Replace the default MyBatis-Plus SpringBoot3 starter dependency with the custom one. ```xml com.baomidou mybatis-plus-spring-boot3-starter version ``` ```xml com.github.yulichang mybatis-plus-spring-boot3-starter version ``` -------------------------------- ### Install SpringBoot2 Starter Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/quickstart/install2.md Replace the default MyBatis-Plus SpringBoot2 starter dependency with the custom one. ```xml com.baomidou mybatis-plus-boot-starter version ``` ```xml com.github.yulichang mybatis-plus-boot-starter version ``` -------------------------------- ### Custom Join with Full Join Example Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/lambda/join.md Shows how to perform custom join types by providing the join keyword as a string. This example uses 'FULL JOIN' but can be adapted for other SQL join types. ```java .join("FULL JOIN", Address.class, on -> on .eq(Address::getUserId, User::getId) .eq(Address::getId, User::getId)) ``` -------------------------------- ### Dynamic Table Name Example Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/dynamic-table-name.md Illustrates how to dynamically change a table name by appending a suffix. This example shows the modification of the 'user' table to 'user_2023'. ```java .setTableName(name -> name + "_2023") ``` -------------------------------- ### Generated SQL for simple or() examples Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Shows the SQL generated when using the `or()` method to combine conditions with OR logic. ```sql -- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同 SELECT * FROM user WHERE id = 1 OR name = '老王' ``` -------------------------------- ### Generated SQL for func() examples Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Illustrates the SQL generated by the `func` method based on the conditional logic within the consumer. ```sql -- 根据条件生成的 SQL 会有所不同 -- 如果条件为 true,则生成的 SQL 为: SELECT * FROM user WHERE id = 1 -- 如果条件为 false,则生成的 SQL 为: SELECT * FROM user WHERE id != 1 ``` -------------------------------- ### Java Union Query Example Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/union.md Demonstrates how to build a union query using MPJLambdaWrapper. Use unionAll() for union all operations. ```java class MpJoinTest { @Resource private UserMapper userMapper; @Test void union() { MPJLambdaWrapper w = JoinWrappers.lambda(User.class) .selectAll(User.class) .union(User.class, union -> union .selectAll(User.class)) .union(User.class, union -> union .selectAll(User.class)); //union all 调用unionAll即可 如下 //.unionAll(User.class, union -> union...); w.list(); } } ``` -------------------------------- ### XML Configuration Query with Wrapper Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Example of using a custom SQL query with a Wrapper via XML configuration in a mapper. ```xml ``` -------------------------------- ### Java - selectJoinList Example Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/selectJoinList.md Demonstrates how to use selectJoinList with MPJLambdaWrapper to perform a left join and retrieve results into a DTO. Ensure UserMapper and necessary entities are available. ```java class MpJoinTest { @Resource private UserMapper userMapper; @Test void joinTest() { MPJLambdaWrapper wrapper = new MPJLambdaWrapper() .selectAll(User.class) .select(Address::getTel) .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 2); List list = userMapper.selectJoinList(UserDTO.class, wrapper); } } ``` -------------------------------- ### Generated SQL for nested or() examples Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Displays the SQL generated for nested OR conditions, demonstrating how complex OR structures are translated into SQL. ```sql -- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同 SELECT * FROM user WHERE (name = '李白' AND status = 'alive') OR (name = '杜甫' AND status = 'alive') ``` -------------------------------- ### Generated SQL for nested and() examples Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Shows the SQL generated for nested AND conditions, illustrating how complex AND structures are represented in SQL. ```sql -- 普通 Wrapper 和 Lambda Wrapper 生成的 SQL 相同 SELECT * FROM user WHERE ((name = '李白' AND status = 'alive') AND (name = '杜甫' AND status = 'alive')) ``` -------------------------------- ### Java - selectJoinPage Example Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/selectJoinPage.md Demonstrates how to use `selectJoinPage` with `MPJLambdaWrapper` to perform a left join between User and Address tables, selecting specific fields and applying a filter. Ensure the MyBatis-Plus pagination plugin is enabled. ```java class MpJoinTest { @Resource private UserMapper userMapper; @Test void joinTest() { MPJLambdaWrapper wrapper = new MPJLambdaWrapper() .selectAll(User.class) .select(Address::getAddress) .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 1); IPage page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class, wrapper); } } ``` -------------------------------- ### Basic selectJoinCount Usage Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/selectJoinCount.md This example demonstrates the basic usage of selectJoinCount to get the total number of records matching the join conditions. ```APIDOC ## selectJoinCount ### Description Retrieves the total count of records from a join query. ### Method `selectJoinCount(MPJLambdaWrapper wrapper)` ### Parameters #### Wrapper - **wrapper** (MPJLambdaWrapper) - Required - The wrapper object containing join and query conditions. ### Request Example ```java MPJLambdaWrapper wrapper = new MPJLambdaWrapper() .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 2); Integer count = userMapper.selectJoinCount(wrapper); ``` ### Response #### Success Response (Integer) - **count** (Integer) - The total number of records matching the query. ### Response Example ```json 1 ``` ``` -------------------------------- ### Full Example with Multiple Functions Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/lambda/select/selectFunc.md Demonstrates the integration of various selectFunc usages within a single query, including date formatting, string concatenation, and conditional logic. ```java MPJLambdaWrapper wrapper = JoinWrappers.lambda(User.class) .selectFunc(() -> "DATE_FORMAT(%s, '%%Y-%%m-%%d')", User::getCreateTime) .selectFunc("concat(%s, %s)", arg -> arg .accept(User::getFirstName, User::getLastName) , UserDTO::getFullName) .selectFunc("if(%s < 18, {0}, {1})", arg -> arg .accept(User::getAge).values("未成年", "成年") , UserDTO::getStatus); List userList = wrapper.list(UserDTO.class); ``` -------------------------------- ### in SubQuery Example Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/sub-query.md An example demonstrating the usage of the `in` subquery with a nested condition and setting a subquery alias. ```APIDOC ## in SubQuery Example ### Description This example illustrates how to use the `in` clause for subqueries. It shows how to select specific fields from the subquery, apply a range condition using `between`, and set an alias for the subquery. ### Code Example ```java MPJLambdaWrapper wrapper = JoinWrappers.lambda(User.class) .selectAll() .leftJoin(Address.class, Address::getUserId, User::getId) .in(User::getId, User.class, in -> in .setAlias("sub") // Sets an alias for the subquery .select(User::getId) .between(User::getId, 0, 100)); wrapper.list(); ``` ### Corresponding SQL ```sql SELECT t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.id IN (SELECT sub.id FROM `user` sub WHERE sub.del = false AND (sub.id BETWEEN ? AND ?)) ``` ``` -------------------------------- ### SQL - Corresponding Query Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/selectJoinList.md This SQL query corresponds to the Java selectJoinList example, illustrating the generated SQL for a left join with specific selections and a WHERE clause. ```sql SELECT t.id, t.name, t.sex, t.head_img, t1.tel FROM user t LEFT JOIN address t1 ON t1.user_id = t.id WHERE (t.id = ?) ``` -------------------------------- ### Generated SQL for Union Query Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/union.md The corresponding SQL generated for the union query example. ```sql SELECT t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time FROM `user` t UNION SELECT t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time FROM `user` t UNION SELECT t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time FROM `user` t ``` -------------------------------- ### Annotation Query with Wrapper Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Example of using a custom SQL query with a Wrapper via annotation in a mapper interface. ```java @Select("select * from mysql_data ${ew.customSqlSegment}") List getAll(@Param(Constants.WRAPPER) Wrapper wrapper); ``` -------------------------------- ### Sub-query Example with 'in' Operator Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/sub-query.md An example of using the `in` operator for sub-queries. It selects users and joins with addresses, then filters users whose IDs are within a specified range from a sub-query on the user table. ```java MPJLambdaWrapper wrapper = JoinWrappers.lambda(User.class) .selectAll() .leftJoin(Address.class, Address::getUserId, User::getId) .in(User::getId, User.class, in -> in// [!code highlight] .select(User::getId)// [!code highlight] .between(User::getId, 0, 100));// [!code highlight] ``` -------------------------------- ### Generated SQL for applyFunc Example Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/apply-func.md This SQL illustrates the output generated by the Java code using applyFunc. It shows how the concatenated function calls with placeholders are translated into a valid SQL WHERE clause. ```sql SELECT t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE concat(t.id, t1.user_id, ?) is not null AND concat(t.id, t1.user_id, ?) is not null ``` -------------------------------- ### Updating Multiple Tables Using Entities and Wrapper Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/updateJoinAndNull.md This example shows how to update multiple joined tables (User, Address, Area) using entities for SET clauses and the wrapper for WHERE conditions. It utilizes `setUpdateEntity` to specify which entities' fields should be updated. Note that `setUpdateEntity` updates non-null fields, while `setUpdateEntityAndNull` updates all fields. ```java class MpJoinTest { @Resource private UserMapper userMapper; /** * 场景: * 三表联查并且按照实体更新这三张表 * 主表 user 副表 address 和 area */ @Test void update() { //主表类 用于生成 set 语句 User user = new User().setName("aaa").setUpdateBy(123); //两个关联表 用于生成 set 语句 Address address = new Address().setTel("119").setAddress("人民广场"); Area area = new Area().setProvince("北京").setCity("北京!"); UpdateJoinWrapper update = JoinWrappers.update(User.class) //设置两个副表的 set 语句 .setUpdateEntity(address, area) //address和area 两张表空字段和非空字段一起更新 可以改成如下setUpdateEntityAndNull //.setUpdateEntityAndNull(address, area) .leftJoin(Address.class, Address::getUserId, User::getId) .leftJoin(Area.class, Area::getId, Address::getAreaId) .eq(User::getId, 1); int i = userMapper.updateJoinAndNull(user, update); } ``` ```log ==> Preparing: UPDATE `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) SET t.pid=?, t.`name`=?, t.`json`=?, t.sex=?, t.head_img=?, t.create_time=?, t.address_id=?, t.address_id2=?, t.create_by=?, t.update_by=?, t1.tel=?,t1.address=?,t2.province=?,t2.city=? WHERE (t.id = ?) ==> Parameters: null, aaa(String), null, null, null, null, null, null, null, 123(Integer), 119(String), 人民广场(String), 北京(String), 北京!(String), 1(Integer) <== Updates: 19 ``` -------------------------------- ### Wrapper Join Delete (Delete All Tables) Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/deleteJoin.md Example demonstrating how to perform a join delete operation that targets all tables involved in the join (primary and secondary tables). ```APIDOC ## Wrapper Join Delete (Delete All Tables) ### Description This example demonstrates how to use `deleteJoin` with `deleteAll()` to remove records from all tables involved in the join (primary and secondary tables). ### Method `userMapper.deleteJoin(wrapper);` ### Example Usage ```java DeleteJoinWrapper wrapper = JoinWrappers.delete(User.class) .deleteAll() .leftJoin(Address.class, Address::getUserId, User::getId) .leftJoin(Area.class, Area::getId, Address::getAreaId) .eq(User::getId, 1); int i = userMapper.deleteJoin(wrapper); ``` ### SQL Log Example ```log ==> Preparing: DELETE t,t1,t2 FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) WHERE (t.id = ?) ==> Parameters: 1(Integer) <== Updates: 19 ``` ### Note on Deletion Scope - `deleteAll()`: Deletes data from all tables (primary and secondary). - `delete(Class... deleteClasses)`: Allows specifying which tables to delete data from. ``` -------------------------------- ### Setting SET clauses and WHERE conditions manually Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/updateJoin.md This example demonstrates how to manually set the fields to be updated for multiple tables and specify the WHERE clause using the `updateJoin` method. ```APIDOC ## Manual SET and WHERE clause ### Description Manually set update fields for multiple tables and define the WHERE condition. ### Example Usage ```java // Assuming UserMapper and AddressMapper are available UpdateJoinWrapper update = JoinWrappers.update(User.class) .set(User::getName, "aaaaaa") // Set field in the main table .set(Address::getAddress, "bbbbb") // Set field in the joined table .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 1); // Set WHERE condition int affectedRows = userMapper.updateJoin(null, update); ``` ### SQL Equivalent ```sql UPDATE `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) SET t.`name`=?, t1.address=? WHERE (t.id = ?) ``` ``` -------------------------------- ### Example of Dynamic Table Name with Wrapper Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/dynamic-table-name.md Demonstrates how to set dynamic table names for both the main and a secondary table within a wrapper query. Ensure you are using version 1.4.4+ for wrapper dynamic table name support. Be aware of potential SQL injection risks when using dynamic table names. ```java MPJLambdaWrapper wrapper = new MPJLambdaWrapper() .select(User::getId) .leftJoin(Address.class, on -> on .eq(Address::getUserId, User::getId) // 副表动态表名 name 为原副表名 返回新表名 .setTableName(name -> name + "aaaaaaaaaa")) // [!code ++] .leftJoin(Area.class, Area::getId, Address::getAreaId) .le(User::getId, 10000) .orderByDesc(User::getId) // 主表动态表名 name 为原主表表名 返回新表名 .setTableName(name -> name + "bbbbbbb"); // [!code ++] ``` -------------------------------- ### Updating Multiple Tables Using Entity Objects Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/updateJoinAndNull.md This example demonstrates updating multiple joined tables (primary, secondary, and tertiary) using entity objects for each. The `setUpdateEntity` and `setUpdateEntityAndNull` methods allow specifying which entities' fields should be updated. ```APIDOC ## Update Multiple Tables with Entities ### Description Update multiple joined tables (e.g., user, address, area) by providing entity objects for each. Use `setUpdateEntity` to update non-null fields or `setUpdateEntityAndNull` to update all fields (including nulls) for the specified entities. ### Example Usage ```java // Assuming User, Address, Area classes and UserMapper are defined User user = new User().setName("aaa").setUpdateBy(123); Address address = new Address().setTel("119").setAddress("人民广场"); Area area = new Area().setProvince("北京").setCity("北京!"); UpdateJoinWrapper update = JoinWrappers.update(User.class) .setUpdateEntity(address, area) // Updates non-null fields of address and area // .setUpdateEntityAndNull(address, area) // Use this to update all fields including nulls .leftJoin(Address.class, Address::getUserId, User::getId) .leftJoin(Area.class, Area::getId, Address::getAreaId) .eq(User::getId, 1); int updatedRows = userMapper.updateJoinAndNull(user, update); ``` ### Log Output Example ```log ==> Preparing: UPDATE `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) SET t.pid=?, t.`name`=?, t.`json`=?, t.sex=?, t.head_img=?, t.create_time=?, t.address_id=?, t.address_id2=?, t.create_by=?, t.update_by=?, t1.tel=?,t1.address=?,t2.province=?,t2.city=? WHERE (t.id = ?) ==> Parameters: null, aaa(String), null, null, null, null, null, null, null, 123(Integer), 119(String), 人民广场(String), 北京(String), 北京!(String), 1(Integer) <== Updates: 19 ``` ### Note `setUpdateEntity` updates only non-null fields. Use `setUpdateEntityAndNull` to update all fields, including nulls. For updating only non-null fields of the primary entity, refer to the `updateJoin` method. ``` -------------------------------- ### Wrapper Join Delete (Delete Primary Table) Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/deleteJoin.md Example demonstrating how to perform a join delete operation that targets only the primary table based on the provided wrapper conditions. ```APIDOC ## Wrapper Join Delete (Delete Primary Table) ### Description This example shows how to use `deleteJoin` to delete records from the primary table (`User`) based on specified join conditions and a `WHERE` clause. ### Method `userMapper.deleteJoin(wrapper);` ### Example Usage ```java DeleteJoinWrapper wrapper = JoinWrappers.delete(User.class) .leftJoin(Address.class, Address::getUserId, User::getId) .leftJoin(Area.class, Area::getId, Address::getAreaId) .eq(User::getId, 1); int i = userMapper.deleteJoin(wrapper); ``` ### SQL Log Example ```sql ==> Preparing: DELETE t FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) WHERE (t.id = ?) ==> Parameters: 1(Integer) <== Updates: 1 ``` ``` -------------------------------- ### Wrapper Join Delete (Main Table Only) Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/deleteJoin.md Demonstrates deleting only the main table's records based on wrapper conditions. This example uses a left join to specify the deletion criteria. ```java class MpJoinTest { @Resource private UserMapper userMapper; /** * wrapper连表删除(删除主表) */ @Test void update() { DeleteJoinWrapper wrapper = JoinWrappers.delete(User.class) .leftJoin(Address.class, Address::getUserId, User::getId) .leftJoin(Area.class, Area::getId, Address::getAreaId) .eq(User::getId, 1); int i = userMapper.deleteJoin(wrapper); } } ``` ```sql ==> Preparing: DELETE t FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) WHERE (t.id = ?) ==> Parameters: 1(Integer) <== Updates: 1 ``` -------------------------------- ### Main table update by entity, sub-table manual SET Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/updateJoin.md This example demonstrates updating the main table using an entity and manually setting fields for a sub-table, with the wrapper defining the WHERE condition. ```APIDOC ## Main table update by entity, sub-table manual SET ### Description Updates the main table using an entity for SET clauses and manually sets fields for a sub-table, using the wrapper for the WHERE condition. ### Example Usage ```java // Assuming UserMapper and AddressMapper are available User user = new User().setName("aaa").setUpdateBy(123); UpdateJoinWrapper update = JoinWrappers.update(User.class) .set(Address::getAddress, "bbbbb") // Set field in the joined table .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 1); // Set WHERE condition int affectedRows = userMapper.updateJoin(user, update); ``` ### SQL Equivalent ```sql UPDATE `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) SET t.`name`=?, t.update_by=?, t1.address=? WHERE (t.id = ?) ``` ### Note By default, only non-null fields in the entity are updated. Refer to `updateJoinAndNull` for updating all fields (including nulls). ``` -------------------------------- ### Setting SET Clauses and WHERE Conditions Manually Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/updateJoinAndNull.md This example demonstrates manually setting fields for update using the `set` method on the `UpdateJoinWrapper`. The `entity` parameter passed to `updateJoinAndNull` is null, indicating that only the explicitly set fields should be updated. ```java class MpJoinTest { @Resource private UserMapper userMapper; /** * 手动set条件 * 更新 user表name字段和address表address字段 */ @Test void update() { UpdateJoinWrapper update = JoinWrappers.update(User.class) .set(User::getName, "aaaaaa") .set(Address::getAddress, "bbbbb") .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 1); int i = userMapper.updateJoinAndNull(null, update); } ``` ```sql UPDATE `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) SET t.`name`=?, t1.address=? WHERE (t.id = ?) ``` -------------------------------- ### Setting Set Statements and Where Conditions Manually Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/updateJoinAndNull.md This example demonstrates how to manually set fields for update using the `set` method within the `UpdateJoinWrapper`. This is useful when you want to explicitly define which fields to update and their values, including fields from joined tables. ```APIDOC ## Manual Set Statements ### Description Manually set the fields to be updated using the `set` method. This example updates the `name` field of the `user` table and the `address` field of the `address` table. ### Example Usage ```java // Assuming UserMapper and Address are defined UpdateJoinWrapper update = JoinWrappers.update(User.class) .set(User::getName, "aaaaaa") .set(Address::getAddress, "bbbbb") .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 1); int updatedRows = userMapper.updateJoinAndNull(null, update); ``` ### Corresponding SQL ```sql UPDATE `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) SET t.`name`=?, t1.address=? WHERE (t.id = ?) ``` ``` -------------------------------- ### Left Join with Multi-Condition Field Aliases Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/lambda/join.md Provides an example of using field aliases within multi-condition joins. This allows referencing specific aliases for fields involved in the ON clause. ```java leftJoin(Address.class, "addr", on -> on .eq(Address::getUserId, "u1", User::getId) .eq(Address::getId, "u2", User::getId) .eq("addr1", Address::getId, "u2", User::getId)) ``` -------------------------------- ### Get Join Count with Default COUNT(*) Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/selectJoinCount.md Use selectJoinCount to get the total number of records matching the join conditions and filters. This defaults to COUNT(*). ```java class MpJoinTest { @Resource private UserMapper userMapper; @Test void joinTest() { MPJLambdaWrapper wrapper = new MPJLambdaWrapper() .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 2); Integer count = userMapper.selectJoinCount(wrapper); System.out.println(count); } } ``` ```sql SELECT COUNT(*) FROM user t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE (t.id = ?) ``` -------------------------------- ### 开启多级查询 Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/mapping/intro.md 默认映射查询只进行两层,可通过 conf.loop(true) 开启多级查询。注意:在父子关系表中使用可能导致死循环。 ```java userService.listDeep(Wrappers.emptyWrapper(), conf -> conf.loop(true)); ``` -------------------------------- ### Implement MPJBaseServiceImpl for User Service Implementation (Optional) Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/quickstart/install.md Optionally, implement MPJBaseServiceImpl for your User service implementation to provide the service layer functionality. This requires a compatible UserMapper. ```java @Service public class UserServiceImpl extends MPJBaseServiceImpl implements UserService { } ``` -------------------------------- ### Adding OR conditions with or() - QueryWrapper Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Chain the `or()` method with `QueryWrapper` to append OR logic between subsequent query conditions. This example shows a simple OR condition. ```java QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("id", 1).or().eq("name", "老王"); ``` -------------------------------- ### Updating based on entity with wrapper as WHERE condition Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/updateJoin.md This example shows how to update records using an entity for SET clauses and a wrapper for the WHERE condition. ```APIDOC ## Update based on Entity with Wrapper as WHERE condition ### Description Updates records using an entity to define the SET clauses and a wrapper to specify the WHERE condition. ### Example Usage ```java // Assuming UserMapper is available User user = new User().setName("aaa").setUpdateBy(123); UpdateJoinWrapper update = JoinWrappers.update(User.class) .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 1); // Set WHERE condition int affectedRows = userMapper.updateJoin(user, update); ``` ### SQL Equivalent ```sql UPDATE `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) SET t.`name`=?, t.update_by=? WHERE (t.id = ?) ``` ### Note By default, only non-null fields in the entity are updated. Refer to `updateJoinAndNull` for updating all fields (including nulls). ``` -------------------------------- ### 配置Gradle快照仓库 Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/problem.md 为Gradle项目配置快照仓库,以便下载MyBatis-Plus-Join的快照版本。 ```groovy repositories { maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } } ``` -------------------------------- ### selectJoinCount with specific field count Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/selectJoinCount.md This example shows how to use selectJoinCount to count a specific field, like 'id', from the joined tables. ```APIDOC ## selectJoinCount with specific field ### Description Retrieves the count of a specific field (e.g., 'id') from a join query. This is useful when you need to count distinct values or a particular column. ### Method `selectJoinCount(MPJLambdaWrapper wrapper)` ### Parameters #### Wrapper - **wrapper** (MPJLambdaWrapper) - Required - The wrapper object containing join, select, and query conditions. ### Request Example ```java MPJLambdaWrapper wrapper = new MPJLambdaWrapper() .select(User::getId) .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 2); Integer count = userMapper.selectJoinCount(wrapper); ``` ### Response #### Success Response (Integer) - **count** (Integer) - The count of the specified field (e.g., 'id') matching the query. ### Response Example ```json 1 ``` ``` -------------------------------- ### Database Schema Script Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/quickstart/quickstart.md SQL script to create the 'user' and 'address' tables. ```sql DROP TABLE IF EXISTS user; CREATE TABLE user ( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', age INT(11) NULL DEFAULT NULL COMMENT '年龄', email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id) ); DROP TABLE IF EXISTS address; CREATE TABLE address ( id BIGINT(20) NOT NULL COMMENT '主键ID', user_id BIGINT(20) NULL DEFAULT NULL COMMENT '用户id', city VARCHAR(50) NULL DEFAULT NULL COMMENT '城市', address VARCHAR(50) NULL DEFAULT NULL COMMENT '地址', PRIMARY KEY (id) ); ``` -------------------------------- ### 添加MyBatis-Plus-Join快照版本依赖 Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/problem.md 添加MyBatis-Plus-Join的快照版本依赖,通常版本号以SNAPSHOT结尾。需要配置快照仓库以供下载。 ```xml com.github.yulichang mybatis-plus-join-boot-starter xxx-SNAPSHOT ``` ```xml snapshots https://oss.sonatype.org/content/repositories/snapshots/ ``` ```xml aliyunmaven *,!snapshots 阿里云公共仓库 https://maven.aliyun.com/repository/public ``` -------------------------------- ### Get Lambda Wrapper from UpdateWrapper Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Obtain a LambdaUpdateWrapper from an UpdateWrapper to use Lambda expressions for building update conditions, improving code conciseness and safety. ```java UpdateWrapper updateWrapper = new UpdateWrapper<>(); LambdaUpdateWrapper lambdaUpdateWrapper = updateWrapper.lambda(); // 使用 Lambda 表达式构建更新条件 lambdaUpdateWrapper.set(User::getName, "李四"); ``` -------------------------------- ### Get Lambda Wrapper from QueryWrapper Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Obtain a LambdaQueryWrapper from a QueryWrapper to use Lambda expressions for building query conditions, enhancing type safety and readability. ```java QueryWrapper queryWrapper = new QueryWrapper<>(); LambdaQueryWrapper lambdaQueryWrapper = queryWrapper.lambda(); // 使用 Lambda 表达式构建查询条件 lambdaQueryWrapper.eq("name", "张三"); ``` -------------------------------- ### 修改 Service 接口继承 MPJDeepService Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/mapping/intro.md 将原有的 MP 的 IService 接口修改为 MPJDeepService 以支持注解查询。此更改不会影响原有代码。 ```java public interface UserService extends MPJDeepService { } ``` -------------------------------- ### Implement Custom Extension Interface Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/wrapper-ext.md Create an `Ext` interface in the `com.github.yulichang.wrapper.ext` package to add new methods or overload existing ones. Ensure the package and class names are not changed. ```java package com.github.yulichang.wrapper.ext; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.github.yulichang.wrapper.MPJLambdaWrapper; import com.github.yulichang.wrapper.interfaces.IExt; public interface Ext> extends IExt { default Children eqIfPresent(SFunction column, Object val) { getChildren().eq(Objects.nonNull(val), column, val); return getChildren(); } } ``` -------------------------------- ### Get Join Count with COUNT(field) Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/selectJoinCount.md To count a specific field, use the select() method before calling selectJoinCount. Note that only one field can be selected for counting. ```java class MpJoinTest { @Resource private UserMapper userMapper; @Test void joinTest1() { MPJLambdaWrapper wrapper = new MPJLambdaWrapper() .select(User::getId) .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 2); Integer count = userMapper.selectJoinCount(wrapper); System.out.println(count); } } ``` ```sql SELECT COUNT(t.id) FROM user t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE (t.id = ?) ``` -------------------------------- ### Database Data Script Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/quickstart/quickstart.md SQL script to insert sample data into the 'user' and 'address' tables. ```sql DELETE FROM user; INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, 'test1@baomidou.com'), (2, 'Jack', 20, 'test2@baomidou.com'), (3, 'Tom', 28, 'test3@baomidou.com'), (4, 'Sandy', 21, 'test4@baomidou.com'), (5, 'Billie', 24, 'test5@baomidou.com'); DELETE FROM address; INSERT INTO address (id, user_id, city, address) VALUES (1, 1, '北京', '人民广场'), (2, 2, '上海', '人民广场'), (3, 3, '广州', '人民广场'), (4, 4, '上海', '人民广场'), (5, 5, '北京', '人民广场'); ``` -------------------------------- ### Updating multiple tables using entities Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/updateJoin.md This example shows how to update fields in the main table and multiple sub-tables simultaneously using entities, with the wrapper specifying the WHERE condition. ```APIDOC ## Updating multiple tables using entities ### Description Updates fields in the main table and multiple sub-tables using entities for SET clauses, with the wrapper defining the WHERE condition. ### Example Usage ```java // Assuming UserMapper, AddressMapper, and AreaMapper are available User user = new User().setName("aaa").setUpdateBy(123); Address address = new Address().setTel("119").setAddress("People's Square"); Area area = new Area().setProvince("Beijing").setCity("Beijing!"); UpdateJoinWrapper update = JoinWrappers.update(User.class) .setUpdateEntity(address, area) // Set fields for sub-tables // .setUpdateEntityAndNull(address, area) // Use this to update null and non-null fields .leftJoin(Address.class, Address::getUserId, User::getId) .leftJoin(Area.class, Area::getId, Address::getAreaId) .eq(User::getId, 1); // Set WHERE condition int affectedRows = userMapper.updateJoin(user, update); ``` ### SQL Equivalent ```sql UPDATE `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) SET t.`name`=?, t.update_by=?, t1.tel=?, t1.address=?, t2.province=?, t2.city=? WHERE (t.id = ?) ``` ### Note By default, only non-null fields in the entities are updated. Use `setUpdateEntityAndNull` to update all fields (including nulls). ``` -------------------------------- ### 调用映射查询方法 Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/mapping/intro.md 通过 Service 层的方法(如 getByIdDeep, listDeep, pageDeep)执行映射查询。注意:关系映射通过多次单表查询实现,默认只查询两层。 ```java /** * 一对一,一对多关系映射查询 * 以Deep结尾的方法会进行映射查询 * 如果不需要关系映射就使用mybatis plus原生方法即可,比如 getById listByIds 等 *

* 注意:关系映射不会去关联查询,而是执行多次单表查询(对结果汇总后使用in语句查询,再对结果进行匹配) */ @SpringBootTest class MappingTest { @Resource private UserService userService; @Test void test1() { User uesr = userService.getByIdDeep(2); System.out.println(deep); } @Test void test2() { List list = userService.listDeep(Wrappers.emptyWrapper()); list.forEach(System.out::println); } @Test void test3() { Page page = new Page<>(2, 2); Page result = userService.pageDeep(page, Wrappers.emptyWrapper()); result.getRecords().forEach(System.out::println); } } ``` -------------------------------- ### Corresponding SQL for Aliasing Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/lambda/select/selectAs.md This shows the resulting SQL when using the aliasing methods. ```sql t.name AS nickname ``` -------------------------------- ### Creating MyBatis-Plus Wrappers Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Use the Wrappers factory class to quickly instantiate QueryWrapper, LambdaQueryWrapper, UpdateWrapper, and LambdaUpdateWrapper. This reduces boilerplate code. ```java QueryWrapper queryWrapper = Wrappers.query(); queryWrapper.eq("name", "张三"); ``` ```java LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(); lambdaQueryWrapper.eq(User::getName, "张三"); ``` ```java UpdateWrapper updateWrapper = Wrappers.update(); updateWrapper.set("name", "李四"); ``` ```java LambdaUpdateWrapper lambdaUpdateWrapper = Wrappers.lambdaUpdate(); lambdaUpdateWrapper.set(User::getName, "李四"); ``` -------------------------------- ### notLikeRight - QueryWrapper and LambdaQueryWrapper Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Use notLikeRight to exclude records that do not start with the specified value (non-left fuzzy match). This method is applicable to string fields and supports both QueryWrapper and LambdaQueryWrapper. ```java QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.notLikeRight("name", "王"); ``` ```java LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.notLikeRight(User::getName, "王"); ``` -------------------------------- ### likeLeft - QueryWrapper and LambdaQueryWrapper Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/condition-wrapper.md Use likeLeft for right fuzzy matching, excluding records that do not start with the specified value. This method is suitable for string fields and supports both QueryWrapper and LambdaQueryWrapper. ```java QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.likeLeft("name", "王"); ``` ```java LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.likeLeft(User::getName, "王"); ``` ```sql SELECT * FROM user WHERE name LIKE '%王' ``` -------------------------------- ### Call Custom Extension Methods Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/wrapper-ext.md After implementing the `Ext` interface and excluding the default extension package, you can directly call your custom methods like `eqIfPresent` on `JoinWrappers`. ```java JoinWrappers.lambda(User.class) .selectAll() .eqIfPresent(User::getId, 1) .eq(User::getId, 1); ``` -------------------------------- ### SQL - Corresponding Query Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/selectJoinPage.md The SQL query generated by the `selectJoinPage` method with the provided wrapper configuration. This shows the structure of the join and the WHERE clause. ```sql SELECT t.id, t.name, t.sex, t.head_img, t1.address FROM user t LEFT JOIN address t1 ON t1.user_id = t.id WHERE (t.id = ?) LIMIT ? ``` -------------------------------- ### Manual SET Clauses with updateJoin Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/updateJoin.md Demonstrates how to manually set fields for both the primary and joined tables using the updateJoin method. The 'entity' parameter can be null when all SET clauses are defined in the wrapper. ```java class MpJoinTest { @Resource private UserMapper userMapper; /** * 手动set条件 * 更新 user表name字段和address表address字段 */ @Test void update() { UpdateJoinWrapper update = JoinWrappers.update(User.class) .set(User::getName, "aaaaaa") .set(Address::getAddress, "bbbbb") .leftJoin(Address.class, Address::getUserId, User::getId) .eq(User::getId, 1); int i = userMapper.updateJoin(null, update); } ``` -------------------------------- ### Wrapper Join Delete (All Tables) Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/api/deleteJoin.md Demonstrates deleting records from all joined tables, including the main table. The deleteAll() method is used to specify this behavior. Alternatively, specific tables can be targeted using the delete() method. ```java class MpJoinTest { @Resource private UserMapper userMapper; /** * wrapper连表删除(删除全部表) */ @Test void update() { DeleteJoinWrapper wrapper = JoinWrappers.delete(User.class) //删除全部的表数据 (主表和副表) .deleteAll() //也可以删除指定的表数据,调用 delete() 传要删除的实体类class 如下 //.delete(User.class, Address.class, Area.class) .leftJoin(Address.class, Address::getUserId, User::getId) .leftJoin(Area.class, Area::getId, Address::getAreaId) .eq(User::getId, 1); int i = userMapper.deleteJoin(wrapper); } } ``` ```log ==> Preparing: DELETE t,t1,t2 FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) LEFT JOIN area t2 ON (t2.id = t1.area_id) WHERE (t.id = ?) ==> Parameters: 1(Integer) <== Updates: 19 ``` -------------------------------- ### Implement JoinCrudRepository for User Repository (Optional) Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/quickstart/install.md Optionally, implement JoinCrudRepository for your User repository. This provides enhanced CRUD operations with join capabilities and requires MPJ 1.5.2+ and MP 3.5.9+. ```java @Repository public class UserRepository extends JoinCrudRepository { } ``` -------------------------------- ### eq SubQuery Method Source: https://github.com/mybatis-plus-join/mybatis-plus-join.github.io/blob/main/docs/pages/core/other/sub-query.md Demonstrates the `eq` method for constructing subqueries. It supports a version with a condition flag to conditionally apply the subquery. ```APIDOC ## eq SubQuery Method ### Description This method is used to construct an equality condition within a subquery. It allows specifying the column, the main entity class for the subquery, and a wrapper to define the subquery's conditions. ### Method Signature ```java eq(SFunction colum, Class queryClass, Function wrapper) ``` ### Overloaded Method with Condition ```java eq(boolean condition, SFunction colum, Class queryClass, Function wrapper) ``` This overloaded version allows you to conditionally include the subquery based on the `condition` boolean parameter. If `condition` is `false`, the subquery will not be added. ```