Persistence Layer Interface
This article provides a detailed introduction to various methods of performing persistence operations with MyBatis-Plus, including insertion, update, deletion, query, and pagination. Through this article, you will learn how the various methods provided by MyBatis-Plus perform data operations and their corresponding SQL statements.
Service Interface
IService is a generic Service layer interface provided by MyBatis-Plus. It encapsulates common CRUD operations, including insertion, deletion, querying, and pagination. By extending the IService
interface, you can quickly implement basic database operations while maintaining code simplicity and maintainability.
The method naming in the IService
interface follows certain conventions, such as get
for single-row queries, remove
for deletion, list
for collection queries, and page
for paginated queries. This helps avoid confusion with Mapper layer methods.
save
// Insert a record (selective fields, strategy insertion)boolean save(T entity);// Batch insertboolean saveBatch(Collection<T> entityList);// Batch insertboolean saveBatch(Collection<T> entityList, int batchSize);
Function Description: Inserts records with strategic insertion based on the fields of the entity object.
Return Value: boolean, indicating whether the insertion operation was successful.
Parameter Description:
Type | Parameter Name | Description |
---|---|---|
T | entity | Entity object |
Collection<T> | entityList | Collection of entity objects |
int | batchSize | Batch size for insertion |
Example (save):
// Assume a User entity objectUser user = new User();user.setName("John Doe");user.setEmail("john.doe@example.com");boolean result = userService.save(user); // Call the save methodif (result) { System.out.println("User saved successfully.");} else { System.out.println("Failed to save user.");}
Generated SQL:
INSERT INTO user (name, email) VALUES ('John Doe', 'john.doe@example.com')
Example (saveBatch):
// Assume a list of User entity objectsList<User> users = Arrays.asList( new User("Alice", "alice@example.com"), new User("Bob", "bob@example.com"), new User("Charlie", "charlie@example.com"));// Batch insert with default batch sizeboolean result = userService.saveBatch(users); // Call the saveBatch method with default batch sizeif (result) { System.out.println("Users saved successfully.");} else { System.out.println("Failed to save users.");}
Generated SQL (assuming default batch size is 3):
INSERT INTO user (name, email) VALUES('Alice', 'alice@example.com'),('Bob', 'bob@example.com'),('Charlie', 'charlie@example.com')
Example (saveBatch with specified batch size):
// Assume a list of User entity objectsList<User> users = Arrays.asList( new User("David", "david@example.com"), new User("Eve", "eve@example.com"), new User("Frank", "frank@example.com"), new User("Grace", "grace@example.com"));// Batch insert with specified batch size of 2boolean result = userService.saveBatch(users, 2); // Call the saveBatch method with specified batch sizeif (result) { System.out.println("Users saved successfully.");} else { System.out.println("Failed to save users.");}
Generated SQL (with specified batch size of 2):
-- First batchINSERT INTO user (name, email) VALUES('David', 'david@example.com'),('Eve', 'eve@example.com')
-- Second batchINSERT INTO user (name, email) VALUES('Frank', 'frank@example.com'),('Grace', 'grace@example.com')
Through the above examples, we can see how the save series methods perform batch insert operations at the Service layer and their corresponding SQL statements. These methods greatly simplify the code for insertion operations and improve development efficiency.
saveOrUpdate
// Updates the record if the TableId annotated property value exists, otherwise inserts a new recordboolean saveOrUpdate(T entity);// Attempts to update based on updateWrapper, otherwise executes saveOrUpdate(T) methodboolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);// Batch update or insertboolean saveOrUpdateBatch(Collection<T> entityList);// Batch update or insertboolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
Function Description: Determines whether to update or insert a record based on the primary key ID of the entity object.
Return Value: boolean, indicating whether the insert or update operation was successful.
Parameter Description:
Type | Parameter | Description |
---|---|---|
T | entity | Entity object |
Wrapper<T> | updateWrapper | Entity object wrapper class UpdateWrapper |
Collection<T> | entityList | Collection of entity objects |
int | batchSize | Batch size for insertion |
Example (saveOrUpdate):
// Assume a User entity object where id is a property annotated with TableIdUser user = new User();user.setId(1);user.setName("John Doe");user.setEmail("john.doe@example.com");boolean result = userService.saveOrUpdate(user); // Call saveOrUpdate methodif (result) { System.out.println("User updated or saved successfully.");} else { System.out.println("Failed to update or save user.");}
Generated SQL (assuming a record with id 1 exists):
UPDATE user SET name = 'John Doe', email = 'john.doe@example.com' WHERE id = 1
Generated SQL (assuming a record with id 1 does not exist):
INSERT INTO user (id, name, email) VALUES (1, 'John Doe', 'john.doe@example.com')
Example (saveOrUpdateBatch):
// Assume a list of User entity objects, each with an id propertyList<User> users = Arrays.asList( new User(1, "Alice", "alice@example.com"), new User(2, "Bob", "bob@example.com"), new User(3, "Charlie", "charlie@example.com"));// Perform batch update or insert with default batch sizeboolean result = userService.saveOrUpdateBatch(users); // Call saveOrUpdateBatch method with default batch sizeif (result) { System.out.println("Users updated or saved successfully.");} else { System.out.println("Failed to update or save users.");}
Generated SQL (assuming records with id 1 and 2 exist, and id 3 does not):
UPDATE user SET name = 'Alice', email = 'alice@example.com' WHERE id = 1UPDATE user SET name = 'Bob', email = 'bob@example.com' WHERE id = 2INSERT INTO user (id, name, email) VALUES (3, 'Charlie', 'charlie@example.com')
Example (saveOrUpdateBatch with specified batch size):
// Assume a list of User entity objectsList<User> users = Arrays.asList( new User(4, "David", "david@example.com"), new User(5, "Eve", "eve@example.com"), new User(6, "Frank", "frank@example.com"));// Perform batch update or insert with a batch size of 2boolean result = userService.saveOrUpdateBatch(users, 2); // Call saveOrUpdateBatch method with specified batch sizeif (result) { System.out.println("Users updated or saved successfully.");} else { System.out.println("Failed to update or save users.");}
Generated SQL (assuming batch size is 2):
-- First batchUPDATE user SET name = 'David', email = 'david@example.com' WHERE id = 4UPDATE user SET name = 'Eve', email = 'eve@example.com' WHERE id = 5
-- Second batchINSERT INTO user (id, name, email) VALUES (6, 'Frank', 'frank@example.com')
Through the above examples, we can see how the saveOrUpdate series methods perform batch update or insert operations at the Service layer, along with their corresponding SQL statements. These methods provide efficient data operations, allowing updates or inserts based on different conditions.
remove
// Delete records based on conditions set by queryWrapperboolean remove(Wrapper<T> queryWrapper);// Delete by IDboolean removeById(Serializable id);// Delete records based on columnMap conditionsboolean removeByMap(Map<String, Object> columnMap);// Batch delete (by ID list)boolean removeByIds(Collection<? extends Serializable> idList);
Function Description: Deletes records that match the specified conditions.
Return Value: boolean, indicating whether the deletion was successful.
Parameter Description:
Type | Parameter | Description |
---|---|---|
Wrapper<T> | queryWrapper | Entity wrapper QueryWrapper |
Serializable | id | Primary key ID |
Map<String, Object> | columnMap | Table field map object |
Collection<? extends Serializable> | idList | Primary key ID list |
Example (remove):
// Assume a QueryWrapper object with deletion condition: name = 'John Doe'QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");boolean result = userService.remove(queryWrapper); // Call remove methodif (result) { System.out.println("Record deleted successfully.");} else { System.out.println("Failed to delete record.");}
Generated SQL:
DELETE FROM user WHERE name = 'John Doe'
Example (removeById):
// Assume deleting a user with ID = 1boolean result = userService.removeById(1); // Call removeById methodif (result) { System.out.println("User deleted successfully.");} else { System.out.println("Failed to delete user.");}
Generated SQL:
DELETE FROM user WHERE id = 1
Example (removeByMap):
// Assume a columnMap with deletion condition: age = 30Map<String, Object> columnMap = new HashMap<>();columnMap.put("age", 30);boolean result = userService.removeByMap(columnMap); // Call removeByMap methodif (result) { System.out.println("Records deleted successfully.");} else { System.out.println("Failed to delete records.");}
Generated SQL:
DELETE FROM user WHERE age = 30
Example (removeByIds):
// Assume a list of IDs for batch user deletionList<Integer> ids = Arrays.asList(1, 2, 3);boolean result = userService.removeByIds(ids); // Call removeByIds methodif (result) { System.out.println("Users deleted successfully.");} else { System.out.println("Failed to delete users.");}
Generated SQL:
DELETE FROM user WHERE id IN (1, 2, 3)
Through the above examples, we can see how the remove series methods perform deletion operations at the Service layer and their corresponding SQL statements. These methods provide flexible data manipulation approaches for performing deletions under various conditions.
update
// Update records based on UpdateWrapper conditions, sqlset needs to be setboolean update(Wrapper<T> updateWrapper);// Update records based on whereWrapper conditionsboolean update(T updateEntity, Wrapper<T> whereWrapper);// Update by IDboolean updateById(T entity);// Batch update by IDboolean updateBatchById(Collection<T> entityList);// Batch update by IDboolean updateBatchById(Collection<T> entityList, int batchSize);
Function Description: Updates records that meet specified conditions.
Return Value: boolean, indicating whether the update operation was successful.
Parameter Description:
Type | Param Name | Description |
---|---|---|
Wrapper<T> | updateWrapper | Entity object wrapper class UpdateWrapper |
T | entity | Entity object |
Collection<T> | entityList | Collection of entities |
int | batchSize | Batch size for update |
Example (Update using UpdateWrapper):
// Assume an UpdateWrapper object with update condition name = 'John Doe' and updating the email fieldUpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.eq("name", "John Doe").set("email", "john.doe@newdomain.com");boolean result = userService.update(updateWrapper); // Call update methodif (result) { System.out.println("Record updated successfully.");} else { System.out.println("Failed to update record.");}
Generated SQL:
UPDATE user SET email = 'john.doe@newdomain.com' WHERE name = 'John Doe'
Example (Update using WhereWrapper):
// Assume a User entity object setting the name field to update, and a whereWrapper with condition id = 1User updateEntity = new User();updateEntity.setName("Updated Name");QueryWrapper<User> whereWrapper = new QueryWrapper<>();whereWrapper.eq("id", 1);boolean result = userService.update(updateEntity, whereWrapper); // Call update methodif (result) { System.out.println("Record updated successfully.");} else { System.out.println("Failed to update record.");}
Generated SQL:
UPDATE user SET name = 'Updated Name' WHERE id = 1
Example (updateById):
// Assume a User entity object setting the email field to update by IDUser updateEntity = new User();updateEntity.setId(1);updateEntity.setEmail("updated.email@example.com");boolean result = userService.updateById(updateEntity); // Call updateById methodif (result) { System.out.println("Record updated successfully.");} else { System.out.println("Failed to update record.");}
Generated SQL:
UPDATE user SET email = 'updated.email@example.com' WHERE id = 1
Example (updateBatchById):
// Assume a list of User entity objects for batch updateList<User> users = Arrays.asList( new User(1, null, "new.email1@example.com"), new User(2, null, "new.email2@example.com"));boolean result = userService.updateBatchById(users); // Call updateBatchById method with default batch sizeif (result) { System.out.println("Records updated successfully.");} else { System.out.println("Failed to update records.");}
Generated SQL (assuming default batch size is 2):
UPDATE user SET email = 'new.email1@example.com' WHERE id = 1UPDATE user SET email = 'new.email2@example.com' WHERE id = 2
Example (updateBatchById with specified batch size):
// Assume a list of User entity objects for batch update with batch size 1List<User> users = Arrays.asList( new User(1, null, "new.email1@example.com"), new User(2, null, "new.email2@example.com"));boolean result = userService.updateBatchById(users, 1); // Call updateBatchById method with specified batch sizeif (result) { System.out.println("Records updated successfully.");} else { System.out.println("Failed to update records.");}
Generated SQL (assuming batch size is 1):
-- First batchUPDATE user SET email = 'new.email1@example.com' WHERE id = 1-- Second batchUPDATE user SET email = 'new.email2@example.com' WHERE id = 2
Through the above examples, we can see how the update
series methods perform update operations at the Service layer and their corresponding SQL statements. These methods provide flexible data manipulation approaches for performing updates under different conditions.
get
// Query by IDT getById(Serializable id);// Query one record based on Wrapper. If the result set contains multiple records, an exception will be thrown. To get a random record, add limit condition wrapper.last("LIMIT 1")T getOne(Wrapper<T> queryWrapper);// Query one record based on WrapperT getOne(Wrapper<T> queryWrapper, boolean throwEx);// Query one record based on WrapperMap<String, Object> getMap(Wrapper<T> queryWrapper);// Query one record based on Wrapper<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
Functionality: Query records that meet specified conditions.
Return Value: Query result, which may be an entity object, Map object, or other types.
Parameter Description:
Type | Param Name | Description |
---|---|---|
Serializable | id | Primary Key ID |
Wrapper<T> | queryWrapper | Entity object encapsulation class QueryWrapper |
boolean | throwEx | Whether to throw exception when multiple results exist |
T | entity | Entity object |
Function<? super Object, V> | mapper | Conversion function |
Example (getById):
// Assume querying a user with ID 1User user = userService.getById(1); // Call getById methodif (user != null) { System.out.println("User found: " + user);} else { System.out.println("User not found.");}
Generated SQL:
SELECT * FROM user WHERE id = 1
Example (getOne):
// Assume a QueryWrapper object with query condition name = 'John Doe'QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");User user = userService.getOne(queryWrapper); // Call getOne methodif (user != null) { System.out.println("User found: " + user);} else { System.out.println("User not found.");}
Generated SQL:
SELECT * FROM user WHERE name = 'John Doe'
Example (getOne without throwing exception):
// Assume a QueryWrapper object with query condition name = 'John Doe' and not throwing exceptionQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");User user = userService.getOne(queryWrapper, false); // Call getOne methodif (user != null) { System.out.println("User found: " + user);} else { System.out.println("User not found.");}
Generated SQL:
SELECT * FROM user WHERE name = 'John Doe'
Example (getMap):
// Assume a QueryWrapper object with query condition name = 'John Doe' and mapping result to MapQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");Map<String, Object> userMap = userService.getMap(queryWrapper); // Call getMap methodif (userMap != null) { System.out.println("User found: " + userMap);} else { System.out.println("User not found.");}
Generated SQL:
SELECT * FROM user WHERE name = 'John Doe'
Example (getObj):
// Assume a QueryWrapper object with query condition name = 'John Doe' and converting result to StringQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "John Doe");String userName = userService.getObj(queryWrapper, obj -> ((User) obj).getName()); // Call getObj methodif (userName != null) { System.out.println("User name found: " + userName);} else { System.out.println("User name not found.");}
Generated SQL:
SELECT * FROM user WHERE name = 'John Doe'
Through the above examples, we can see how the get
series methods perform query operations at the Service layer and their corresponding SQL statements. These methods provide flexible data querying approaches for different conditions.
list
// Query allList<T> list();// Query listList<T> list(Wrapper<T> queryWrapper);// Query (batch query by IDs)Collection<T> listByIds(Collection<? extends Serializable> idList);// Query (by columnMap conditions)Collection<T> listByMap(Map<String, Object> columnMap);// Query all as mapsList<Map<String, Object>> listMaps();// Query list as mapsList<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);// Query all recordsList<Object> listObjs();// Query all records<V> List<V> listObjs(Function<? super Object, V> mapper);// Query all records by Wrapper conditionsList<Object> listObjs(Wrapper<T> queryWrapper);// Query all records by Wrapper conditions<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
Functionality: Queries records that meet the specified conditions.
Return Value: Query results, which may be entity objects, Map objects, or other types.
Parameter Description:
Type | Parameter | Description |
---|---|---|
Wrapper<T> | queryWrapper | Entity object wrapper class QueryWrapper |
Collection<? extends Serializable> | idList | List of primary key IDs |
Map<String, Object> | columnMap | Table field map object |
Function<? super Object, V> | mapper | Conversion function |
Example (list):
// Query all usersList<User> users = userService.list(); // Call list methodfor (User user : users) { System.out.println("User: " + user);}
Generated SQL:
SELECT * FROM user
Example (list with QueryWrapper):
// Assume a QueryWrapper object with query condition age > 25QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<User> users = userService.list(queryWrapper); // Call list methodfor (User user : users) { System.out.println("User: " + user);}
Generated SQL:
SELECT * FROM user WHERE age > 25
Example (listByIds):
// Assume a list of IDs for batch querying usersList<Integer> ids = Arrays.asList(1, 2, 3);Collection<User> users = userService.listByIds(ids); // Call listByIds methodfor (User user : users) { System.out.println("User: " + user);}
Generated SQL:
SELECT * FROM user WHERE id IN (1, 2, 3)
Example (listByMap):
// Assume a columnMap with query condition age = 30Map<String, Object> columnMap = new HashMap<>();columnMap.put("age", 30);Collection<User> users = userService.listByMap(columnMap); // Call listByMap methodfor (User user : users) { System.out.println("User: " + user);}
Generated SQL:
SELECT * FROM user WHERE age = 30
Example (listMaps):
// Query all users and map results to MapList<Map<String, Object>> userMaps = userService.listMaps(); // Call listMaps methodfor (Map<String, Object> userMap : userMaps) { System.out.println("User Map: " + userMap);}
Generated SQL:
SELECT * FROM user
Example (listMaps with QueryWrapper):
// Assume a QueryWrapper object with query condition age > 25 and map results to MapQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<Map<String, Object>> userMaps = userService.listMaps(queryWrapper); // Call listMaps methodfor (Map<String, Object> userMap : userMaps) { System.out.println("User Map: " + userMap);}
Generated SQL:
SELECT * FROM user WHERE age > 25
Example (listObjs):
// Query all users and convert results to String listList<String> userNames = userService.listObjs(obj -> ((User) obj).getName()); // Call listObjs methodfor (String userName : userNames) { System.out.println("User Name: " + userName);}
Generated SQL:
SELECT * FROM user
Example (listObjs with QueryWrapper):
// Assume a QueryWrapper object with query condition age > 25 and convert results to String listQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<String> userNames = userService.listObjs(queryWrapper, obj -> ((User) obj).getName()); // Call listObjs methodfor (String userName : userNames) { System.out.println("User Name: " + userName);}
Generated SQL:
SELECT * FROM user WHERE age > 25
Through the above examples, we can see how the list
series methods perform query operations at the Service layer and their corresponding SQL statements. These methods provide flexible data querying approaches for different conditions.
page
// Unconditional pagination queryIPage<T> page(IPage<T> page);// Conditional pagination queryIPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);// Unconditional pagination queryIPage<Map<String, Object>> pageMaps(IPage<T> page);// Conditional pagination queryIPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
Function Description: Pagination query for records matching the conditions.
Return Value: Pagination query result, including the record list and total record count.
Parameter Description:
Type | Parameter | Description |
---|---|---|
IPage<T> | page | Pagination object |
Wrapper<T> | queryWrapper | Entity object encapsulation class QueryWrapper |
Example (page):
// Assume an unconditional pagination query, displaying 10 records per page, querying the 1st pageIPage<User> page = new Page<>(1, 10);IPage<User> userPage = userService.page(page); // Call the page methodList<User> userList = userPage.getRecords();long total = userPage.getTotal();System.out.println("Total users: " + total);for (User user : userList) { System.out.println("User: " + user);}
Generated SQL:
SELECT * FROM user LIMIT 10 OFFSET 0
Example (page QueryWrapper form):
// Assume a QueryWrapper object with the query condition age > 25, performing a conditional pagination queryIPage<User> page = new Page<>(1, 10);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);IPage<User> userPage = userService.page(page, queryWrapper); // Call the page methodList<User> userList = userPage.getRecords();long total = userPage.getTotal();System.out.println("Total users (age > 25): " + total);for (User user : userList) { System.out.println("User: " + user);}
Generated SQL:
SELECT * FROM user WHERE age > 25 LIMIT 10 OFFSET 0
Example (pageMaps):
// Assume an unconditional pagination query, mapping results to Map, displaying 10 records per page, querying the 1st pageIPage<Map<String, Object>> page = new Page<>(1, 10);IPage<Map<String, Object>> userPageMaps = userService.pageMaps(page); // Call the pageMaps methodList<Map<String, Object>> userMapList = userPageMaps.getRecords();long total = userPageMaps.getTotal();System.out.println("Total users: " + total);for (Map<String, Object> userMap : userMapList) { System.out.println("User Map: " + userMap);}
Generated SQL:
SELECT * FROM user LIMIT 10 OFFSET 0
Example (pageMaps QueryWrapper form):
// Assume a QueryWrapper object with the query condition age > 25, performing a conditional pagination query, mapping results to MapIPage<Map<String, Object>> page = new Page<>(1, 10);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);IPage<Map<String, Object>> userPageMaps = userService.pageMaps(page, queryWrapper); // Call the pageMaps methodList<Map<String, Object>> userMapList = userPageMaps.getRecords();long total = userPageMaps.getTotal();System.out.println("Total users (age > 25): " + total);for (Map<String, Object> userMap : userMapList) { System.out.println("User Map: " + userMap);}
Generated SQL:
SELECT * FROM user WHERE age > 25 LIMIT 10 OFFSET 0
Through the above examples, we can see how the page
series methods perform pagination queries at the Service layer and their corresponding SQL statements. These methods provide flexible data querying capabilities, allowing pagination queries under different conditions.
count
// Query total record countint count();// Query total record count based on Wrapper conditionsint count(Wrapper<T> queryWrapper);
// Starting from version 3.4.3.2, return type changed to long// Query total record countlong count();// Query total record count based on Wrapper conditionslong count(Wrapper<T> queryWrapper);
Function Description: Queries the total number of records that meet the specified conditions.
Return Value: The total count of records that match the conditions.
Parameter Description:
Type | Parameter | Description |
---|---|---|
Wrapper<T> | queryWrapper | Entity object wrapper class QueryWrapper |
Example (count):
// Query the total record count in the user tableint totalUsers = userService.count(); // Call count methodSystem.out.println("Total users: " + totalUsers);
Generated SQL:
SELECT COUNT(*) FROM user
Example (count with QueryWrapper):
// Assume a QueryWrapper object with condition age > 25, query total users meeting the conditionQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);int totalUsers = userService.count(queryWrapper); // Call count methodSystem.out.println("Total users (age > 25): " + totalUsers);
Generated SQL:
SELECT COUNT(*) FROM user WHERE age > 25
Through the above examples, we can see how the count
method performs record counting operations at the Service layer, along with their corresponding SQL statements. These methods provide flexible data counting approaches that can perform record counting based on different conditions.
Mapper Interface
BaseMapper is a universal Mapper interface provided by MyBatis-Plus, which encapsulates a series of common database operation methods, including CRUD (Create, Read, Update, Delete). By inheriting BaseMapper, developers can quickly perform database operations without writing cumbersome SQL statements.
insert
// Insert a recordint insert(T entity);
Function Description: Insert a record.
Return Value: int, indicating the number of affected rows, typically 1 for a successful insertion.
Parameter Description:
Type | Parameter | Description |
---|---|---|
T | entity | Entity object |
Example (insert):
User user = new User();user.setName("John Doe");user.setEmail("john.doe@example.com");int rows = userMapper.insert(user); // Call the insert methodif (rows > 0) { System.out.println("User inserted successfully.");} else { System.out.println("Failed to insert user.");}
Generated SQL:
INSERT INTO user (name, email) VALUES (?, ?)
From the above example, we can see how the insert
method performs insertion operations at the Mapper layer and its corresponding SQL statement. This method simplifies the implementation of insertion operations, eliminating the need for developers to manually write SQL statements.
delete
// Delete records based on entity conditionsint delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);// Batch delete by IDsint deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);// Delete by IDint deleteById(Serializable id);// Delete records based on columnMap conditionsint deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
Function Description: Deletes records that match the specified conditions.
Return Value: int, indicating the number of affected rows (typically 1 for successful deletion).
Parameter Description:
Type | Parameter | Description |
---|---|---|
Wrapper<T> | wrapper | Entity wrapper class (can be null) |
Collection<? extends Serializable> | idList | Primary key ID list (cannot be null/empty) |
Serializable | id | Primary key ID |
Map<String, Object> | columnMap | Table column map object |
Example (delete):
// Assume a QueryWrapper object with condition age > 25 to delete matching usersQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);int rows = userMapper.delete(queryWrapper); // Call delete methodif (rows > 0) { System.out.println("Users deleted successfully.");} else { System.out.println("No users deleted.");}
Generated SQL:
DELETE FROM user WHERE age > 25
Example (deleteBatchIds):
// Batch delete users with given ID listList<Integer> ids = Arrays.asList(1, 2, 3);int rows = userMapper.deleteBatchIds(ids); // Call deleteBatchIds methodif (rows > 0) { System.out.println("Users deleted successfully.");} else { System.out.println("No users deleted.");}
Generated SQL:
DELETE FROM user WHERE id IN (1, 2, 3)
Example (deleteById):
// Delete single user by IDint userId = 1;int rows = userMapper.deleteById(userId); // Call deleteById methodif (rows > 0) { System.out.println("User deleted successfully.");} else { System.out.println("No user deleted.");}
Generated SQL:
DELETE FROM user WHERE id = 1
Example (deleteByMap):
// Delete users matching columnMap condition (age = 30)Map<String, Object> columnMap = new HashMap<>();columnMap.put("age", 30);int rows = userMapper.deleteByMap(columnMap); // Call deleteByMap methodif (rows > 0) { System.out.println("Users deleted successfully.");} else { System.out.println("No users deleted.");}
Generated SQL:
DELETE FROM user WHERE age = 30
Through these examples, we can observe how the delete
series methods perform deletion operations at the Mapper layer and their corresponding SQL statements. These methods provide flexible data deletion approaches based on different conditions.
update
// Update records based on whereWrapper conditionsint update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);// Update by IDint updateById(@Param(Constants.ENTITY) T entity);
Function Description: Updates records that meet the specified conditions.
Return Value: int, representing the number of affected rows, typically 1 indicating a successful update.
Parameter Description:
Type | Param Name | Description |
---|---|---|
T | entity | Entity object (set condition values, can be null) |
Wrapper<T> | updateWrapper | Entity object wrapper class (can be null, where the entity inside generates WHERE clauses) |
Example (update):
// Assume an UpdateWrapper object with query condition age > 25, updating emails of matching usersUpdateWrapper<User> updateWrapper = new UpdateWrapper<>();updateWrapper.gt("age", 25);User updateUser = new User();updateUser.setEmail("new.email@example.com");int rows = userMapper.update(updateUser, updateWrapper); // Call update methodif (rows > 0) { System.out.println("Users updated successfully.");} else { System.out.println("No users updated.");}
Generated SQL:
UPDATE user SET email = ? WHERE age > 25
Example (updateById):
// Assume updating the email of user with ID 1User updateUser = new User();updateUser.setId(1);updateUser.setEmail("new.email@example.com");int rows = userMapper.updateById(updateUser); // Call updateById methodif (rows > 0) { System.out.println("User updated successfully.");} else { System.out.println("No user updated.");}
Generated SQL:
UPDATE user SET email = ? WHERE id = 1
Through the above examples, we can see how the update
series methods perform update operations at the Mapper layer and their corresponding SQL statements. These methods provide flexible data update approaches for different conditional operations.
select
// Query by IDT selectById(Serializable id);// Query a single record based on entity conditionsT selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// Batch query (by ID list)List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);// Query all records based on entity conditionsList<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// Query (based on columnMap conditions)List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);// Query all records based on Wrapper conditionsList<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// Query all records based on Wrapper conditions. Note: Only returns the value of the first fieldList<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// Query all records with pagination based on entity conditionsIPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// Query all records with pagination based on Wrapper conditionsIPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// Query total record count based on Wrapper conditionsInteger selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
Function Description: Query records that meet the specified conditions.
Return Value: Query results, which may be entity objects, Map objects, or other types.
Parameter Description:
Type | Param Name | Description |
---|---|---|
Serializable | id | Primary Key ID |
Wrapper<T> | queryWrapper | Entity encapsulation class (can be null) |
Collection<? extends Serializable> | idList | Primary Key ID list (cannot be null/empty) |
Map<String, Object> | columnMap | Table field map object |
IPage<T> | page | Pagination condition (can be RowBounds.DEFAULT) |
Example (selectById):
// Query a single user by IDint userId = 1;User user = userMapper.selectById(userId); // Call selectById methodSystem.out.println("User: " + user);
Generated SQL:
SELECT * FROM user WHERE id = 1
Example (selectOne):
// Assume a QueryWrapper object with condition age > 25, query one matching userQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);User user = userMapper.selectOne(queryWrapper); // Call selectOne methodSystem.out.println("User: " + user);
Generated SQL:
SELECT * FROM user WHERE age > 25
Example (selectBatchIds):
// Assume an ID list for batch queryList<Integer> ids = Arrays.asList(1, 2, 3);List<User> users = userMapper.selectBatchIds(ids); // Call selectBatchIds methodfor (User u : users) { System.out.println("User: " + u);}
Generated SQL:
SELECT * FROM user WHERE id IN (1, 2, 3)
Example (selectList):
// Assume a QueryWrapper object with condition age > 25, query all matching usersQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<User> users = userMapper.selectList(queryWrapper); // Call selectList methodfor (User u : users) { System.out.println("User: " + u);}
Generated SQL:
SELECT * FROM user WHERE age > 25
Example (selectByMap):
// Assume a columnMap with condition age > 30, query matching usersMap<String, Object> columnMap = new HashMap<>();columnMap.put("age", 30);List<User> users = userMapper.selectByMap(columnMap); // Call selectByMap methodfor (User u : users) { System.out.println("User: " + u);}
Generated SQL:
SELECT * FROM user WHERE age > 30
Example (selectMaps):
// Assume a QueryWrapper object with condition age > 25, query all matching users and map results to MapQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<Map<String, Object>> userMaps = userMapper.selectMaps(queryWrapper); // Call selectMaps methodfor (Map<String, Object> userMap : userMaps) { System.out.println("User Map: " + userMap);}
Generated SQL:
SELECT * FROM user WHERE age > 25
Example (selectObjs):
// Assume a QueryWrapper object with condition age > 25, query all matching users but only return the first field valueQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);List<Object> userIds = userMapper.selectObjs(queryWrapper); // Call selectObjs methodfor (Object userId : userIds) { System.out.println("User ID: " + userId);}
Generated SQL:
SELECT id FROM user WHERE age > 25
Example (selectPage):
// Pagination query: 10 records per page, page 1, condition age > 25IPage<User> page = new Page<>(1, 10);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);IPage<User> userPage = userMapper.selectPage(page, queryWrapper); // Call selectPage methodList<User> userList = userPage.getRecords();long total = userPage.getTotal();System.out.println("Total users (age > 25): " + total);for (User user : userList) { System.out.println("User: " + user);}
Generated SQL:
SELECT * FROM user WHERE age > 25 LIMIT 10 OFFSET 0
Example (selectMapsPage):
// Pagination query: 10 records per page, page 1, condition age > 25, map results to MapIPage<Map<String, Object>> = new Page<>(1, 10);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);IPage<Map<String, Object>> userPageMaps = userMapper.selectMapsPage(page, queryWrapper); // Call selectMapsPage methodList<Map<String, Object>> userMapList = userPageMaps.getRecords();long total = userPageMaps.getTotal();System.out.println("Total users (age > 25): " + total);for (Map<String, Object> userMap : userMapList) { System.out.println("User Map: " + userMap);}
Generated SQL:
SELECT * FROM user WHERE age > 25 LIMIT 10 OFFSET 0
Example (selectCount):
// Assume a QueryWrapper object with condition age > 25, query total record countQueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);Integer totalUsers = userMapper.selectCount(queryWrapper); // Call selectCount methodSystem.out.println("Total users (age > 25): " + totalUsers);
Generated SQL:
SELECT COUNT(*) FROM user WHERE age > 25
Through these examples, we can see how the select
series methods perform query operations at the Mapper layer and their corresponding SQL statements. These methods provide flexible data query approaches, including single-record queries, batch queries, conditional queries, pagination queries, etc., based on different conditions.
Mapper Layer Optional Components
Optional components are extension methods provided by MyBatis-Plus, located in the com.baomidou.mybatisplus.extension.injector.methods
package. These methods require the use of the SQL Injector to extend the functionality of the Mapper interface.
Before using these optional components, ensure that the SQL Injector has been properly configured. For more usage examples and detailed information, refer to the official samples and source code comments.
Optional Components Description
alwaysUpdateSomeColumnById
int alwaysUpdateSomeColumnById(T entity);
Source: alwaysUpdateSomeColumnById
Function: This method is used to forcibly update certain fields during an update operation, regardless of whether these fields have changed in the entity object. This is particularly useful in certain business scenarios, such as updating timestamp fields to ensure they are updated with every operation.
Use Case: When you need to update specific fields (e.g., update time, version number, etc.) every time a record is updated, even if these fields remain unchanged in the entity object.
insertBatchSomeColumn
int insertBatchSomeColumn(List<T> entityList);
Source: insertBatchSomeColumn
Function: This method is used for batch insertion of entity objects but only inserts specified fields within the entities. This is useful when you need to batch insert data but do not want to include all fields.
Use Case: When you need to batch insert data and only want to include specific fields from the entity objects, either to improve insertion efficiency or protect sensitive data.
logicDeleteByIdWithFill
int logicDeleteByIdWithFill(T entity);
Source: logicDeleteByIdWithFill
Function: This method is used for logical deletion of records while populating certain fields in the entity object. Logical deletion means the record is not physically removed from the database but is instead marked as deleted by updating a specific field (e.g., a deleted
field).
Use Case: When you need to implement logical deletion functionality and want certain fields (e.g., deletion time, deleter, etc.) in the entity object to be automatically populated during the deletion operation.
Usage Tips
- Before using these optional components, ensure that the SQL injector is properly configured in your project.
- These methods typically need to be explicitly declared in the Mapper interface so that MyBatis-Plus can recognize and generate the corresponding SQL statements.
- Each optional component has its specific use cases; choose the appropriate method based on business requirements.
- In practical use, you may need to combine annotations on entity objects (such as
@TableField
,@TableLogic
, etc.) to achieve more complex functionalities.
By utilizing these optional components, you can further extend the capabilities of MyBatis-Plus to meet more diverse business needs.
Chain
Chain is a fluent programming style provided by MyBatis-Plus, allowing developers to write database operation code in a more concise and intuitive way. Chain is divided into two main categories: query
and update
, used for query and update operations respectively. Each category further includes two styles: regular chain and lambda chain. The lambda chain provides type-safe query condition construction but does not support Kotlin.
Usage Steps
query
Provides chained query operations, allowing methods to be called consecutively to build query conditions.
// Chained query - standardQueryChainWrapper<T> query();// Chained query - lambda style. Note: Kotlin is not supportedLambdaQueryChainWrapper<T> lambdaQuery();
Example:
// Standard chained query examplequery().eq("name", "John").list(); // Query all records where name is "John"
// Lambda chained query examplelambdaQuery().eq(User::getAge, 30).one(); // Query a single record where age is 30
update
Provides chained update operations, allowing methods to be called consecutively to build update conditions.
// Chained update - standardUpdateChainWrapper<T> update();// Chained update - lambda style. Note: Kotlin is not supportedLambdaUpdateChainWrapper<T> lambdaUpdate();
Example:
// Standard chained update exampleupdate().set("status", "inactive").eq("name", "John").update(); // Update the status to "inactive" for records where name is "John"
// Lambda chained update exampleUser updateUser = new User();updateUser.setEmail("new.email@example.com");lambdaUpdate().set(User::getEmail, updateUser.getEmail()).eq(User::getId, 1).update(); // Update the email for the user with ID 1
Usage Tips
- Chained operations return instances of
QueryChainWrapper
orUpdateChainWrapper
, allowing developers to sequentially call methods to build query or update conditions. - Lambda-style chained operations provide type-safe query condition construction through method references like
Entity::getId
, avoiding hardcoded strings and improving code readability and safety. - When using chained operations, pay attention to the order of method calls—typically, conditions are set first, followed by query or update operations.
- Chained operations support various condition-building methods, such as
eq
,ne
,gt
,lt
,like
, etc. Choose the appropriate method based on actual needs. - The results returned by chained operations can be a single record, multiple records, total record count, etc., depending on the final method called.
By using Chain, developers can write database operation code more efficiently while maintaining clarity and maintainability.
ActiveRecord
The ActiveRecord pattern is a design pattern that allows entity classes to interact directly with the database, where the entity class serves as both the domain model and the data access object. In MyBatis-Plus, an entity class only needs to inherit the Model
class to gain powerful CRUD operation capabilities.
Usage Steps
Extend the Model Class
import com.baomidou.mybatisplus.extension.activerecord.Model;
public class User extends Model<User> { // Entity class field definitions... private Long id; private String name; private Integer age; // ... Other fields and getter/setter methods}
Invoke CRUD Methods
// Create a new user and insert into the databaseUser user = new User();user.setName("John Doe");user.setAge(30);boolean isInserted = user.insert(); // Return value indicates whether the operation succeeded
// Query all usersList<User> allUsers = user.selectAll();
// Update user information by IDuser.setId(1L);user.setName("Updated Name");boolean isUpdated = user.updateById(); // Return value indicates whether the operation succeeded
// Delete a user by IDboolean isDeleted = user.deleteById(); // Return value indicates whether the operation succeeded
Usage Tips
- In ActiveRecord mode, entity classes can directly call methods like
insert
,selectAll
,updateById
, anddeleteById
to perform database operations. - After an entity class inherits the
Model
class, it automatically gains a series of database operation methods, eliminating the need to manually write SQL statements. - The fields in the entity class must correspond to the columns in the database table, typically specified through annotations (e.g.,
@TableField
,@TableId
, etc.) to define the mapping between fields and columns. - For update or delete operations, it is usually necessary to first query the entity object, modify its properties, and then call the update or delete method.
- Insert and update operations typically return a boolean value indicating whether the operation was successful.
- Query operations return the corresponding query results, such as a single entity object or a list of entity objects.
By using the ActiveRecord pattern, developers can write database operation code more concisely while maintaining clarity and maintainability. This pattern is particularly suitable for simple CRUD operations, significantly reducing the need for repetitive code.
SimpleQuery
SimpleQuery is a utility class provided by MyBatis-Plus. It encapsulates the results of a selectList
query, allowing them to be processed in a Stream
-like manner, thereby simplifying API calls.
A notable feature of SimpleQuery is its peeks
parameter, which is a variable argument of type Consumer...
. This means you can chain multiple operations, and these operations will be executed sequentially when the query results are processed.
For usage examples of SimpleQuery, refer to the official test case.
Usage Steps
Import the SimpleQuery Utility Class
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;import com.baomidou.mybatisplus.core.toolkit.support.SimpleQuery;
Using SimpleQuery for Queries
// Assume there is a User entity class and its corresponding BaseMapperList<Long> ids = SimpleQuery.list( Wrappers.lambdaQuery(User.class), // Use the lambda query builder User::getId, // The field to extract, here it's the User's id System.out::println, // The first peek operation, printing each user user -> userNames.add(user.getName()) // The second peek operation, adding each user's name to the userNames list);
Usage Tips
- The SimpleQuery utility class provides a concise way to handle query results, allowing you to apply multiple operations on the query results, which are executed sequentially in the order they are added.
- When using SimpleQuery, you need to provide a query builder (e.g.,
Wrappers.lambdaQuery()
), a field for extracting results (e.g.,User::getId
), and one or morepeek
operations of theConsumer
type. - The
peek
operation can be used to perform any side-effect actions, such as logging, updating caches, sending notifications, etc., without affecting the query results themselves. - SimpleQuery returns a list containing all queried entity objects, which have already had all
peek
operations applied. - By using SimpleQuery, you can separate query logic from result processing logic, making the code clearer and easier to maintain.
By leveraging the SimpleQuery utility class, developers can handle query results more efficiently while maintaining code simplicity and readability. This utility is particularly suitable for scenarios requiring complex processing of query results.
Feature Details
keyMap
The keyMap
method of SimpleQuery provides a convenient way to query the database and encapsulate the results into a Map
, where a specific attribute of the entity serves as the key and the entity itself as the value. This method also supports performing additional side-effect operations during result processing, such as logging or cache updates.
Method Signature
// Query records from the table and encapsulate them as Map<attribute, entity>Map<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks);
// Query records from the table and encapsulate them as Map<attribute, entity>, with support for parallel streamsMap<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);
Parameter Description
Type | Parameter | Description |
---|---|---|
E | entity | The entity object type, representing the query result’s entity type. |
A | attribute | The entity attribute type, also the type of the key in the returned Map . |
LambdaQueryWrapper<E> | wrapper | A lambda-enabled condition builder for constructing query conditions. |
SFunction<E, A> | sFunction | A getter method reference for the entity attribute, used to determine the key value in the Map . |
boolean | isParallel | If set to true , the underlying query will use parallel streams, improving efficiency for large datasets. |
Consumer<E>… | peeks | A variable argument for specifying additional operations during result processing, such as logging or cache updates. |
Usage Example
// Assume a User entity class and its corresponding BaseMapperLambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getStatus, "active"); // Query users with status "active"
// Use keyMap to query and encapsulate resultsMap<String, User> userMap = SimpleQuery.keyMap( queryWrapper, // Query condition builder User::getUsername, // Use username as the key user -> System.out.println("Processing user: " + user.getUsername()) // Log the processed username);
// Iterate through resultsfor (Map.Entry<String, User> entry : userMap.entrySet()) { System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());}
Usage Tips
- The
keyMap
method is suitable for scenarios requiring quick entity lookup based on a specific attribute. - The
sFunction
parameter allows specifying any entity attribute as theMap
key, making result access more intuitive and efficient. - The
peeks
parameter enables additional side-effect operations during result processing, which do not affect the finalMap
result. - For large datasets, consider setting
isParallel
totrue
to enable parallel streams and improve query efficiency.
By using SimpleQuery’s keyMap
method, developers can handle query results more efficiently, encapsulate them into easy-to-use data structures, and perform additional side-effect operations, making the code more concise and flexible.
map
The map
method of SimpleQuery provides a convenient way to query the database and encapsulate the results into a Map
, where one entity attribute serves as the key and another as the value. This method also supports performing additional side-effect operations during result processing, such as logging or cache updates.
Method Signature
// Query records from the table and encapsulate them as Map<attribute, attribute>Map<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, Consumer<E>... peeks);
// Query records from the table and encapsulate them as Map<attribute, attribute>, with support for parallel streamsMap<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, boolean isParallel, Consumer<E>... peeks);
Parameter Description
Type | Parameter | Description |
---|---|---|
E | entity | The entity object type, representing the query result’s entity type. |
A | attribute | The entity attribute type, serving as the key type in the returned Map . |
P | attribute | The entity attribute type, serving as the value type in the returned Map . |
LambdaQueryWrapper<E> | wrapper | A lambda-enabled condition builder for constructing query conditions. |
SFunction<E, A> | keyFunc | A getter method reference for the entity attribute, used to determine the key value in the Map . |
SFunction<E, P> | valueFunc | A getter method reference for the entity attribute, used to determine the value in the Map . |
boolean | isParallel | If set to true , the underlying query will use parallel streams, improving efficiency for large datasets. |
Consumer<E>… | peeks | A variable argument for specifying additional operations during result processing, such as logging or cache updates. |
Usage Example
// Assume a User entity class and its corresponding BaseMapperLambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getStatus, "active"); // Query users with status "active"
// Use map to query and encapsulate resultsMap<String, Integer> userMap = SimpleQuery.map( queryWrapper, // Query condition builder User::getUsername, // Use username as the key User::getAge, // Use age as the value user -> System.out.println("Processing user: " + user.getUsername()) // Log the processed username);
// Iterate through resultsfor (Map.Entry<String, Integer> entry : userMap.entrySet()) { System.out.println("Username: " + entry.getKey() + ", Age: " + entry.getValue());}
Usage Tips
- The
map
method is suitable for scenarios requiring quick lookup of one attribute based on another. - The
keyFunc
andvalueFunc
parameters allow specifying any entity attributes as theMap
key and value, making result access more intuitive and efficient. - The
peeks
parameter enables additional side-effect operations during result processing, which do not affect the finalMap
result. - For large datasets, consider setting
isParallel
totrue
to enable parallel streams and improve query efficiency.
By using SimpleQuery’s map
method, developers can handle query results more efficiently, encapsulate them into easy-to-use data structures, and perform additional side-effect operations, making the code more concise and flexible.
group
The group
method of SimpleQuery provides a convenient way to query the database and group the results by a specific entity attribute, encapsulating them into a Map
. This method also supports performing additional side-effect operations during result processing, such as logging or cache updates. Additionally, it allows further processing of grouped collections using a Collector
.
Method Signature
// Query records from the table and encapsulate them as Map<attribute, List<entity>>Map<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Consumer<T>... peeks);
// Query records from the table and encapsulate them as Map<attribute, List<entity>>, with support for parallel streamsMap<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, boolean isParallel, Consumer<T>... peeks);
// Query records from the table and encapsulate them as Map<attribute, downstream collector for grouped collections>M group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, Consumer<T>... peeks);
// Query records from the table and encapsulate them as Map<attribute, downstream collector for grouped collections>, with support for parallel streamsM group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, boolean isParallel, Consumer<T>... peeks);
Parameter Description
Type | Parameter | Description |
---|---|---|
T | entity | The entity object type, representing the query result’s entity type. |
K | attribute | The entity attribute type, serving as the key type in the returned Map . |
D | - | The downstream collector’s return type, serving as the value type in the Map . |
A | - | The intermediate type for downstream operations, used for Collector intermediate results. |
M | - | The final return type, Map<K, D> . |
LambdaQueryWrapper<T> | wrapper | A lambda-enabled condition builder for constructing query conditions. |
SFunction<T, K> | sFunction | The grouping criterion, a getter method reference for the entity attribute, used to determine the key value in the Map . |
Collector<T, A, D> | downstream | A downstream collector for further processing of grouped collections. |
boolean | isParallel | If set to true , the underlying query will use parallel streams, improving efficiency for large datasets. |
Consumer<T>… | peeks | A variable argument for specifying additional operations during result processing, such as logging or cache updates. |
Usage Example
// Assume a User entity class and its corresponding BaseMapperLambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getStatus, "active"); // Query users with status "active"
// Use group to query and encapsulate results, grouped by usernameMap<String, List<User>> userGroup = SimpleQuery.group( queryWrapper, // Query condition builder User::getUsername, // Use username as the grouping key user -> System.out.println("Processing user: " + user.getUsername()) // Log the processed username);
// Iterate through resultsfor (Map.Entry<String, List<User>> entry : userGroup.entrySet()) { System.out.println("Username: " + entry.getKey()); for (User user : entry.getValue()) { System.out.println(" - User: " + user); }}
Usage Tips
- The
group
method is suitable for scenarios requiring grouping of query results by a specific attribute. - The
sFunction
parameter allows specifying any entity attribute as the grouping criterion, making result organization more flexible. - The
downstream
parameter enables further processing of grouped collections using aCollector
, such as counting, summing, or averaging. - The
peeks
parameter enables additional side-effect operations during result processing, which do not affect the finalMap
result. - For large datasets, consider setting
isParallel
totrue
to enable parallel streams and improve query efficiency.
By using SimpleQuery’s group
method, developers can handle query results more efficiently, group them by specific attributes, and perform additional side-effect operations, making the code more concise and flexible.
list
The list
method of SimpleQuery provides a convenient way to query the database and encapsulate the results into a List
, where the elements are specific attributes of the entities. This method also supports performing additional side-effect operations during result processing, such as logging or cache updates.
Method Signature
// Query records from the table and encapsulate them as List<attribute>List<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks);
// Query records from the table and encapsulate them as List<attribute>, with support for parallel streamsList<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);
Parameter Description
Type | Parameter | Description |
---|---|---|
E | entity | The entity object type, representing the query result’s entity type. |
A | attribute | The entity attribute type, serving as the element type in the returned List . |
LambdaQueryWrapper<E> | wrapper | A lambda-enabled condition builder for constructing query conditions. |
SFunction<E, A> | sFunction | A getter method reference for the entity attribute, used to determine the element value in the List . |
boolean | isParallel | If set to true , the underlying query will use parallel streams, improving efficiency for large datasets. |
Consumer<E>… | peeks | A variable argument for specifying additional operations during result processing, such as logging or cache updates. |
Usage Example
// Assume a User entity class and its corresponding BaseMapperLambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getStatus, "active"); // Query users with status "active"
// Use list to query and encapsulate results, extracting all usernamesList<String> userNames = SimpleQuery.list( queryWrapper, // Query condition builder User::getUsername, // Extract usernames as list elements user -> System.out.println("Processing user: " + user.getUsername()) // Log the processed username);
// Iterate through resultsfor (String username : userNames) { System.out.println("Username: " + username);}
Usage Tips
- The
list
method is suitable for scenarios requiring quick extraction of a list of specific attributes. - The
sFunction
parameter allows specifying any entity attribute as theList
element, making result access more intuitive and efficient. - The
peeks
parameter enables additional side-effect operations during result processing, which do not affect the finalList
result. - For large datasets, consider setting
isParallel
totrue
to enable parallel streams and improve query efficiency.
By using SimpleQuery’s list
method, developers can handle query results more efficiently, encapsulate them into easy-to-use data structures, and perform additional side-effect operations, making the code more concise and flexible.
Db Kit
Db Kit is a utility class provided by MyBatis-Plus, enabling developers to perform CRUD operations through static method calls. This avoids potential circular dependency issues with Service injection in Spring environments, simplifies code, and improves development efficiency.
For the complete usage of Db Kit, refer to the official test case.
Usage Example
// Assume there is a User entity class and corresponding BaseMapper
// Query a single entity by idUser user = Db.getById(1L, User.class);
// Query multiple entities by idsList<User> userList = Db.listByIds(Arrays.asList(1L, 2L, 3L), User.class);
// Query using condition constructorLambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(User.class) .eq(User::getStatus, "active");List<User> activeUsers = Db.list(queryWrapper);
// Insert a new entityUser newUser = new User();newUser.setUsername("newUser");newUser.setAge(25);boolean isInserted = Db.insert(newUser);
// Update an entity by idUser updateUser = new User();updateUser.setId(1L);updateUser.setUsername("updatedUser");boolean isUpdated = Db.updateById(updateUser);
// Update using condition constructorLambdaUpdateWrapper<User> updateWrapper = Wrappers.lambdaUpdate(User.class) .set(User::getAge, 30) .eq(User::getUsername, "updatedUser");boolean isUpdatedByWrapper = Db.update(null, updateWrapper);
// Delete an entity by idboolean isDeleted = Db.removeById(1L);
// Delete using condition constructorLambdaDeleteWrapper<User> deleteWrapper = Wrappers.lambdaDelete(User.class) .eq(User::getStatus, "inactive");boolean isDeletedByWrapper = Db.remove(deleteWrapper);
// Batch insertList<User> batchUsers = Arrays.asList( new User("user1", 20), new User("user2", 22), new User("user3", 24));boolean isBatchInserted = Db.saveBatch(batchUsers);
// Batch updateList<User> batchUpdateUsers = Arrays.asList( new User(1L, "user1", 21), new User(2L, "user2", 23), new User(3L, "user3", 25));boolean isBatchUpdated = Db.updateBatchById(batchUpdateUsers);
Usage Tips
- Db Kit provides a series of static methods that can be directly called for database operations without going through the Service layer, simplifying the code structure.
- When using Db Kit, ensure the parameters passed are correct, especially when using Wrapper, where the entity class or entity object must be specified.
- For batch operations, such as batch inserts or updates, it is recommended to use the batch methods provided by Db Kit to improve efficiency.
- Avoid frequently calling Db Kit methods in loops, as this may lead to performance issues.
By using Db Kit, developers can perform database operations more efficiently while maintaining code simplicity and readability. This utility class is particularly suitable for simple CRUD operations, significantly reducing the need for repetitive code.