From e26661003f9231b7772b98307755f95b625b993b Mon Sep 17 00:00:00 2001
From: LeO
+ * If the rootInterface contains a generic placeholder like {@code Important: MBG does not verify that the interface exists, or is a
valid Java interface. If specified, the value of this property should be a fully qualified
- interface name (like com.mycompany.MyRootInterface). Generic Type Support: If the root interface is a generic interface, you can
+ use a placeholder for the type parameter. The placeholder will be automatically
+ replaced with the actual record type for each table. For example:
+
+ *
+ *
+ * @param rootInterface
+ * the rootInterface string from configuration, may contain generic placeholders
+ * @param recordType
+ * the actual record type (fully qualified) to use as replacement
+ * @return the processed rootInterface string with placeholders replaced, or the original string if no
+ * replacement is needed
+ */
+ protected String processRootInterfaceWithGenerics(String rootInterface, String recordType) {
+ if (!stringHasValue(rootInterface) || !stringHasValue(recordType)) {
+ return rootInterface;
+ }
+
+ // Check if rootInterface contains generic brackets
+ int openBracketIndex = rootInterface.indexOf('<');
+ if (openBracketIndex == -1) {
+ // No generic brackets, return as-is for backward compatibility
+ return rootInterface;
+ }
+
+ int closeBracketIndex = rootInterface.lastIndexOf('>');
+ if (closeBracketIndex == -1 || closeBracketIndex <= openBracketIndex) {
+ // Malformed generic brackets, return as-is
+ return rootInterface;
+ }
+
+ String baseInterface = rootInterface.substring(0, openBracketIndex);
+ String genericContent = rootInterface.substring(openBracketIndex + 1, closeBracketIndex).trim();
+
+ // Check if the generic content is a placeholder (single letter or single letter with extends clause)
+ // Common Java generic type parameter names: T, E, K, V, N, U, R, S
+ if (isGenericPlaceholder(genericContent)) {
+ // Replace placeholder with actual record type
+ return baseInterface + "<" + recordType + ">";
+ }
+
+ // Already has a concrete type (fully qualified or not), return as-is
+ return rootInterface;
+ }
+
+ /**
+ * Checks if a generic content string represents a placeholder that should be replaced.
+ * Placeholders are typically single-letter type parameters like T, E, K, V, etc.,
+ * optionally with an "extends" clause like "T extends Entity".
+ *
+ * @param genericContent
+ * the content between angle brackets
+ * @return true if this looks like a placeholder that should be replaced
+ */
+ private boolean isGenericPlaceholder(String genericContent) {
+ if (genericContent.isEmpty()) {
+ return false;
+ }
+
+ String trimmed = genericContent.trim();
+
+ // Simple case: just a single uppercase letter (T, E, K, V, etc.)
+ if (trimmed.length() == 1 && Character.isUpperCase(trimmed.charAt(0))) {
+ return true;
+ }
+
+ // Case with bounds: "T extends SomeClass" or "T super SomeClass"
+ // Pattern: single uppercase letter followed by " extends " or " super "
+ int extendsIndex = trimmed.indexOf(" extends ");
+ int superIndex = trimmed.indexOf(" super ");
+
+ if (extendsIndex > 0 || superIndex > 0) {
+ int boundIndex = extendsIndex > 0 ? extendsIndex : superIndex;
+ // First part should be a single uppercase letter
+ String typeParam = trimmed.substring(0, boundIndex).trim();
+ if (typeParam.length() == 1 && Character.isUpperCase(typeParam.charAt(0))) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/core/mybatis-generator-core/src/main/java/org/mybatis/generator/codegen/mybatis3/javamapper/JavaMapperGenerator.java b/core/mybatis-generator-core/src/main/java/org/mybatis/generator/codegen/mybatis3/javamapper/JavaMapperGenerator.java
index 6a4f34528..d7fc673ec 100644
--- a/core/mybatis-generator-core/src/main/java/org/mybatis/generator/codegen/mybatis3/javamapper/JavaMapperGenerator.java
+++ b/core/mybatis-generator-core/src/main/java/org/mybatis/generator/codegen/mybatis3/javamapper/JavaMapperGenerator.java
@@ -75,7 +75,10 @@ public List
+
+ Placeholders are typically single uppercase letters (T, E, K, V, etc.) optionally
+ followed by " extends ..." or " super ...". If you specify a fully qualified type
+ (like com.mycompany.BaseMapper<T> will become
+ com.mycompany.BaseMapper<com.example.User> for a User tablecom.mycompany.BaseMapper<T extends Entity> will become
+ com.mycompany.BaseMapper<com.example.User>BaseMapper<com.example.User>), it will be used as-is without
+ replacement.
Important: MBG does not verify that the interface exists, or is a valid Java interface.
If specified, the value of this property should be a fully qualified - interface name (like com.mycompany.MyRootInterface).
+ interface name (like com.mycompany.MyRootInterface). +Generic Type Support: If the root interface is a generic interface, you can + use a placeholder for the type parameter. The placeholder will be automatically + replaced with the actual record type for this table. For example: +
com.mycompany.BaseMapper<T> will become
+ com.mycompany.BaseMapper<com.example.User>com.mycompany.BaseMapper<T extends Entity> will become
+ com.mycompany.BaseMapper<com.example.User>BaseMapper<com.example.User>), it will be used as-is without
+ replacement.