MyBatis-Flex is an elegant enhancement framework for MyBatis providing type-safe query building, active record patterns, and comprehensive ORM capabilities
—
Business logic abstraction with enhanced CRUD operations, batch processing, and query chaining. The IService interface provides a comprehensive service layer pattern that's perfect for service-oriented architectures and dependency injection frameworks.
Comprehensive service interface providing business logic layer operations with enhanced functionality beyond basic CRUD.
/**
* Enhanced service layer interface for business logic operations
* @param <T> Entity type
*/
public interface IService<T> {
int DEFAULT_BATCH_SIZE = 1000;
/**
* Get the base mapper for entity operations
* @return BaseMapper instance
*/
BaseMapper<T> getMapper();
// ===== Save operations =====
/**
* Save single entity (ignores null properties)
* @param entity entity to save
* @return true if successful
*/
boolean save(T entity);
/**
* Save multiple entities in batch (default batch size: 1000)
* @param entities collection of entities to save
* @return true if all successful
*/
boolean saveBatch(Collection<T> entities);
/**
* Save multiple entities with custom batch size
* @param entities collection of entities to save
* @param batchSize number of entities per batch
* @return true if all successful
*/
boolean saveBatch(Collection<T> entities, int batchSize);
/**
* Save or update entity based on primary key existence (ignores null properties)
* @param entity entity to save or update
* @return true if successful
*/
boolean saveOrUpdate(T entity);
/**
* Save or update multiple entities in batch (default batch size: 1000)
* @param entities collection of entities
* @return true if all successful
*/
boolean saveOrUpdateBatch(Collection<T> entities);
/**
* Save or update multiple entities with custom batch size
* @param entities collection of entities
* @param batchSize number of entities per batch
* @return true if all successful
*/
boolean saveOrUpdateBatch(Collection<T> entities, int batchSize);
// ===== Remove operations =====
/**
* Remove entities by query wrapper conditions
* @param query query conditions
* @return true if successful
*/
boolean remove(QueryWrapper query);
/**
* Remove entities by query condition
* @param condition query condition
* @return true if successful
*/
boolean remove(QueryCondition condition);
/**
* Remove entity by entity object (using primary key)
* @param entity entity object with primary key
* @return true if successful
*/
boolean removeById(T entity);
/**
* Remove entity by primary key
* @param id primary key value
* @return true if successful
*/
boolean removeById(Serializable id);
/**
* Remove entities by primary key collection
* @param ids collection of primary key values
* @return true if successful
*/
boolean removeByIds(Collection<? extends Serializable> ids);
/**
* Remove entities by Map conditions (prevents empty map to avoid full table deletion)
* @param query Map of column-value conditions
* @return true if successful
* @throws FlexException if map is null or empty
*/
boolean removeByMap(Map<String, Object> query);
// ===== Update operations =====
/**
* Update entity by primary key (ignores null properties by default)
* @param entity entity to update
* @return true if successful
*/
boolean updateById(T entity);
/**
* Update entity by primary key with null handling option
* @param entity entity to update
* @param ignoreNulls whether to ignore null properties
* @return true if successful
*/
boolean updateById(T entity, boolean ignoreNulls);
/**
* Update entity by Map conditions
* @param entity entity with new values
* @param query Map of where conditions
* @return true if successful
*/
boolean update(T entity, Map<String, Object> query);
/**
* Update entity by query wrapper conditions
* @param entity entity with new values
* @param query query wrapper conditions
* @return true if successful
*/
boolean update(T entity, QueryWrapper query);
/**
* Update entity by query condition
* @param entity entity with new values
* @param condition query condition
* @return true if successful
*/
boolean update(T entity, QueryCondition condition);
/**
* Batch update entities by primary key (default batch size: 1000, ignores null properties)
* @param entities collection of entities to update
* @return true if all successful
*/
boolean updateBatch(Collection<T> entities);
/**
* Batch update entities with null handling option (default batch size: 1000)
* @param entities collection of entities to update
* @param ignoreNulls whether to ignore null properties
* @return true if all successful
*/
boolean updateBatch(Collection<T> entities, boolean ignoreNulls);
/**
* Batch update entities with custom batch size (ignores null properties)
* @param entities collection of entities to update
* @param batchSize number of entities per batch
* @return true if all successful
*/
boolean updateBatch(Collection<T> entities, int batchSize);
/**
* Batch update entities with custom batch size and null handling option
* @param entities collection of entities to update
* @param batchSize number of entities per batch
* @param ignoreNulls whether to ignore null properties
* @return true if all successful
*/
boolean updateBatch(Collection<T> entities, int batchSize, boolean ignoreNulls);
// ===== Query operations =====
/**
* Get entity by primary key
* @param id primary key value
* @return entity or null if not found
*/
T getById(Serializable id);
/**
* Get entity by entity primary key
* @param entity entity object with primary key
* @return entity or null if not found
*/
T getOneByEntityId(T entity);
/**
* Get entity by entity primary key with Optional wrapper
* @param entity entity object with primary key
* @return Optional containing entity or empty
*/
Optional<T> getByEntityIdOpt(T entity);
/**
* Get entity by primary key with Optional wrapper
* @param id primary key value
* @return Optional containing entity or empty
*/
Optional<T> getByIdOpt(Serializable id);
/**
* Get single entity by query wrapper conditions
* @param query query conditions
* @return single entity or null
*/
T getOne(QueryWrapper query);
/**
* Get single entity by query wrapper with Optional wrapper
* @param query query conditions
* @return Optional containing entity or empty
*/
Optional<T> getOneOpt(QueryWrapper query);
/**
* Get single entity by query wrapper and transform to target type
* @param query query conditions
* @param asType target type class
* @return transformed object or null
*/
<R> R getOneAs(QueryWrapper query, Class<R> asType);
/**
* Get single entity by query wrapper, transform to target type with Optional wrapper
* @param query query conditions
* @param asType target type class
* @return Optional containing transformed object or empty
*/
<R> Optional<R> getOneAsOpt(QueryWrapper query, Class<R> asType);
/**
* Get single entity by query condition
* @param condition query condition
* @return single entity or null
*/
T getOne(QueryCondition condition);
/**
* Get single entity by query condition with Optional wrapper
* @param condition query condition
* @return Optional containing entity or empty
*/
Optional<T> getOneOpt(QueryCondition condition);
/**
* Get first column value of first row from query result
* @param query query conditions
* @return object value or null
*/
Object getObj(QueryWrapper query);
/**
* Get first column value of first row with Optional wrapper
* @param query query conditions
* @return Optional containing object value or empty
*/
Optional<Object> getObjOpt(QueryWrapper query);
/**
* Get first column value of first row and cast to target type
* @param query query conditions
* @param asType target type class (e.g., Long.class, String.class)
* @return typed value or null
*/
<R> R getObjAs(QueryWrapper query, Class<R> asType);
/**
* Get first column value of first row, cast to target type with Optional wrapper
* @param query query conditions
* @param asType target type class
* @return Optional containing typed value or empty
*/
<R> Optional<R> getObjAsOpt(QueryWrapper query, Class<R> asType);
/**
* Get all values from first column of query result
* @param query query conditions
* @return list of object values
*/
List<Object> objList(QueryWrapper query);
/**
* Get all values from first column and cast to target type
* @param query query conditions
* @param asType target type class
* @return list of typed values
*/
<R> List<R> objListAs(QueryWrapper query, Class<R> asType);
/**
* Get all entities
* @return list of all entities
*/
List<T> list();
/**
* Get entities by query wrapper conditions
* @param query query conditions
* @return list of entities
*/
List<T> list(QueryWrapper query);
/**
* Get entities by query condition
* @param condition query condition
* @return list of entities
*/
List<T> list(QueryCondition condition);
/**
* Get entities by query wrapper and transform to target type
* @param query query conditions
* @param asType target type class
* @return list of transformed objects
*/
<R> List<R> listAs(QueryWrapper query, Class<R> asType);
/**
* Get entities by primary key collection
* @param ids collection of primary key values
* @return list of entities
*/
List<T> listByIds(Collection<? extends Serializable> ids);
/**
* Get entities by Map conditions
* @param query Map of column-value conditions
* @return list of entities
*/
List<T> listByMap(Map<String, Object> query);
// ===== Count and existence operations =====
/**
* Check if entities exist by query wrapper conditions
* @param query query conditions
* @return true if exists, false otherwise
*/
boolean exists(QueryWrapper query);
/**
* Check if entities exist by query condition
* @param condition query condition
* @return true if exists, false otherwise
*/
boolean exists(QueryCondition condition);
/**
* Count all entities
* @return total count
*/
long count();
/**
* Count entities by query wrapper conditions
* @param query query conditions
* @return count matching conditions
*/
long count(QueryWrapper query);
/**
* Count entities by query condition
* @param condition query condition
* @return count matching condition
*/
long count(QueryCondition condition);
// ===== Pagination operations =====
/**
* Paginate all entities
* @param page pagination parameters
* @return page of entities
*/
Page<T> page(Page<T> page);
/**
* Paginate entities by query wrapper conditions
* @param page pagination parameters
* @param query query conditions
* @return page of entities
*/
Page<T> page(Page<T> page, QueryWrapper query);
/**
* Paginate entities by query condition
* @param page pagination parameters
* @param condition query condition
* @return page of entities
*/
Page<T> page(Page<T> page, QueryCondition condition);
/**
* Paginate entities with type transformation
* @param page pagination parameters
* @param query query conditions
* @param asType target type class
* @return page of transformed objects
*/
<R> Page<R> pageAs(Page<R> page, QueryWrapper query, Class<R> asType);
// ===== Query wrapper and chain operations =====
/**
* Create default QueryWrapper
* @return QueryWrapper instance
*/
QueryWrapper query();
/**
* Create query chain for fluent operations
* @return QueryChain instance
*/
QueryChain<T> queryChain();
/**
* Create update chain for fluent operations
* @return UpdateChain instance
*/
UpdateChain<T> updateChain();
}Service Implementation Example:
import com.mybatisflex.core.service.IService;
import org.springframework.stereotype.Service;
// Entity
@Table("users")
public class User {
@Id
private Long id;
private String name;
private Integer age;
private String email;
private Boolean active;
private Date createTime;
// Constructors, getters, setters...
}
// Service interface
public interface UserService extends IService<User> {
// Custom business methods
List<User> findActiveUsers();
List<User> findUsersByAgeRange(int minAge, int maxAge);
boolean deactivateUser(Long userId);
}
// Service implementation
@Service
public class UserServiceImpl implements UserService {
@Override
public List<User> findActiveUsers() {
return list(QueryWrapper.create()
.from(User.class)
.where(USER.ACTIVE.eq(true))
.orderBy(USER.CREATE_TIME.desc()));
}
@Override
public List<User> findUsersByAgeRange(int minAge, int maxAge) {
return list(QueryWrapper.create()
.from(User.class)
.where(USER.AGE.between(minAge, maxAge))
.and(USER.ACTIVE.eq(true)));
}
@Override
public boolean deactivateUser(Long userId) {
User user = getById(userId);
if (user != null) {
user.setActive(false);
return update(user);
}
return false;
}
}Comprehensive save operations with batch processing and upsert functionality.
/**
* Save single entity (ignores null properties)
* @param entity entity to save
* @return true if successful
*/
boolean save(T entity);
/**
* Save multiple entities in batch (default batch size: 1000)
* @param entities collection of entities to save
* @return true if all successful
*/
boolean saveBatch(Collection<T> entities);
/**
* Save multiple entities with custom batch size
* @param entities collection of entities to save
* @param batchSize number of entities per batch
* @return true if all successful
*/
boolean saveBatch(Collection<T> entities, int batchSize);
/**
* Save or update entity based on primary key existence (ignores null properties)
* @param entity entity to save or update
* @return true if successful
*/
boolean saveOrUpdate(T entity);
/**
* Save or update multiple entities in batch (default batch size: 1000)
* @param entities collection of entities
* @return true if all successful
*/
boolean saveOrUpdateBatch(Collection<T> entities);
/**
* Save or update multiple entities with custom batch size
* @param entities collection of entities
* @param batchSize number of entities per batch
* @return true if all successful
*/
boolean saveOrUpdateBatch(Collection<T> entities, int batchSize);Save Examples:
@Autowired
private UserService userService;
public void demonstrateSaveOperations() {
// Single save
User user = new User("Alice", 25, "alice@example.com");
boolean saved = userService.save(user);
// Batch save
List<User> users = Arrays.asList(
new User("Bob", 30, "bob@example.com"),
new User("Charlie", 28, "charlie@example.com"),
new User("Diana", 32, "diana@example.com")
);
boolean batchSaved = userService.saveBatch(users);
// Custom batch size
boolean customBatchSaved = userService.saveBatch(users, 2);
// Save or update
User existingUser = userService.getById(1L);
existingUser.setAge(26);
boolean upserted = userService.saveOrUpdate(existingUser);
// New user (will be inserted)
User newUser = new User("Eve", 29, "eve@example.com");
boolean newUpserted = userService.saveOrUpdate(newUser);
// Save or update multiple entities in batch
List<User> existingUsers = userService.listByIds(Arrays.asList(1L, 2L, 3L));
existingUsers.forEach(user -> user.setAge(user.getAge() + 1));
boolean batchUpserted = userService.saveOrUpdateBatch(existingUsers);
// Save or update with custom batch size
boolean customBatchUpserted = userService.saveOrUpdateBatch(existingUsers, 500);
}Comprehensive remove operations with query conditions and safety features.
/**
* Remove entities by query wrapper conditions
* @param query query wrapper with conditions
* @return true if successful
*/
boolean remove(QueryWrapper query);
/**
* Remove entities by query condition
* @param condition single query condition
* @return true if successful
*/
boolean remove(QueryCondition condition);
/**
* Remove entity by entity object (using primary key)
* @param entity entity object with primary key
* @return true if successful
*/
boolean removeById(T entity);
/**
* Remove entity by primary key
* @param id primary key value
* @return true if successful
*/
boolean removeById(Serializable id);
/**
* Remove entities by primary key collection
* @param ids collection of primary key values
* @return true if successful
*/
boolean removeByIds(Collection<? extends Serializable> ids);
/**
* Remove entities by Map conditions (prevents empty map)
* @param query Map of column-value conditions
* @return true if successful
* @throws FlexException if map is null or empty
*/
boolean removeByMap(Map<String, Object> query);Remove Examples:
public void demonstrateRemoveOperations() {
// Remove by primary key
boolean removed = userService.removeById(1L);
// Remove by entity object
User user = userService.getById(2L);
boolean removedByEntity = userService.removeById(user);
// Remove by multiple IDs
List<Long> ids = Arrays.asList(3L, 4L, 5L);
boolean batchRemoved = userService.removeByIds(ids);
// Remove by query wrapper
boolean removedByQuery = userService.remove(
QueryWrapper.create()
.from(User.class)
.where(USER.ACTIVE.eq(false))
.and(USER.LAST_LOGIN_TIME.lt(oneYearAgo))
);
// Remove by query condition
boolean removedByCondition = userService.remove(
USER.AGE.lt(18).and(USER.ACTIVE.eq(false))
);
// Remove by Map conditions (safer than manual SQL)
Map<String, Object> conditions = new HashMap<>();
conditions.put("status", "INACTIVE");
conditions.put("deleted", true);
boolean removedByMap = userService.removeByMap(conditions);
// Note: Empty map will throw FlexException to prevent accidental full table deletion
// userService.removeByMap(new HashMap<>()); // This would throw an exception
}Advanced update operations with batch processing and null handling options.
/**
* Update entity by primary key (ignores null properties by default)
* @param entity entity to update
* @return true if successful
*/
boolean updateById(T entity);
/**
* Update entity by primary key with null handling option
* @param entity entity to update
* @param ignoreNulls whether to ignore null properties
* @return true if successful
*/
boolean updateById(T entity, boolean ignoreNulls);
/**
* Update entity by Map conditions
* @param entity entity with new values
* @param query Map of where conditions
* @return true if successful
*/
boolean update(T entity, Map<String, Object> query);
/**
* Update entity by query wrapper conditions
* @param entity entity with new values
* @param query query wrapper conditions
* @return true if successful
*/
boolean update(T entity, QueryWrapper query);
/**
* Update entity by query condition
* @param entity entity with new values
* @param condition query condition
* @return true if successful
*/
boolean update(T entity, QueryCondition condition);
/**
* Batch update entities by primary key (default batch size: 1000)
* @param entities collection of entities to update
* @return true if all successful
*/
boolean updateBatch(Collection<T> entities);
/**
* Batch update entities with null handling option
* @param entities collection of entities to update
* @param ignoreNulls whether to ignore null properties
* @return true if all successful
*/
boolean updateBatch(Collection<T> entities, boolean ignoreNulls);
/**
* Batch update entities with custom batch size
* @param entities collection of entities to update
* @param batchSize number of entities per batch
* @return true if all successful
*/
boolean updateBatch(Collection<T> entities, int batchSize);
/**
* Batch update entities with custom batch size and null handling
* @param entities collection of entities to update
* @param batchSize number of entities per batch
* @param ignoreNulls whether to ignore null properties
* @return true if all successful
*/
boolean updateBatch(Collection<T> entities, int batchSize, boolean ignoreNulls);Update Examples:
public void demonstrateUpdateOperations() {
// Basic update by ID (ignores null properties)
User user = userService.getById(1L);
user.setAge(26);
user.setEmail(null); // This field will be ignored
boolean updated = userService.updateById(user);
// Update by ID with null handling control
User user2 = userService.getById(2L);
user2.setAge(27);
user2.setEmail(null); // This field will be set to NULL in database
boolean updatedWithNulls = userService.updateById(user2, false);
// Update by query conditions
User updateData = new User();
updateData.setActive(false);
updateData.setUpdateTime(new Date());
boolean updatedByQuery = userService.update(updateData,
QueryWrapper.create()
.from(User.class)
.where(USER.LAST_LOGIN_TIME.lt(sixMonthsAgo))
);
// Update by Map conditions
Map<String, Object> whereConditions = new HashMap<>();
whereConditions.put("department", "IT");
whereConditions.put("active", true);
User salaryUpdate = new User();
salaryUpdate.setSalary(salaryUpdate.getSalary() * 1.1); // 10% raise
boolean updatedByMap = userService.update(salaryUpdate, whereConditions);
// Update by single condition
User statusUpdate = new User();
statusUpdate.setStatus("VERIFIED");
boolean updatedByCondition = userService.update(statusUpdate,
USER.EMAIL_VERIFIED.eq(true).and(USER.STATUS.eq("PENDING"))
);
// Batch updates
List<User> usersToUpdate = userService.listByIds(Arrays.asList(1L, 2L, 3L));
usersToUpdate.forEach(u -> u.setLastUpdated(new Date()));
// Default batch update (ignores nulls, batch size 1000)
boolean batchUpdated = userService.updateBatch(usersToUpdate);
// Batch update with null handling
boolean batchUpdatedWithNulls = userService.updateBatch(usersToUpdate, false);
// Batch update with custom batch size
boolean customBatchUpdated = userService.updateBatch(usersToUpdate, 500);
// Batch update with both custom batch size and null handling
boolean fullCustomBatch = userService.updateBatch(usersToUpdate, 500, false);
}Enhanced query operations with Optional support, type transformations, and advanced querying methods.
/**
* Get entity by primary key
* @param id primary key value
* @return entity or null if not found
*/
T getById(Serializable id);
/**
* Get entity by entity primary key
* @param entity entity object with primary key
* @return entity or null if not found
*/
T getOneByEntityId(T entity);
/**
* Get entity by entity primary key with Optional wrapper
* @param entity entity object with primary key
* @return Optional containing entity or empty
*/
Optional<T> getByEntityIdOpt(T entity);
/**
* Get entity by primary key with Optional wrapper
* @param id primary key value
* @return Optional containing entity or empty
*/
Optional<T> getByIdOpt(Serializable id);
/**
* Get single entity by query wrapper conditions
* @param query query conditions
* @return single entity or null
*/
T getOne(QueryWrapper query);
/**
* Get single entity by query wrapper with Optional wrapper
* @param query query conditions
* @return Optional containing entity or empty
*/
Optional<T> getOneOpt(QueryWrapper query);
/**
* Get single entity by query wrapper and transform to target type
* @param query query conditions
* @param asType target type class
* @return transformed object or null
*/
<R> R getOneAs(QueryWrapper query, Class<R> asType);
/**
* Get single entity by query wrapper, transform with Optional wrapper
* @param query query conditions
* @param asType target type class
* @return Optional containing transformed object or empty
*/
<R> Optional<R> getOneAsOpt(QueryWrapper query, Class<R> asType);
/**
* Get single entity by query condition
* @param condition query condition
* @return single entity or null
*/
T getOne(QueryCondition condition);
/**
* Get single entity by query condition with Optional wrapper
* @param condition query condition
* @return Optional containing entity or empty
*/
Optional<T> getOneOpt(QueryCondition condition);
/**
* Get first column value of first row from query result
* @param query query conditions
* @return object value or null
*/
Object getObj(QueryWrapper query);
/**
* Get first column value with Optional wrapper
* @param query query conditions
* @return Optional containing object value or empty
*/
Optional<Object> getObjOpt(QueryWrapper query);
/**
* Get first column value and cast to target type
* @param query query conditions
* @param asType target type class (e.g., Long.class, String.class)
* @return typed value or null
*/
<R> R getObjAs(QueryWrapper query, Class<R> asType);
/**
* Get first column value, cast to target type with Optional wrapper
* @param query query conditions
* @param asType target type class
* @return Optional containing typed value or empty
*/
<R> Optional<R> getObjAsOpt(QueryWrapper query, Class<R> asType);
/**
* Get all values from first column of query result
* @param query query conditions
* @return list of object values
*/
List<Object> objList(QueryWrapper query);
/**
* Get all values from first column and cast to target type
* @param query query conditions
* @param asType target type class
* @return list of typed values
*/
<R> List<R> objListAs(QueryWrapper query, Class<R> asType);
/**
* Get all entities
* @return list of all entities
*/
List<T> list();
/**
* Get entities by query wrapper conditions
* @param query query conditions
* @return list of entities
*/
List<T> list(QueryWrapper query);
/**
* Get entities by query condition
* @param condition query condition
* @return list of entities
*/
List<T> list(QueryCondition condition);
/**
* Transform query results to different type
* @param query query conditions
* @param asType target type class
* @return list of transformed objects
*/
<R> List<R> listAs(QueryWrapper query, Class<R> asType);
/**
* Get entities by primary keys
* @param ids collection of primary key values
* @return list of entities
*/
List<T> listByIds(Collection<? extends Serializable> ids);
/**
* Get entities by Map conditions
* @param query Map of column-value conditions
* @return list of entities
*/
List<T> listByMap(Map<String, Object> query);Query Examples:
public void demonstrateQueryOperations() {
// Basic queries
User user = userService.getById(1L);
Optional<User> userOpt = userService.getByIdOpt(1L);
// Query by entity object
User entityWithId = new User();
entityWithId.setId(1L);
User foundUser = userService.getOneByEntityId(entityWithId);
Optional<User> foundUserOpt = userService.getByEntityIdOpt(entityWithId);
// Single query with conditions
User youngUser = userService.getOne(
QueryWrapper.create()
.from(User.class)
.where(USER.AGE.lt(25))
.orderBy(USER.AGE.asc())
);
// Optional query
Optional<User> youngUserOpt = userService.getOneOpt(
QueryWrapper.create()
.from(User.class)
.where(USER.AGE.lt(25))
);
// Query with single condition
User activeUser = userService.getOne(USER.ACTIVE.eq(true));
Optional<User> activeUserOpt = userService.getOneOpt(USER.ACTIVE.eq(true));
// Type transformation queries
UserDTO userDTO = userService.getOneAs(
QueryWrapper.create()
.select(USER.ID, USER.NAME, USER.EMAIL)
.from(User.class)
.where(USER.ID.eq(1L)),
UserDTO.class
);
Optional<UserDTO> userDTOOpt = userService.getOneAsOpt(
QueryWrapper.create()
.select(USER.ID, USER.NAME, USER.EMAIL)
.from(User.class)
.where(USER.ID.eq(1L)),
UserDTO.class
);
// Object value queries (for single column results)
Object maxAge = userService.getObj(
QueryWrapper.create()
.select(QueryMethods.max(USER.AGE))
.from(User.class)
);
Optional<Object> maxAgeOpt = userService.getObjOpt(
QueryWrapper.create()
.select(QueryMethods.max(USER.AGE))
.from(User.class)
);
// Typed object queries
Long userCount = userService.getObjAs(
QueryWrapper.create()
.select(QueryMethods.count())
.from(User.class),
Long.class
);
Optional<Long> userCountOpt = userService.getObjAsOpt(
QueryWrapper.create()
.select(QueryMethods.count())
.from(User.class),
Long.class
);
// Object list queries (for single column multiple rows)
List<Object> allEmails = userService.objList(
QueryWrapper.create()
.select(USER.EMAIL)
.from(User.class)
.where(USER.ACTIVE.eq(true))
);
List<String> allEmailsTyped = userService.objListAs(
QueryWrapper.create()
.select(USER.EMAIL)
.from(User.class)
.where(USER.ACTIVE.eq(true)),
String.class
);
// List queries
List<Long> ids = Arrays.asList(1L, 2L, 3L);
List<User> users = userService.listByIds(ids);
List<User> allUsers = userService.list();
List<User> activeUsers = userService.list(
QueryWrapper.create()
.from(User.class)
.where(USER.ACTIVE.eq(true))
);
// List by single condition
List<User> youngUsers = userService.list(USER.AGE.lt(25));
// List by Map conditions
Map<String, Object> conditions = new HashMap<>();
conditions.put("active", true);
conditions.put("department", "IT");
List<User> itUsers = userService.listByMap(conditions);
// Type transformation
List<UserDTO> userDTOs = userService.listAs(
QueryWrapper.create()
.select(USER.ID, USER.NAME, USER.EMAIL)
.from(User.class)
.where(USER.ACTIVE.eq(true)),
UserDTO.class
);
}Efficient counting and existence checking with various query methods.
/**
* Check if entities exist by query wrapper conditions
* @param query query conditions
* @return true if exists, false otherwise
*/
boolean exists(QueryWrapper query);
/**
* Check if entities exist by query condition
* @param condition query condition
* @return true if exists, false otherwise
*/
boolean exists(QueryCondition condition);
/**
* Count all entities
* @return total count
*/
long count();
/**
* Count entities by query wrapper conditions
* @param query query conditions
* @return count matching conditions
*/
long count(QueryWrapper query);
/**
* Count entities by query condition
* @param condition query condition
* @return count matching condition
*/
long count(QueryCondition condition);Count and Existence Examples:
public void demonstrateCountAndExistence() {
// Basic count
long totalUsers = userService.count();
// Count with query wrapper conditions
long activeUserCount = userService.count(
QueryWrapper.create()
.from(User.class)
.where(USER.ACTIVE.eq(true))
);
// Count with single condition
long youngUserCount = userService.count(USER.AGE.lt(25));
// Existence checks
boolean hasActiveUsers = userService.exists(
QueryWrapper.create()
.from(User.class)
.where(USER.ACTIVE.eq(true))
);
boolean hasAdminUsers = userService.exists(USER.ROLE.eq("ADMIN"));
// Complex existence check
boolean hasRecentUsers = userService.exists(
QueryWrapper.create()
.from(User.class)
.where(USER.CREATE_TIME.ge(lastMonth))
.and(USER.ACTIVE.eq(true))
);
// Use existence for conditional logic
if (userService.exists(USER.EMAIL.eq("admin@example.com"))) {
// Admin user already exists, skip creation
System.out.println("Admin user already exists");
} else {
// Create admin user
User admin = new User("admin@example.com", "ADMIN");
userService.save(admin);
}
}Enhanced pagination with type transformation support and multiple query methods.
/**
* Paginate all entities
* @param page pagination parameters
* @return page of entities
*/
Page<T> page(Page<T> page);
/**
* Paginate entities by query wrapper conditions
* @param page pagination parameters
* @param query query conditions
* @return page of entities
*/
Page<T> page(Page<T> page, QueryWrapper query);
/**
* Paginate entities by query condition
* @param page pagination parameters
* @param condition query condition
* @return page of entities
*/
Page<T> page(Page<T> page, QueryCondition condition);
/**
* Paginate with type transformation
* @param page pagination parameters
* @param query query conditions
* @param asType target type class
* @return page of transformed objects
*/
<R> Page<R> pageAs(Page<R> page, QueryWrapper query, Class<R> asType);Pagination Examples:
public void demonstratePagination() {
// Basic pagination
Page<User> page1 = new Page<>(1, 10);
Page<User> result1 = userService.page(page1);
// Pagination with query wrapper conditions
Page<User> page2 = new Page<>(1, 10);
Page<User> result2 = userService.page(page2,
QueryWrapper.create()
.from(User.class)
.where(USER.ACTIVE.eq(true))
.orderBy(USER.CREATE_TIME.desc())
);
// Pagination with single condition
Page<User> page3 = new Page<>(1, 10);
Page<User> result3 = userService.page(page3, USER.ACTIVE.eq(true));
// Pagination with type transformation
Page<UserSummaryDTO> dtoPage = new Page<>(1, 20);
Page<UserSummaryDTO> dtoResult = userService.pageAs(dtoPage,
QueryWrapper.create()
.select(USER.ID, USER.NAME, USER.EMAIL, USER.CREATE_TIME)
.from(User.class)
.where(USER.ACTIVE.eq(true)),
UserSummaryDTO.class
);
System.out.println("Total records: " + dtoResult.getTotalRow());
System.out.println("Total pages: " + dtoResult.getTotalPage());
}Fluent interfaces for complex query and update operations with query wrapper creation.
/**
* Create default QueryWrapper
* @return QueryWrapper instance
*/
QueryWrapper query();
/**
* Create query chain for fluent operations
* @return QueryChain instance
*/
QueryChain<T> queryChain();
/**
* Create update chain for fluent operations
* @return UpdateChain instance
*/
UpdateChain<T> updateChain();
/**
* Fluent query interface
* @param <T> Entity type
*/
public interface QueryChain<T> {
QueryChain<T> select(QueryColumn... columns);
QueryChain<T> from(Class<?> entityClass);
QueryChain<T> where(QueryCondition condition);
QueryChain<T> orderBy(QueryColumn... columns);
QueryChain<T> groupBy(QueryColumn... columns);
QueryChain<T> limit(long limit);
T one();
List<T> list();
Page<T> page(Page<T> page);
long count();
}
/**
* Fluent update interface
* @param <T> Entity type
*/
public interface UpdateChain<T> {
UpdateChain<T> set(String column, Object value);
UpdateChain<T> set(QueryColumn column, Object value);
UpdateChain<T> where(QueryCondition condition);
boolean update();
long count();
}Query Wrapper and Chaining Examples:
public void demonstrateQueryWrapperAndChaining() {
// Basic QueryWrapper creation
QueryWrapper basicQuery = userService.query()
.from(User.class)
.where(USER.ACTIVE.eq(true));
List<User> basicResults = userService.list(basicQuery);
// Advanced QueryWrapper with multiple conditions
QueryWrapper complexQuery = userService.query()
.select(USER.ID, USER.NAME, USER.EMAIL, USER.CREATE_TIME)
.from(User.class)
.where(USER.AGE.between(25, 45))
.and(USER.ACTIVE.eq(true))
.and(USER.DEPARTMENT.in("IT", "Engineering", "Product"))
.orderBy(USER.CREATE_TIME.desc(), USER.NAME.asc())
.limit(50);
List<User> complexResults = userService.list(complexQuery);
// Query chaining for fluent operations
List<User> chainedUsers = userService.queryChain()
.select(USER.ID, USER.NAME, USER.EMAIL)
.where(USER.AGE.between(25, 35))
.and(USER.ACTIVE.eq(true))
.orderBy(USER.NAME.asc())
.limit(10)
.list();
// Count with chaining
long count = userService.queryChain()
.where(USER.CITY.eq("New York"))
.and(USER.ACTIVE.eq(true))
.count();
// Single result with chaining
User singleUser = userService.queryChain()
.where(USER.EMAIL.eq("john@example.com"))
.and(USER.ACTIVE.eq(true))
.one();
// Pagination with chaining
Page<User> pageResult = userService.queryChain()
.where(USER.DEPARTMENT.eq("IT"))
.orderBy(USER.CREATE_TIME.desc())
.page(new Page<>(1, 20));
// Update chaining for fluent updates
boolean updated = userService.updateChain()
.set(USER.ACTIVE, false)
.set(USER.UPDATE_TIME, new Date())
.set(USER.DEACTIVATION_REASON, "Inactive for 6 months")
.where(USER.LAST_LOGIN_TIME.lt(sixMonthsAgo))
.and(USER.ACTIVE.eq(true))
.update();
// Batch update with chaining
long updateCount = userService.updateChain()
.set(USER.STATUS, "VERIFIED")
.set(USER.VERIFICATION_DATE, new Date())
.where(USER.EMAIL_VERIFIED.eq(true))
.and(USER.PHONE_VERIFIED.eq(true))
.and(USER.STATUS.eq("PENDING"))
.count(); // Returns number of affected rows
}// Service layer types
public interface IService<T> {
int DEFAULT_BATCH_SIZE = 1000;
BaseMapper<T> getMapper();
// All CRUD and query methods...
}
// Query wrapper types
public interface QueryWrapper {
QueryWrapper select(QueryColumn... columns);
QueryWrapper from(Class<?> entityClass);
QueryWrapper where(QueryCondition condition);
QueryWrapper and(QueryCondition condition);
QueryWrapper orderBy(QueryColumn... columns);
QueryWrapper limit(long limit);
static QueryWrapper create();
}
public interface QueryCondition {
QueryCondition and(QueryCondition condition);
QueryCondition or(QueryCondition condition);
}
// Chain interfaces
public interface QueryChain<T> {
QueryChain<T> select(QueryColumn... columns);
QueryChain<T> where(QueryCondition condition);
QueryChain<T> and(QueryCondition condition);
QueryChain<T> orderBy(QueryColumn... columns);
QueryChain<T> limit(long limit);
T one();
List<T> list();
Page<T> page(Page<T> page);
long count();
}
public interface UpdateChain<T> {
UpdateChain<T> set(String column, Object value);
UpdateChain<T> set(QueryColumn column, Object value);
UpdateChain<T> where(QueryCondition condition);
UpdateChain<T> and(QueryCondition condition);
boolean update();
long count();
}
// Page and mapper types
public interface BaseMapper<T> {
int insert(T entity, boolean ignoreNulls);
int insertOrUpdate(T entity, boolean ignoreNulls);
int delete(T entity);
int deleteById(Serializable id);
int update(T entity, boolean ignoreNulls);
T selectOneById(Serializable id);
List<T> selectListByQuery(QueryWrapper query);
// ... other mapper methods
}
public class Page<T> {
private long pageNumber; // Current page number
private long pageSize; // Page size
private long totalRow; // Total records
private long totalPage; // Total pages
private List<T> records; // Page data
public Page(long pageNumber, long pageSize);
public long getTotalRow();
public long getTotalPage();
public List<T> getRecords();
}
// Standard Java types
public interface Optional<T> {
boolean isPresent();
T get();
T orElse(T other);
T orElseGet(Supplier<? extends T> other);
<U> Optional<U> map(Function<? super T, ? extends U> mapper);
void ifPresent(Consumer<? super T> consumer);
}
public interface Collection<E> extends Iterable<E> {
int size();
boolean isEmpty();
boolean contains(Object o);
boolean add(E e);
boolean remove(Object o);
}
public interface Map<K,V> {
V get(Object key);
V put(K key, V value);
boolean isEmpty();
int size();
}
public interface Serializable {
// Marker interface for primary key types (Long, String, Integer, etc.)
}Install with Tessl CLI
npx tessl i tessl/maven-com-mybatis-flex--mybatis-flex-core