Skip to content

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:

TypeParameterDescription
TentityEntity object
Collection<T>entityListEntity object collection
intbatchSizeInsert batch size

Example (save):

// Assume we have a User entity object
User user = new User();
user.setName("John Doe");
user.setEmail("john.doe@example.com");
boolean result = userService.save(user); // Call the save method
if (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 objects
List<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 size
boolean result = userService.saveBatch(users); // Call saveBatch method with default batch size
if (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 objects
List<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 2
boolean result = userService.saveBatch(users, 2); // Call saveBatch method with specified batch size
if (result) {
System.out.println("Users saved successfully.");
} else {
System.out.println("Failed to save users.");
}

Generated SQL (with specified batch size of 2):

-- First batch
INSERT INTO user (name, email) VALUES
('David', 'david@example.com'),
('Eve', 'eve@example.com')
-- Second batch
INSERT 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:

TypeParameter NameDescription
TentityEntity object
Wrapper<T>updateWrapperEntity object wrapper class UpdateWrapper
Collection<T>entityListCollection of entity objects
intbatchSizeInsert batch size

Example (saveOrUpdate):

// Assume a User entity object where id is the property annotated with TableId
User user = new User();
user.setId(1);
user.setName("John Doe");
user.setEmail("john.doe@example.com");
boolean result = userService.saveOrUpdate(user); // Call the saveOrUpdate method
if (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 property
List<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 size
boolean result = userService.saveOrUpdateBatch(users); // Call saveOrUpdateBatch method with default batch size
if (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 = 1
UPDATE user SET name = 'Bob', email = 'bob@example.com' WHERE id = 2
INSERT INTO user (id, name, email) VALUES (3, 'Charlie', 'charlie@example.com')

Example (saveOrUpdateBatch with specified batch size):

// Assume a collection of User entity objects
List<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 2
boolean result = userService.saveOrUpdateBatch(users, 2); // Call saveOrUpdateBatch method with specified batch size
if (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 batch
UPDATE user SET name = 'David', email = 'david@example.com' WHERE id = 4
UPDATE user SET name = 'Eve', email = 'eve@example.com' WHERE id = 5
-- Second batch
INSERT 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:

TypeParameterDescription
Wrapper<T>queryWrapperEntity wrapper QueryWrapper
SerializableidPrimary Key ID
Map<String, Object>columnMapTable column map object
Collection<? extends Serializable>idListPrimary 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 method
if (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 1
boolean result = userService.removeById(1); // Call removeById method
if (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 = 30
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("age", 30);
boolean result = userService.removeByMap(columnMap); // Call removeByMap method
if (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 deletion
List<Integer> ids = Arrays.asList(1, 2, 3);
boolean result = userService.removeByIds(ids); // Call removeByIds method
if (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 条件,更新记录 需要设置sqlset
boolean 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:

TypeParameterDescription
Wrapper<T>updateWrapperEntity object wrapper class UpdateWrapper
TentityEntity object
Collection<T>entityListEntity object collection
intbatchSizeBatch update size

Example (update with UpdateWrapper):

// Assume an UpdateWrapper object with update condition name = 'John Doe' and update field email
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name", "John Doe").set("email", "john.doe@newdomain.com");
boolean result = userService.update(updateWrapper); // Call update method
if (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 = 1
User updateEntity = new User();
updateEntity.setName("Updated Name");
QueryWrapper<User> whereWrapper = new QueryWrapper<>();
whereWrapper.eq("id", 1);
boolean result = userService.update(updateEntity, whereWrapper); // Call update method
if (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 ID
User updateEntity = new User();
updateEntity.setId(1);
updateEntity.setEmail("updated.email@example.com");
boolean result = userService.updateById(updateEntity); // Call updateById method
if (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 update
List<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 size
if (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 = 1
UPDATE 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 1
List<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 size
if (result) {
System.out.println("Records updated successfully.");
} else {
System.out.println("Failed to update records.");
}

Generated SQL (with specified batch size of 1):

-- First batch
UPDATE user SET email = 'new.email1@example.com' WHERE id = 1
-- Second batch
UPDATE 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:

TypeParameterDescription
SerializableidPrimary key ID
Wrapper<T>queryWrapperEntity object wrapper class QueryWrapper
booleanthrowExWhether to throw exception when multiple results found
TentityEntity object
Function<? super Object, V>mapperConversion function

Example (getById):

// Assume you want to query a user with ID 1
User user = userService.getById(1); // Call getById method
if (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 method
if (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 exception
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "John Doe");
User user = userService.getOne(queryWrapper, false); // Call getOne method
if (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 Map
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "John Doe");
Map<String, Object> userMap = userService.getMap(queryWrapper); // Call getMap method
if (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 String
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "John Doe");
String userName = userService.getObj(queryWrapper, obj -> ((User) obj).getName()); // Call getObj method
if (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 all
List<T> list();
// Query list
List<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 lists
List<Map<String, Object>> listMaps();
// Query list
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// Query all records
List<Object> listObjs();
// Query all records
<V> List<V> listObjs(Function<? super Object, V> mapper);
// Query all records by Wrapper condition
List<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:

TypeParameterDescription
Wrapper<T>queryWrapperEntity object wrapper class QueryWrapper
Collection<? extends Serializable>idListPrimary key ID list
Map<String, Object>columnMapTable field map object
Function<? super Object, V>mapperConversion function

Example (list):

// Query all users
List<User> users = userService.list(); // Call list method
for (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 > 25
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
List<User> users = userService.list(queryWrapper); // Call list method
for (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 query
List<Integer> ids = Arrays.asList(1, 2, 3);
Collection<User> users = userService.listByIds(ids); // Call listByIds method
for (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 = 30
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("age", 30);
Collection<User> users = userService.listByMap(columnMap); // Call listByMap method
for (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 Map
List<Map<String, Object>> userMaps = userService.listMaps(); // Call listMaps method
for (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 Map
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
List<Map<String, Object>> userMaps = userService.listMaps(queryWrapper); // Call listMaps method
for (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 list
List<String> userNames = userService.listObjs(obj -> ((User) obj).getName()); // Call listObjs method
for (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 list
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
List<String> userNames = userService.listObjs(queryWrapper, obj -> ((User) obj).getName()); // Call listObjs method
for (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:

TypeNameDescription
IPage<T>pagePagination object
Wrapper<T>queryWrapperEntity wrapper class QueryWrapper

Example (page):

// Unconditional paginated query, showing 10 records per page, querying page 1
IPage<User> page = new Page<>(1, 10);
IPage<User> userPage = userService.page(page); // Call page method
List<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 > 25
IPage<User> page = new Page<>(1, 10);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
IPage<User> userPage = userService.page(page, queryWrapper); // Call page method
List<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 1
IPage<Map<String, Object>> page = new Page<>(1, 10);
IPage<Map<String, Object>> userPageMaps = userService.pageMaps(page); // Call pageMaps method
List<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 Map
IPage<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 method
List<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 count
int count();
// Query total record count based on Wrapper conditions
int count(Wrapper<T> queryWrapper);
// Starting from version 3.4.3.2, return value changed to long
// Query total record count
long count();
// Query total record count based on Wrapper conditions
long 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:

TypeParameterDescription
Wrapper<T>queryWrapperEntity object wrapper class QueryWrapper

Example (count):

// Query the total number of records in the user table
int totalUsers = userService.count(); // Call count method
System.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 condition
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
int totalUsers = userService.count(queryWrapper); // Call count method
System.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 record
int 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:

TypeParameterDescription
TentityEntity 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 method
if (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:

TypeParameterDescription
Wrapper<T>wrapperEntity wrapper class (can be null)
Collection<? extends Serializable>idListPrimary key ID list (cannot be null or empty)
SerializableidPrimary key ID
Map<String, Object>columnMapTable column map object

Example (delete):

// Assume you have a QueryWrapper object with conditions set to age > 25, delete users that match
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
int rows = userMapper.delete(queryWrapper); // Call delete method
if (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 batch
List<Integer> ids = Arrays.asList(1, 2, 3);
int rows = userMapper.deleteBatchIds(ids); // Call deleteBatchIds method
if (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 ID
int userId = 1;
int rows = userMapper.deleteById(userId); // Call deleteById method
if (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 match
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("age", 30);
int rows = userMapper.deleteByMap(columnMap); // Call deleteByMap method
if (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:

TypeParameterDescription
TentityEntity object (sets condition values, can be null)
Wrapper<T>updateWrapperEntity 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 condition
UpdateWrapper<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 method
if (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 1
User updateUser = new User();
updateUser.setId(1);
updateUser.setEmail("new.email@example.com");
int rows = userMapper.updateById(updateUser); // Call the updateById method
if (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:

TypeParameterDescription
SerializableidPrimary key ID
Wrapper<T>queryWrapperEntity wrapper (can be null)
Collection<? extends Serializable>idListPrimary key ID list (cannot be null or empty)
Map<String, Object>columnMapTable column map object
IPage<T>pagePagination condition (can be RowBounds.DEFAULT)

Example (selectById):

// Query a single user by ID
int userId = 1;
User user = userMapper.selectById(userId); // Call selectById method
System.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 matches
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
User user = userMapper.selectOne(queryWrapper); // Call selectOne method
System.out.println("User: " + user);

Generated SQL:

SELECT * FROM user WHERE age > 25

Example (selectBatchIds):

// Assume we have a list of IDs, query users in batch
List<Integer> ids = Arrays.asList(1, 2, 3);
List<User> users = userMapper.selectBatchIds(ids); // Call selectBatchIds method
for (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 match
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
List<User> users = userMapper.selectList(queryWrapper); // Call selectList method
for (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 match
Map<String, Object> columnMap = new HashMap<>();
columnMap.put("age", 30);
List<User> users = userMapper.selectByMap(columnMap); // Call selectByMap method
for (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 Map
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
List<Map<String, Object>> userMaps = userMapper.selectMaps(queryWrapper); // Call selectMaps method
for (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 record
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
List<Object> userIds = userMapper.selectObjs(queryWrapper); // Call selectObjs method
for (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 > 25
IPage<User> page = new Page<>(1, 10);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
IPage<User> userPage = userMapper.selectPage(page, queryWrapper); // Call selectPage method
List<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 Map
IPage<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 method
List<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 count
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 25);
Integer totalUsers = userMapper.selectCount(queryWrapper); // Call selectCount method
System.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 supported
LambdaQueryChainWrapper<T> lambdaQuery();

Example:

// Standard chain-style query example
query().eq("name", "John").list(); // Query all records where name equals "John"
// Lambda chain-style query example
lambdaQuery().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 supported
LambdaUpdateChainWrapper<T> lambdaUpdate();

Example:

// Standard chain-style update example
update().set("status", "inactive").eq("name", "John").update(); // Update the status to "inactive" for records where name equals "John"
// Lambda chain-style update example
User 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 or UpdateChainWrapper, 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 database
User user = new User();
user.setName("John Doe");
user.setAge(30);
boolean isInserted = user.insert(); // Return value indicates whether the operation succeeded
// Query all users
List<User> allUsers = user.selectAll();
// Update user information by ID
user.setId(1L);
user.setName("Updated Name");
boolean isUpdated = user.updateById(); // Return value indicates whether the operation succeeded
// Delete user by ID
boolean 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, and deleteById 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 BaseMapper
List<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 as User::getId), and one or more peek operations of type Consumer.
  • 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 support
Map<A, E> keyMap(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);
Parameter Description
TypeParameter NameDescription
EentityThe entity object type, representing the type of the query result entity.
AattributeThe entity attribute type, which is also the type of the key in the returned Map.
LambdaQueryWrapper<E>wrapperA lambda-enabled condition constructor for building query conditions.
SFunction<E, A>sFunctionA getter method reference for the entity property, used to determine the value for the Map key.
booleanisParallelIf set to true, uses a parallel stream for execution, which can improve efficiency when processing large datasets.
Consumer<E>…peeksA 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 BaseMapper
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getStatus, "active"); // Query users with status "active"
// Use keyMap to query and encapsulate results
Map<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 results
for (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 the Map 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 final Map result.
  • When processing large datasets, consider setting the isParallel parameter to true 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 support
Map<A, P> map(LambdaQueryWrapper<E> wrapper, SFunction<E, A> keyFunc, SFunction<E, P> valueFunc, boolean isParallel, Consumer<E>... peeks);
Parameter Description
TypeParameter NameDescription
EentityThe entity object type, representing the type of the query result entity.
AattributeThe entity attribute type used as the key type in the returned Map.
PattributeThe entity attribute type used as the value type in the returned Map.
LambdaQueryWrapper<E>wrapperA lambda-enabled condition constructor for building query conditions.
SFunction<E, A>keyFuncA getter method reference for the entity property, used to determine the value for the Map key.
SFunction<E, P>valueFuncA getter method reference for the entity property, used to determine the value for the Map value.
booleanisParallelIf set to true, uses a parallel stream for execution, which can improve efficiency when processing large datasets.
Consumer<E>…peeksA 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 BaseMapper
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getStatus, "active"); // Query users with status "active"
// Use map to query and encapsulate results
Map<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 results
for (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 and valueFunc parameters, you can specify any entity properties as the Map 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 final Map result.
  • When processing large datasets, consider setting the isParallel parameter to true 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 support
Map<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 support
M group(LambdaQueryWrapper<T> wrapper, SFunction<T, K> sFunction, Collector<? super T, A, D> downstream, boolean isParallel, Consumer<T>... peeks);
Parameter Description
TypeParameter NameDescription
TentityThe entity object type, representing the type of the query result entity.
KattributeThe 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>wrapperA lambda-enabled condition constructor for building query conditions.
SFunction<T, K>sFunctionThe grouping criteria, a getter method reference for the entity property, used to determine the value for the Map key.
Collector<T, A, D>downstreamA downstream collector for further processing of the grouped collections.
booleanisParallelIf set to true, uses a parallel stream for execution, which can improve efficiency when processing large datasets.
Consumer<T>…peeksA 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 BaseMapper
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getStatus, "active"); // Query users with status "active"
// Use group to query and encapsulate results, grouped by username
Map<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 results
for (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 a Collector 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 final Map result.
  • When processing large datasets, consider setting the isParallel parameter to true 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 support
List<A> list(LambdaQueryWrapper<E> wrapper, SFunction<E, A> sFunction, boolean isParallel, Consumer<E>... peeks);
Parameter Description
TypeParameter NameDescription
EentityThe entity object type, representing the type of the query result entity.
AattributeThe entity attribute type used as the element type in the returned List.
LambdaQueryWrapper<E>wrapperA lambda-enabled condition constructor for building query conditions.
SFunction<E, A>sFunctionA getter method reference for the entity property, used to determine the value for the List elements.
booleanisParallelIf set to true, uses a parallel stream for execution, which can improve efficiency when processing large datasets.
Consumer<E>…peeksA 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 BaseMapper
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getStatus, "active"); // Query users with status "active"
// Use list to query and encapsulate results, extracting all usernames
List<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 results
for (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 the List 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 final List result.
  • When processing large datasets, consider setting the isParallel parameter to true 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 id
User user = Db.getById(1L, User.class);
// Query multiple entities by ids
List<User> userList = Db.listByIds(Arrays.asList(1L, 2L, 3L), User.class);
// Query using a condition wrapper
LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery(User.class)
.eq(User::getStatus, "active");
List<User> activeUsers = Db.list(queryWrapper);
// Insert a new entity
User newUser = new User();
newUser.setUsername("newUser");
newUser.setAge(25);
boolean isInserted = Db.insert(newUser);
// Update an entity by id
User updateUser = new User();
updateUser.setId(1L);
updateUser.setUsername("updatedUser");
boolean isUpdated = Db.updateById(updateUser);
// Update using a condition wrapper
LambdaUpdateWrapper<User> updateWrapper = Wrappers.lambdaUpdate(User.class)
.set(User::getAge, 30)
.eq(User::getUsername, "updatedUser");
boolean isUpdatedByWrapper = Db.update(null, updateWrapper);
// Delete an entity by id
boolean isDeleted = Db.removeById(1L);
// Delete using a condition wrapper
LambdaDeleteWrapper<User> deleteWrapper = Wrappers.lambdaDelete(User.class)
.eq(User::getStatus, "inactive");
boolean isDeletedByWrapper = Db.remove(deleteWrapper);
// Batch insert
List<User> batchUsers = Arrays.asList(
new User("user1", 20),
new User("user2", 22),
new User("user3", 24)
);
boolean isBatchInserted = Db.saveBatch(batchUsers);
// Batch update
List<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.

Baomidou

© 2016-2025 Baomidou™. All Rights Reserved.

Power by Astro Starlight | Sponsored by JetBrains

渝ICP备2021000141号-1 | 渝公网安备50011302222097