Persistence Layer Interface
This document provides a comprehensive overview of various persistence operations using MyBatis-Plus, including insertion, update, deletion, query, and pagination. Through this guide, you will learn how the different methods provided by MyBatis-Plus perform data operations and see the corresponding SQL statements they generate.
Service Interface
IService is a generic Service layer interface provided by MyBatis-Plus that encapsulates common CRUD operations, including insert, delete, query, 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 specific conventions: get
for single-row queries, remove
for deletion, list
for collection queries, and page
for paginated queries. This naming pattern helps avoid confusion with Mapper layer methods.
save
// 插入一条记录(选择字段,策略插入)boolean save(T entity);// 插入(批量)boolean saveBatch(Collection<T> entityList);// 插入(批量)boolean saveBatch(Collection<T> entityList, int batchSize);
Function Description: Inserts records using strategic insertion based on the entity object’s fields.
Return Value: boolean, indicating whether the insert operation was successful.
Parameter Description:
Type | Parameter | Description |
---|---|---|
T | entity | Entity object |
Collection<T> | entityList | Entity object collection |
int | batchSize | Insert batch size |
Example (save):
// Assume we have 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 we have a collection 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"));// Perform batch insert using default batch sizeboolean result = userService.saveBatch(users); // Call 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 we have a collection 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"));// Perform batch insert with specified batch size of 2boolean result = userService.saveBatch(users, 2); // Call 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 examples above, you can see how the save series methods perform batch insert operations at the Service layer, along with their corresponding SQL statements. These methods significantly simplify insert operation code and improve development efficiency.
saveOrUpdate
// TableId 注解属性值存在则更新记录,否插入一条记录boolean saveOrUpdate(T entity);// 批量修改插入boolean saveOrUpdateBatch(Collection<T> entityList);// 批量修改插入boolean 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. If the record exists, it updates; otherwise, it inserts.
Return Value: boolean, indicating whether the insert or update operation was successful.
Parameter Description:
Type | Parameter Name | Description |
---|---|---|
T | entity | Entity object |
Wrapper<T> | updateWrapper | Entity object wrapper class UpdateWrapper |
Collection<T> | entityList | Collection of entity objects |
int | batchSize | Insert batch size |
Example (saveOrUpdate):
// Assume a User entity object where id is the 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 the 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 collection 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/insert using the 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 id=2 exist, and id=3 does not exist):
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 collection 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/insert with a specified 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 a batch size of 2 is specified):
-- 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 examples above, you can see how the saveOrUpdate series methods perform batch update and insert operations at the Service layer, along with their corresponding SQL statements. These methods provide efficient data operations, allowing you to update or insert records based on different conditions.
remove
// 根据 queryWrapper 设置的条件,删除记录boolean remove(Wrapper<T> queryWrapper);// 根据 ID 删除boolean removeById(Serializable id);// 根据 columnMap 条件,删除记录boolean removeByMap(Map<String, Object> columnMap);// 删除(根据ID 批量删除)boolean removeByIds(Collection<? extends Serializable> idList);
Function Description: Deletes records that match the specified conditions.
Return Value: boolean, indicating whether the delete operation was successful.
Parameter Description:
Type | Parameter | Description |
---|---|---|
Wrapper<T> | queryWrapper | Entity wrapper QueryWrapper |
Serializable | id | Primary Key ID |
Map<String, Object> | columnMap | Table column map object |
Collection<? extends Serializable> | idList | Primary Key ID list |
Example (remove):
// Assume a QueryWrapper object with delete condition set to 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 you want to delete the 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 delete condition set to 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 examples above, you can see how the remove series methods perform delete operations at the Service layer and their corresponding SQL statements. These methods provide flexible data manipulation capabilities, allowing you to perform delete operations based on different conditions.
update
// 根据 UpdateWrapper 条件,更新记录 需要设置sqlsetboolean update(Wrapper<T> updateWrapper);// 根据 whereWrapper 条件,更新记录boolean update(T updateEntity, Wrapper<T> whereWrapper);// 根据 ID 选择修改boolean updateById(T entity);// 根据ID 批量更新boolean updateBatchById(Collection<T> entityList);// 根据ID 批量更新boolean updateBatchById(Collection<T> entityList, int batchSize);
Description: Updates records that match the specified conditions.
Return Value: boolean, indicating whether the update operation was successful.
Parameter Description:
Type | Parameter | Description |
---|---|---|
Wrapper<T> | updateWrapper | Entity object wrapper class UpdateWrapper |
T | entity | Entity object |
Collection<T> | entityList | Entity object collection |
int | batchSize | Batch update size |
Example (update with UpdateWrapper):
// Assume an UpdateWrapper object with update condition name = 'John Doe' and update field emailUpdateWrapper<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 with WhereWrapper):
// Assume a User entity object with updated name field, and a whereWrapper with update 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 with updated email field, updating 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 collection 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 of 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 collection of User entity objects for batch update with specified batch size of 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 (with specified batch size of 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 examples above, you can see how the update
series methods perform update operations in the Service layer and their corresponding SQL statements. These methods provide flexible data manipulation approaches for performing updates based on different conditions.
get
// 根据 ID 查询T getById(Serializable id);// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")T getOne(Wrapper<T> queryWrapper);// 根据 Wrapper,查询一条记录T getOne(Wrapper<T> queryWrapper, boolean throwEx);// 根据 Wrapper,查询一条记录Map<String, Object> getMap(Wrapper<T> queryWrapper);// 根据 Wrapper,查询一条记录<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
Function Description: Query records that match the specified conditions.
Return Value: The query result, which may be an entity object, Map object, or other type.
Parameter Description:
Type | Parameter | Description |
---|---|---|
Serializable | id | Primary key ID |
Wrapper<T> | queryWrapper | Entity object wrapper class QueryWrapper |
boolean | throwEx | Whether to throw exception when multiple results found |
T | entity | Entity object |
Function<? super Object, V> | mapper | Conversion function |
Example (getById):
// Assume you want to query 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', without 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', 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', 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 examples above, you can see how the get
series methods perform query operations in the Service layer and their corresponding SQL statements. These methods provide flexible data querying approaches that allow you to query data based on different conditions.
list
// Query allList<T> list();// Query listList<T> list(Wrapper<T> queryWrapper);// Query (batch query by ID)Collection<T> listByIds(Collection<? extends Serializable> idList);// Query (by columnMap condition)Collection<T> listByMap(Map<String, Object> columnMap);// Query all listsList<Map<String, Object>> listMaps();// Query listList<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 conditionList<Object> listObjs(Wrapper<T> queryWrapper);// Query all records by Wrapper condition<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
Function Description: Queries records that match 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 | Primary key ID list |
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 an ID list for batch user queryList<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 examples above, you 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 that allow you to query data based on different conditions.
page
// 无条件分页查询IPage<T> page(IPage<T> page);// 条件分页查询IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);// 无条件分页查询IPage<Map<String, Object>> pageMaps(IPage<T> page);// 条件分页查询IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
Function: Performs paginated queries for records that match the specified conditions.
Return Value: Paginated query results, including the record list and total record count.
Parameters:
Type | Name | Description |
---|---|---|
IPage<T> | page | Pagination object |
Wrapper<T> | queryWrapper | Entity wrapper class QueryWrapper |
Example (page):
// Unconditional paginated query, showing 10 records per page, querying page 1IPage<User> page = new Page<>(1, 10);IPage<User> userPage = userService.page(page); // Call 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 with QueryWrapper):
// Conditional paginated query with QueryWrapper, setting condition age > 25IPage<User> page = new Page<>(1, 10);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 25);IPage<User> userPage = userService.page(page, queryWrapper); // Call 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):
// Unconditional paginated query with results mapped to Map, 10 records per page, querying page 1IPage<Map<String, Object>> page = new Page<>(1, 10);IPage<Map<String, Object>> userPageMaps = userService.pageMaps(page); // Call 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 with QueryWrapper):
// Conditional paginated query with QueryWrapper (age > 25), results mapped 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 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
These examples demonstrate how the page
series methods perform paginated queries at the Service layer and their corresponding SQL statements. These methods provide flexible data querying options for paginated queries with 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 value 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 match the specified conditions.
Return Value: The total number of records that match the conditions.
Parameter Description:
Type | Parameter | Description |
---|---|---|
Wrapper<T> | queryWrapper | Entity object wrapper class QueryWrapper |
Example (count):
// Query the total number of records 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 that meet 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 examples above, you 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 capabilities that allow you to count records based on different conditions.
Mapper Interface
BaseMapper is a universal Mapper interface provided by MyBatis-Plus that encapsulates a series of common database operations, including CRUD (Create, Read, Update, Delete) methods. By extending BaseMapper, you can quickly perform database operations without writing verbose SQL statements.
insert
// Insert a recordint insert(T entity);
Description: Inserts a record.
Return Value: int, representing the number of rows affected by the insert operation, typically 1 indicating 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 (?, ?)
This example demonstrates how the insert
method performs insertion operations at the Mapper layer and shows its corresponding SQL statement. This method simplifies the implementation of insert operations, allowing you to avoid writing SQL statements manually.
delete
// 根据 entity 条件,删除记录int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);// 删除(根据ID 批量删除)int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);// 根据 ID 删除int deleteById(Serializable id);// 根据 columnMap 条件,删除记录int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
Function Description: Deletes records that match the specified conditions.
Return Value: int, representing the number of rows affected by the delete operation, typically 1 to indicate 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 or empty) |
Serializable | id | Primary key ID |
Map<String, Object> | columnMap | Table column map object |
Example (delete):
// Assume you have a QueryWrapper object with conditions set to age > 25, delete users that matchQueryWrapper<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):
// Assume you have a list of IDs, delete users in batchList<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 a 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):
// Assume you have a columnMap with conditions set to age = 30, delete users that matchMap<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 the examples above, you can see how the delete
series methods perform delete operations at the Mapper layer and their corresponding SQL statements. These methods provide flexible ways to delete data based on different conditions.
update
// 根据 whereWrapper 条件,更新记录int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);// 根据 ID 修改int updateById(@Param(Constants.ENTITY) T entity);
Function Description: Updates records that match the specified conditions.
Return Value: int, representing the number of rows affected by the update operation, typically 1 to indicate successful update.
Parameter Description:
Type | Parameter | Description |
---|---|---|
T | entity | Entity object (sets condition values, can be null) |
Wrapper<T> | updateWrapper | Entity object wrapper class (can be null, the entity inside is used to generate the WHERE clause) |
Example (update):
// Assume you have an UpdateWrapper object that sets the query condition to age > 25, updating the email for users that meet the conditionUpdateWrapper<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 the 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 you want to update the email for the user with ID 1User updateUser = new User();updateUser.setId(1);updateUser.setEmail("new.email@example.com");int rows = userMapper.updateById(updateUser); // Call the 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 examples above, you can see how the update
series methods perform update operations at the Mapper layer, along with their corresponding SQL statements. These methods provide flexible ways to update data based on different conditions.
select
// 根据 ID 查询T selectById(Serializable id);// 根据 entity 条件,查询一条记录T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);// 根据 entity 条件,查询全部记录List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 查询(根据 columnMap 条件)List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);// 根据 Wrapper 条件,查询全部记录List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 entity 条件,查询全部记录(并翻页)IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录(并翻页)IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询总记录数Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
Function Description: Query records that match the specified conditions.
Return Value: Query results, which may be entity objects, Map objects, or other types.
Parameter Description:
Type | Parameter | Description |
---|---|---|
Serializable | id | Primary key ID |
Wrapper<T> | queryWrapper | Entity wrapper (can be null) |
Collection<? extends Serializable> | idList | Primary key ID list (cannot be null or empty) |
Map<String, Object> | columnMap | Table column 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 we have a QueryWrapper object with condition age > 25, query one user that matchesQueryWrapper<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 we have a list of IDs, query users in batchList<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 we have a QueryWrapper object with condition age > 25, query all users that matchQueryWrapper<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 we have a columnMap with condition age > 30, query users that matchMap<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 we have 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 we have a QueryWrapper object with condition age > 25, query all matching users but only return the first field value of each recordQueryWrapper<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):
// Assume we want to perform paginated query, 10 records per page, query page 1, with 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):
// Assume we want to perform paginated query, 10 records per page, query page 1, with condition age > 25, and map 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 = 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 we have 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 the examples above, you can see how the select
series methods perform query operations at the Mapper layer and their corresponding SQL statements. These methods provide flexible data querying capabilities, allowing you to query data based on different conditions, including single record queries, batch queries, conditional queries, paginated queries, and more.
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 need to be used with the SQL injector to extend the functionality of your Mapper interface.
Before using these optional components, you need to ensure that the SQL injector is properly configured. For more usage examples and detailed information, you can refer to the official examples and source code comments.
Optional Components Description
alwaysUpdateSomeColumnById
int alwaysUpdateSomeColumnById(T entity);
Source: alwaysUpdateSomeColumnById
Function: This method forces updates to specific fields during update operations, regardless of whether those 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: Use this when you need to update specific fields (like update time, version number, etc.) every time you update a record, even if those fields haven’t changed in the entity object.
insertBatchSomeColumn
int insertBatchSomeColumn(List<T> entityList);
Source: insertBatchSomeColumn
Function: This method performs batch insertion of entity objects, but only inserts specified fields from the entities. This is useful when you need to insert data in batches but don’t want to insert all fields.
Use Case: Use this when you need to batch insert data and only want to insert 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 performs logical deletion of records and populates specific fields in the entity object. Logical deletion means records aren’t actually removed from the database, but are marked as deleted by updating a specific field (such as a deleted
field).
Use Case: Use this when you need to implement logical deletion functionality and want to automatically populate specific fields in the entity object (like deletion time, deleted by user, etc.) during the deletion operation.
Usage Tips
- Before using these optional components, ensure that your project has the SQL injector properly configured.
- These methods typically need to be explicitly declared in your Mapper interface so MyBatis-Plus can recognize them and generate the corresponding SQL statements.
- Each optional component has its specific use case; choose the appropriate method based on your business requirements.
- In practice, you may need to combine these with annotations on your entity objects (such as
@TableField
,@TableLogic
, etc.) to implement more complex functionality.
By using these optional components, you can further extend MyBatis-Plus’s capabilities to meet more diverse business needs.
Chain
Chain is a chain programming style provided by MyBatis-Plus that allows you 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 is further divided into regular chain style and lambda chain style. The lambda chain style provides type-safe query condition construction but does not support Kotlin.
Usage Steps
query
Provides chain-style query operations, allowing you to chain method calls to build query conditions.
// Chain-style query (standard)QueryChainWrapper<T> query();// Chain-style query (lambda). Note: Kotlin is not supportedLambdaQueryChainWrapper<T> lambdaQuery();
Example:
// Standard chain-style query examplequery().eq("name", "John").list(); // Query all records where name equals "John"
// Lambda chain-style query examplelambdaQuery().eq(User::getAge, 30).one(); // Query a single record where age equals 30
update
Provides chain-style update operations, allowing you to chain method calls to build update conditions.
// Chain-style update (standard)UpdateChainWrapper<T> update();// Chain-style update (lambda). Note: Kotlin is not supportedLambdaUpdateChainWrapper<T> lambdaUpdate();
Example:
// Standard chain-style update exampleupdate().set("status", "inactive").eq("name", "John").update(); // Update the status to "inactive" for records where name equals "John"
// Lambda chain-style 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 you to call methods consecutively to build query or update conditions. - Lambda chained operations provide type-safe query condition construction. By using method references like
Entity::getId
, you avoid hard-coded strings, improving code readability and safety. - When using chained operations, pay attention to the calling order of the methods. Typically, you set conditions first and then execute the query or update operation.
- Chained operations support various condition construction methods such as
eq
,ne
,gt
,lt
,like
, etc. You can choose the appropriate method based on your actual needs. - The result returned by a chained operation can be a single record, multiple records, total record count, etc., depending on the final method called.
By using Chain, you can write database operation code more efficiently while maintaining code clarity and maintainability.
ActiveRecord
The ActiveRecord pattern is a design pattern that allows entity classes to interact directly with the database. In this pattern, entity classes serve as both domain models and data access objects. In MyBatis-Plus, your entity classes can gain powerful CRUD operation capabilities simply by extending the Model
class.
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}
Call 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 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 from the
Model
class, it automatically gains a series of database operation methods, eliminating the need to write SQL statements manually. - Fields in the entity class must correspond to columns in the database table. You typically specify the mapping between fields and columns using annotations like
@TableField
and@TableId
. - When performing update or delete operations, you usually need to query the entity object first, 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, you can write database operation code more concisely while maintaining code clarity and maintainability. This pattern is particularly suitable for simple CRUD operations and can significantly reduce repetitive code.
SimpleQuery
SimpleQuery is a utility class provided by MyBatis-Plus that wraps the results of selectList
queries, allowing you to process them using Stream
operations, which simplifies API calls.
One notable feature of SimpleQuery is its peeks
parameter, which is a variable argument of type Consumer...
. This means you can chain multiple operations that will execute sequentially when the query results are processed.
For usage examples of SimpleQuery, refer to the official test cases.
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;
Use SimpleQuery for Queries
// Assume you have a User entity class and corresponding BaseMapperList<Long> ids = SimpleQuery.list( Wrappers.lambdaQuery(User.class), // Use the lambda query wrapper User::getId, // The field to extract, in this case the User's id System.out::println, // First peek operation, prints each user user -> userNames.add(user.getName()) // Second peek operation, adds 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 to the query results that will execute sequentially in the order they were added.
- When using SimpleQuery, you need to provide a query builder (such as
Wrappers.lambdaQuery()
), a field for extracting results (such asUser::getId
), and one or morepeek
operations of typeConsumer
. - The
peek
operation can be used to perform any side-effect operations, such as printing logs, updating caches, or sending notifications, without affecting the query results themselves. - SimpleQuery returns a list containing all queried entity objects, with all
peek
operations already applied to them. - By using SimpleQuery, you can separate query and result processing logic, making your code clearer and easier to maintain.
By using the SimpleQuery utility class, developers can handle query results more efficiently while maintaining code simplicity and readability. This utility class is particularly suitable for scenarios that require complex processing of query results.
Feature Details
keyMap
The keyMap
method in SimpleQuery provides a convenient way to query the database and encapsulate the results into a Map
, where a specific entity property serves as the key and the entity itself serves as the value. This method also supports performing additional side-effect operations during result processing, such as logging or cache updates.
Method Signature
// Queries table records and returns them as Map<Property, Entity>Map<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks);
// Queries table records and returns them as Map<Property, Entity>, with parallel stream supportMap<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);
Parameter Description
Type | Parameter Name | Description |
---|---|---|
E | entity | The entity object type, representing the type of the query result entity. |
A | attribute | The entity attribute type, which is also the type of the key in the returned Map . |
LambdaQueryWrapper<E> | wrapper | A lambda-enabled condition constructor for building query conditions. |
SFunction<E, A> | sFunction | A getter method reference for the entity property, used to determine the value for the Map key. |
boolean | isParallel | If set to true , uses a parallel stream for execution, which can improve efficiency when processing large datasets. |
Consumer<E>… | peeks | A variable argument parameter for specifying additional operations to perform during result processing, such as logging or cache updates. |
Usage Example
// Assume a User entity class and 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 constructor User::getUsername, // Use username as the key user -> System.out.println("Processing user: " + user.getUsername()) // Print 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 where you need to quickly look up entities based on a specific property. - Using the
sFunction
parameter, you can specify any entity property as theMap
key, making result access more intuitive and efficient. - The
peeks
parameter allows you to perform additional side-effect operations during result processing; these operations do not affect the finalMap
result. - When processing large datasets, consider setting the
isParallel
parameter 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, resulting in cleaner and more flexible code.
map
The map
method in SimpleQuery provides a convenient way to query the database and encapsulate the results into a Map
, where one entity property serves as the key and another property serves as the value. This method also supports performing additional side-effect operations during result processing, such as logging or cache updates.
Method Signature
// Queries table records and returns them as Map<Property, Property>Map<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, Consumer<E>... peeks);
// Queries table records and returns them as Map<Property, Property>, with parallel stream supportMap<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, boolean isParallel, Consumer<E>... peeks);
Parameter Description
Type | Parameter Name | Description |
---|---|---|
E | entity | The entity object type, representing the type of the query result entity. |
A | attribute | The entity attribute type used as the key type in the returned Map . |
P | attribute | The entity attribute type used as the value type in the returned Map . |
LambdaQueryWrapper<E> | wrapper | A lambda-enabled condition constructor for building query conditions. |
SFunction<E, A> | keyFunc | A getter method reference for the entity property, used to determine the value for the Map key. |
SFunction<E, P> | valueFunc | A getter method reference for the entity property, used to determine the value for the Map value. |
boolean | isParallel | If set to true , uses a parallel stream for execution, which can improve efficiency when processing large datasets. |
Consumer<E>… | peeks | A variable argument parameter for specifying additional operations to perform during result processing, such as logging or cache updates. |
Usage Example
// Assume a User entity class and 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 constructor User::getUsername, // Use username as the key User::getAge, // Use age as the value user -> System.out.println("Processing user: " + user.getUsername()) // Print 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 where you need to quickly look up one property value based on another property. - Using the
keyFunc
andvalueFunc
parameters, you can specify any entity properties as theMap
key and value, making result access more intuitive and efficient. - The
peeks
parameter allows you to perform additional side-effect operations during result processing; these operations do not affect the finalMap
result. - When processing large datasets, consider setting the
isParallel
parameter 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, resulting in cleaner and more flexible code.
group
The group
method in SimpleQuery provides a convenient way to query the database and group the results by a specific entity property, 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 you to use a Collector
for further processing of the grouped collections.
Method Signature
// Queries table records and returns them as Map<Property, List<Entity>>Map<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Consumer<T>... peeks);
// Queries table records and returns them as Map<Property, List<Entity>>, with parallel stream supportMap<K, List<T>> group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, boolean isParallel, Consumer<T>... peeks);
// Queries table records and returns them as Map<Property, Downstream Collector Result>M group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, Consumer<T>... peeks);
// Queries table records and returns them as Map<Property, Downstream Collector Result>, with parallel stream supportM group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, boolean isParallel, Consumer<T>... peeks);
Parameter Description
Type | Parameter Name | Description |
---|---|---|
T | entity | The entity object type, representing the type of the query result entity. |
K | attribute | The entity attribute type used as the key type in the returned Map . |
D | - | The downstream collector return type, used as the value type in the Map . |
A | - | The intermediate type for downstream operations, used for the Collector ’s intermediate results. |
M | - | The final return type Map<K, D> . |
LambdaQueryWrapper<T> | wrapper | A lambda-enabled condition constructor for building query conditions. |
SFunction<T, K> | sFunction | The grouping criteria, a getter method reference for the entity property, used to determine the value for the Map key. |
Collector<T, A, D> | downstream | A downstream collector for further processing of the grouped collections. |
boolean | isParallel | If set to true , uses a parallel stream for execution, which can improve efficiency when processing large datasets. |
Consumer<T>… | peeks | A variable argument parameter for specifying additional operations to perform during result processing, such as logging or cache updates. |
Usage Example
// Assume a User entity class and 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 constructor User::getUsername, // Use username as the grouping key user -> System.out.println("Processing user: " + user.getUsername()) // Print 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 where you need to group query results by a specific entity property. - Using the
sFunction
parameter, you can specify any entity property as the grouping criteria, making result organization more flexible. - The
downstream
parameter allows you to use aCollector
for further processing of grouped collections, such as counting, summing, or averaging. - The
peeks
parameter allows you to perform additional side-effect operations during result processing; these operations do not affect the finalMap
result. - When processing large datasets, consider setting the
isParallel
parameter 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 properties, and perform additional side-effect operations, resulting in cleaner and more flexible code.
list
The list
method in SimpleQuery provides a convenient way to query the database and encapsulate the results into a List
, where the list elements are specific entity properties. This method also supports performing additional side-effect operations during result processing, such as logging or cache updates.
Method Signature
// Queries table records and returns them as List<Property>List<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, Consumer<E>... peeks);
// Queries table records and returns them as List<Property>, with parallel stream supportList<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);
Parameter Description
Type | Parameter Name | Description |
---|---|---|
E | entity | The entity object type, representing the type of the query result entity. |
A | attribute | The entity attribute type used as the element type in the returned List . |
LambdaQueryWrapper<E> | wrapper | A lambda-enabled condition constructor for building query conditions. |
SFunction<E, A> | sFunction | A getter method reference for the entity property, used to determine the value for the List elements. |
boolean | isParallel | If set to true , uses a parallel stream for execution, which can improve efficiency when processing large datasets. |
Consumer<E>… | peeks | A variable argument parameter for specifying additional operations to perform during result processing, such as logging or cache updates. |
Usage Example
// Assume a User entity class and 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 constructor User::getUsername, // Extract username as list elements user -> System.out.println("Processing user: " + user.getUsername()) // Print the processed username);
// Iterate through resultsfor (String username : userNames) { System.out.println("Username: " + username);}
Usage Tips
- The
list
method is suitable for scenarios where you need to quickly obtain a list of specific entity properties. - Using the
sFunction
parameter, you can specify any entity property as theList
elements, making result access more intuitive and efficient. - The
peeks
parameter allows you to perform additional side-effect operations during result processing; these operations do not affect the finalList
result. - When processing large datasets, consider setting the
isParallel
parameter 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, resulting in cleaner and more flexible code.
Db Kit
Db Kit is a utility class provided by MyBatis-Plus that allows you to perform CRUD operations through static method calls. This approach helps you avoid circular dependency injection issues that can occur in Spring environments, simplifies your code, and improves development efficiency.
For complete usage examples of Db Kit, refer to the official test cases.
Usage Examples
// 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 a condition wrapperLambdaQueryWrapper<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 a condition wrapperLambdaUpdateWrapper<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 a condition wrapperLambdaDeleteWrapper<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 you can call directly for database operations, eliminating the need to go through the Service layer and simplifying your code structure.
- When using Db Kit, ensure that the parameters you pass are correct. This is especially important when using Wrapper, where you need to specify the entity class or entity object.
- For batch operations, such as batch inserts or updates, we recommend using the batch methods provided by Db Kit to improve efficiency.
- Avoid frequently calling Db Kit methods within loops, as this may lead to performance issues.
By using Db Kit, you can perform database operations more efficiently while maintaining clean and readable code. This utility class is particularly well-suited for simple CRUD operations and can significantly reduce the amount of repetitive code you need to write.