MyBatis-Flex is an elegant enhancement framework for MyBatis providing type-safe query building, active record patterns, and comprehensive ORM capabilities
—
Comprehensive database dialect system supporting 40+ database types including MySQL, PostgreSQL, Oracle, SQL Server, and specialized databases. MyBatis-Flex automatically handles database-specific SQL generation and optimization.
Comprehensive enumeration of supported database types with automatic dialect detection and SQL generation.
/**
* Enumeration of supported database types
*/
public enum DbType {
// Major Commercial Databases
MYSQL, MARIADB, POSTGRESQL, ORACLE, SQL_SERVER, DB2,
// Embedded Databases
H2, SQLITE, DERBY, HSQL,
// Cloud Databases
REDSHIFT, SNOWFLAKE, BIGQUERY,
// Chinese Databases
DM, KINGBASE, GBASE, OSCAR, OPENGAUSS,
// In-Memory Databases
SAP_HANA, IGNITE,
// Big Data & Analytics
CLICKHOUSE, HIVE, TRINO, IMPALA, PRESTO,
// NoSQL with SQL Interface
CASSANDRA, ELASTICSEARCH,
// Other Databases
FIREBIRD, INFORMIX, SYBASE, ACCESS,
PHOENIX, KYLIN, CUBRID, EDB,
// Time Series Databases
INFLUXDB, QUESTDB,
// Additional Chinese Databases
HIGHGO, VASTBASE, YASHANDB, ANTDB,
// Specialized Databases
LEALONE, SUNDB, XUGU, GREENPLUM;
/**
* Get database type from JDBC URL
* @param jdbcUrl JDBC connection URL
* @return detected DbType
*/
public static DbType getDbType(String jdbcUrl);
/**
* Check if database supports specific feature
* @param feature database feature to check
* @return true if supported
*/
public boolean supports(DatabaseFeature feature);
}Database Type Detection:
import com.mybatisflex.core.dialect.DbType;
public class DatabaseDetectionExample {
public void demonstrateDetection() {
// Automatic detection from JDBC URL
String mysqlUrl = "jdbc:mysql://localhost:3306/testdb";
DbType mysqlType = DbType.getDbType(mysqlUrl);
// Returns: DbType.MYSQL
String postgresUrl = "jdbc:postgresql://localhost:5432/testdb";
DbType postgresType = DbType.getDbType(postgresUrl);
// Returns: DbType.POSTGRESQL
String oracleUrl = "jdbc:oracle:thin:@localhost:1521:xe";
DbType oracleType = DbType.getDbType(oracleUrl);
// Returns: DbType.ORACLE
String sqlServerUrl = "jdbc:sqlserver://localhost:1433;databaseName=testdb";
DbType sqlServerType = DbType.getDbType(sqlServerUrl);
// Returns: DbType.SQL_SERVER
// Chinese databases
String dmUrl = "jdbc:dm://localhost:5236/testdb";
DbType dmType = DbType.getDbType(dmUrl);
// Returns: DbType.DM
String kingbaseUrl = "jdbc:kingbase8://localhost:54321/testdb";
DbType kingbaseType = DbType.getDbType(kingbaseUrl);
// Returns: DbType.KINGBASE
}
}Database-specific SQL generation interface that handles dialect differences and optimizations.
/**
* Database dialect interface for SQL generation
*/
public interface IDialect {
/**
* Generate SELECT SQL for query
* @param queryWrapper query wrapper
* @return generated SQL string
*/
String forSelectByQuery(QueryWrapper queryWrapper);
/**
* Generate paginated SELECT SQL
* @param queryWrapper query wrapper
* @param offset result offset
* @param rows number of rows
* @return paginated SQL string
*/
String forPaginateQuery(QueryWrapper queryWrapper, long offset, long rows);
/**
* Generate INSERT SQL for entity
* @param entityClass entity class
* @return INSERT SQL template
*/
String forInsert(Class<?> entityClass);
/**
* Generate UPDATE SQL for entity
* @param entityClass entity class
* @return UPDATE SQL template
*/
String forUpdate(Class<?> entityClass);
/**
* Generate DELETE SQL for entity
* @param entityClass entity class
* @return DELETE SQL template
*/
String forDelete(Class<?> entityClass);
/**
* Wrap keyword with database-specific quotes
* @param keyword SQL keyword or identifier
* @return wrapped keyword
*/
String wrap(String keyword);
/**
* Get limit offset processor for pagination
* @return LimitOffsetProcessor instance
*/
LimitOffsetProcessor getLimitOffsetProcessor();
/**
* Get keyword wrapper for identifiers
* @return KeywordWrap instance
*/
KeywordWrap getKeywordWrap();
/**
* Get data source key for multi-datasource scenarios
* @return datasource key
*/
String getDataSourceKey();
}Dialect Usage Examples:
import com.mybatisflex.core.dialect.IDialect;
import com.mybatisflex.core.dialect.impl.*;
public class DialectExample {
public void demonstrateDialects() {
// MySQL dialect
IDialect mysqlDialect = new MysqlDialect();
String mysqlWrapped = mysqlDialect.wrap("user");
// Returns: `user`
// PostgreSQL dialect
IDialect postgresDialect = new PostgresqlDialect();
String postgresWrapped = postgresDialect.wrap("user");
// Returns: "user"
// Oracle dialect
IDialect oracleDialect = new OracleDialect();
String oracleWrapped = oracleDialect.wrap("user");
// Returns: "USER"
// SQL Server dialect
IDialect sqlServerDialect = new SqlserverDialectImpl();
String sqlServerWrapped = sqlServerDialect.wrap("user");
// Returns: [user]
// Generate paginated query
QueryWrapper query = QueryWrapper.create()
.select()
.from(User.class)
.where(USER.ACTIVE.eq(true));
String mysqlPaginated = mysqlDialect.forPaginateQuery(query, 0, 10);
// MySQL: SELECT ... LIMIT 10 OFFSET 0
String sqlServerPaginated = sqlServerDialect.forPaginateQuery(query, 0, 10);
// SQL Server: SELECT ... OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY
}
}Concrete dialect implementations for major database systems.
// MySQL/MariaDB
public class MysqlDialect implements IDialect {
// MySQL-specific SQL generation
}
// PostgreSQL
public class PostgresqlDialect implements IDialect {
// PostgreSQL-specific SQL generation
}
// Oracle
public class OracleDialect implements IDialect {
// Oracle-specific SQL generation
}
// SQL Server
public class SqlserverDialectImpl implements IDialect {
// SQL Server-specific SQL generation
}
// DB2
public class DB2Dialect implements IDialect {
// DB2-specific SQL generation
}
// ClickHouse
public class ClickhouseDialectImpl implements IDialect {
// ClickHouse-specific SQL generation
}
// Chinese Database Dialects
public class DmDialect implements IDialect {
// DM (达梦) database-specific SQL generation
}
public class KingbaseDialect implements IDialect {
// Kingbase (人大金仓) database-specific SQL generation
}
public class GbaseDialect implements IDialect {
// GBase database-specific SQL generation
}Handles database-specific pagination SQL generation.
/**
* Processes LIMIT and OFFSET clauses for different databases
*/
public interface LimitOffsetProcessor {
/**
* Process pagination for query
* @param sql original SQL
* @param offset result offset
* @param limit maximum rows
* @return paginated SQL
*/
String process(String sql, long offset, long limit);
/**
* Check if database supports OFFSET clause
* @return true if supported
*/
boolean supportsOffset();
/**
* Check if database supports LIMIT clause
* @return true if supported
*/
boolean supportsLimit();
}Pagination Examples by Database:
public class PaginationExamples {
public void demonstratePagination() {
String baseSql = "SELECT id, name FROM users WHERE active = 1";
// MySQL/PostgreSQL: LIMIT OFFSET
String mysqlPaginated = "SELECT id, name FROM users WHERE active = 1 LIMIT 10 OFFSET 20";
// SQL Server 2012+: OFFSET FETCH
String sqlServerPaginated = "SELECT id, name FROM users WHERE active = 1 " +
"ORDER BY id OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY";
// Oracle: ROWNUM (traditional)
String oraclePaginated = "SELECT * FROM (" +
"SELECT ROWNUM rn, t.* FROM (" +
"SELECT id, name FROM users WHERE active = 1" +
") t WHERE ROWNUM <= 30" +
") WHERE rn > 20";
// Oracle 12c+: OFFSET FETCH
String oracle12cPaginated = "SELECT id, name FROM users WHERE active = 1 " +
"ORDER BY id OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY";
}
}Handles database-specific identifier quoting and keyword escaping.
/**
* Handles keyword wrapping for different databases
*/
public interface KeywordWrap {
/**
* Wrap identifier with database-specific quotes
* @param keyword identifier to wrap
* @return wrapped identifier
*/
String wrap(String keyword);
/**
* Check if keyword needs wrapping
* @param keyword identifier to check
* @return true if wrapping needed
*/
boolean needsWrap(String keyword);
/**
* Get start quote character
* @return start quote
*/
String getStartQuote();
/**
* Get end quote character
* @return end quote
*/
String getEndQuote();
}Keyword Wrapping Examples:
public class KeywordWrappingExamples {
public void demonstrateWrapping() {
// MySQL: Backticks
String mysqlUser = "`user`";
String mysqlOrder = "`order`";
// PostgreSQL: Double quotes
String postgresUser = "\"user\"";
String postgresOrder = "\"order\"";
// SQL Server: Square brackets
String sqlServerUser = "[user]";
String sqlServerOrder = "[order]";
// Oracle: Double quotes (uppercase)
String oracleUser = "\"USER\"";
String oracleOrder = "\"ORDER\"";
// H2: Double quotes
String h2User = "\"user\"";
String h2Order = "\"order\"";
}
}Defines database capabilities and features for feature detection.
/**
* Database feature enumeration for capability detection
*/
public enum DatabaseFeature {
// SQL Standard Features
LIMIT_OFFSET,
WINDOW_FUNCTIONS,
COMMON_TABLE_EXPRESSIONS,
RECURSIVE_CTE,
// Join Types
FULL_OUTER_JOIN,
CROSS_JOIN,
NATURAL_JOIN,
// Data Types
JSON_TYPE,
ARRAY_TYPE,
UUID_TYPE,
BOOLEAN_TYPE,
// Advanced Features
UPSERT,
MERGE_STATEMENT,
RETURNING_CLAUSE,
BULK_INSERT,
// Index Features
PARTIAL_INDEX,
EXPRESSION_INDEX,
UNIQUE_INDEX,
// Transaction Features
SAVEPOINTS,
READ_UNCOMMITTED,
SERIALIZABLE,
// Specific SQL Features
REGEXP_OPERATOR,
CASE_INSENSITIVE_LIKE,
NULLS_FIRST_LAST,
// Chinese Database Features
ENCRYPT_COLUMN,
AUDIT_TRAIL,
ROW_LEVEL_SECURITY;
}Feature Detection Examples:
public class FeatureDetectionExample {
public void demonstrateFeatureDetection() {
// Check database capabilities
boolean mysqlSupportsJson = DbType.MYSQL.supports(DatabaseFeature.JSON_TYPE);
// Returns: true (MySQL 5.7+)
boolean sqliteSupportsWindowFunctions = DbType.SQLITE.supports(DatabaseFeature.WINDOW_FUNCTIONS);
// Returns: true (SQLite 3.25+)
boolean h2SupportsUpsert = DbType.H2.supports(DatabaseFeature.UPSERT);
// Returns: true
boolean accessSupportsFullOuterJoin = DbType.ACCESS.supports(DatabaseFeature.FULL_OUTER_JOIN);
// Returns: false
// Use feature detection in code
if (DbType.POSTGRESQL.supports(DatabaseFeature.RETURNING_CLAUSE)) {
// Use PostgreSQL RETURNING clause
String sql = "INSERT INTO users (name, email) VALUES (?, ?) RETURNING id";
} else {
// Fallback approach
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
}
}
}Integration with global configuration for automatic dialect selection.
/**
* Database configuration in FlexGlobalConfig
*/
public class FlexGlobalConfig {
/**
* Set database type for automatic dialect selection
* @param dbType database type
*/
public void setDbType(DbType dbType);
/**
* Get configured database type
* @return database type
*/
public DbType getDbType();
/**
* Set custom dialect implementation
* @param dialect custom dialect
*/
public void setDialect(IDialect dialect);
/**
* Get current dialect
* @return dialect implementation
*/
public IDialect getDialect();
}Configuration Examples:
public class DatabaseConfigurationExample {
public void configureDatabase() {
// Automatic configuration
FlexGlobalConfig config = FlexGlobalConfig.getDefaultConfig();
config.setDbType(DbType.POSTGRESQL);
// Custom dialect
IDialect customDialect = new CustomPostgresDialect();
config.setDialect(customDialect);
// Multi-database configuration
FlexGlobalConfig mysqlConfig = new FlexGlobalConfig();
mysqlConfig.setDbType(DbType.MYSQL);
FlexGlobalConfig.setConfig("mysql", mysqlConfig, false);
FlexGlobalConfig postgresConfig = new FlexGlobalConfig();
postgresConfig.setDbType(DbType.POSTGRESQL);
FlexGlobalConfig.setConfig("postgres", postgresConfig, false);
}
}// Core dialect types
public enum DbType {
MYSQL, POSTGRESQL, ORACLE, SQL_SERVER, DB2,
H2, SQLITE, CLICKHOUSE, DM, KINGBASE;
public static DbType getDbType(String jdbcUrl);
public boolean supports(DatabaseFeature feature);
}
public interface IDialect {
String forSelectByQuery(QueryWrapper queryWrapper);
String forPaginateQuery(QueryWrapper queryWrapper, long offset, long rows);
String wrap(String keyword);
}
// Feature detection
public enum DatabaseFeature {
LIMIT_OFFSET, WINDOW_FUNCTIONS, JSON_TYPE, UPSERT, RETURNING_CLAUSE;
}
// Pagination processing
public interface LimitOffsetProcessor {
String process(String sql, long offset, long limit);
boolean supportsOffset();
boolean supportsLimit();
}
// Keyword wrapping
public interface KeywordWrap {
String wrap(String keyword);
boolean needsWrap(String keyword);
String getStartQuote();
String getEndQuote();
}Install with Tessl CLI
npx tessl i tessl/maven-com-mybatis-flex--mybatis-flex-core