diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToMany.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToMany.java index 5f1c48a5..c7ae563b 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToMany.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToMany.java @@ -34,6 +34,20 @@ public @interface RelationManyToMany { */ String selfField() default ""; + /** + * 目标实体类对应的表的 schema,一般关联数据不是 entity,而是 vo、dto 等需要配置此项 + * + * @return schema 名称 + */ + String targetSchema() default ""; + + /** + * 目标实体类对应的表,一般关联数据不是 entity,而是 vo、dto 等需要配置此项 + * + * @return 表名 + */ + String targetTable() default ""; + /** * 目标实体类的关联属性。 * diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToOne.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToOne.java index 0bbf4aff..c1864ed2 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToOne.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationManyToOne.java @@ -34,6 +34,20 @@ public @interface RelationManyToOne { */ String selfField(); + /** + * 目标实体类对应的表的 schema,一般关联数据不是 entity,而是 vo、dto 等需要配置此项 + * + * @return schema 名称 + */ + String targetSchema() default ""; + + /** + * 目标实体类对应的表,一般关联数据不是 entity,而是 vo、dto 等需要配置此项 + * + * @return 表名 + */ + String targetTable() default ""; + /** * 目标实体类的关联属性。 * diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java index 5fcdf7f0..dccce6be 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToMany.java @@ -34,6 +34,20 @@ public @interface RelationOneToMany { */ String selfField() default ""; + /** + * 目标实体类对应的表的 schema,一般关联数据不是 entity,而是 vo、dto 等需要配置此项 + * + * @return schema 名称 + */ + String targetSchema() default ""; + + /** + * 目标实体类对应的表,一般关联数据不是 entity,而是 vo、dto 等需要配置此项 + * + * @return 表名 + */ + String targetTable() default ""; + /** * 目标实体类的关联属性。 * diff --git a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToOne.java b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToOne.java index ca79ecf0..a881e84c 100644 --- a/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToOne.java +++ b/mybatis-flex-annotation/src/main/java/com/mybatisflex/annotation/RelationOneToOne.java @@ -34,18 +34,32 @@ public @interface RelationOneToOne { */ String selfField() default ""; + /** + * 目标实体类对应的表的 schema,一般关联数据不是 entity,而是 vo、dto 等需要配置此项 + * + * @return schema 名称 + */ + String targetSchema() default ""; + + /** + * 目标实体类对应的表,一般关联数据不是 entity,而是 vo、dto 等需要配置此项 + * + * @return 表名 + */ + String targetTable() default ""; + /** * 目标实体类的关联属性。 * * @return 属性名称 - */ + */ String targetField(); /** * 默认使用哪个数据源,若系统找不到该指定的数据源时,默认使用第一个数据源。 * * @return 数据源 - */ - String dataSource() default ""; + */ + String dataSource() default ""; } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/AbstractRelation.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/AbstractRelation.java index 92eb6f32..0d5938a4 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/AbstractRelation.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/AbstractRelation.java @@ -40,6 +40,8 @@ abstract class AbstractRelation { protected Field selfField; protected FieldWrapper selfFieldWrapper; + protected String targetSchema; + protected String targetTable; protected Field targetField; protected Class targetEntityClass; protected TableInfo targetTableInfo; @@ -47,7 +49,8 @@ abstract class AbstractRelation { protected String dataSource; - public AbstractRelation(String selfField, String targetField, String dataSource, Class entityClass, Field relationField) { + public AbstractRelation(String selfField, String targetSchema, String targetTable, String targetField, + String dataSource, Class entityClass, Field relationField) { this.selfEntityClass = entityClass; this.relationField = relationField; this.relationFieldWrapper = FieldWrapper.of(entityClass, relationField.getName()); @@ -59,6 +62,8 @@ abstract class AbstractRelation { this.targetEntityClass = relationFieldWrapper.getMappingType(); + this.targetSchema = targetSchema; + this.targetTable = targetTable; this.targetField = ClassUtil.getFirstField(targetEntityClass, field -> field.getName().equals(targetField)); this.targetFieldWrapper = FieldWrapper.of(targetEntityClass, targetField); @@ -159,15 +164,24 @@ abstract class AbstractRelation { return relationFieldWrapper.getMappingType(); } - public String getDataSource() { - return dataSource; - } + public String getDataSource() { + return dataSource; + } - public void setDataSource(String dataSource) { - this.dataSource = dataSource; - } + public void setDataSource(String dataSource) { + this.dataSource = dataSource; + } - protected static Class getTargetEntityClass(Class entityClass, Field relationField) { + public String getTargetTableWithSchema() { + if (StringUtil.isNotBlank(targetTable)) { + return StringUtil.isNotBlank(targetSchema) ? targetSchema + "." + targetTable : targetTable; + } else { + return targetTableInfo.getTableNameWithSchema(); + } + } + + + protected static Class getTargetEntityClass(Class entityClass, Field relationField) { return FieldWrapper.of(entityClass, relationField.getName()).getMappingType(); } @@ -186,20 +200,21 @@ abstract class AbstractRelation { } - - /** - * 把 Relations 的配置转换为查询的 QueryWrapper - * @param selfEntities 当前的实体类 - * @return QueryWrapper - */ - public abstract QueryWrapper toQueryWrapper(List selfEntities); + /** + * 把 Relations 的配置转换为查询的 QueryWrapper + * + * @param selfEntities 当前的实体类 + * @return QueryWrapper + */ + public abstract QueryWrapper toQueryWrapper(List selfEntities); - /** - * 通过 {@link AbstractRelation#toQueryWrapper(List)} 查询到的结果,通过此方法进行内存 join - * @param selfEntities 当前的实体类列表 - * @param targetObjectList 查询到的结果 - * @param mapper 查询的 Mapper - */ - public abstract void join(List selfEntities, List targetObjectList, BaseMapper mapper); + /** + * 通过 {@link AbstractRelation#toQueryWrapper(List)} 查询到的结果,通过此方法进行内存 join + * + * @param selfEntities 当前的实体类列表 + * @param targetObjectList 查询到的结果 + * @param mapper 查询的 Mapper + */ + public abstract void join(List selfEntities, List targetObjectList, BaseMapper mapper); } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToMany.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToMany.java index 3a7b1a46..acda7d36 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToMany.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToMany.java @@ -31,107 +31,109 @@ import static com.mybatisflex.core.query.QueryMethods.column; class ManyToMany extends AbstractRelation { - private String joinTable; - private String joinSelfColumn; - private String joinTargetColumn; + private String joinTable; + private String joinSelfColumn; + private String joinTargetColumn; - private String orderBy; + private String orderBy; - public ManyToMany(RelationManyToMany annotation, Class entityClass, Field relationField) { - super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationManyToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\""), - getDefaultPrimaryProperty(annotation.targetField(), getTargetEntityClass(entityClass, relationField), "@RelationManyToMany.targetField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\""), - annotation.dataSource(), entityClass, relationField); + public ManyToMany(RelationManyToMany annotation, Class entityClass, Field relationField) { + super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationManyToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") + , annotation.targetSchema() + , annotation.targetTable() + , getDefaultPrimaryProperty(annotation.targetField(), getTargetEntityClass(entityClass, relationField), "@RelationManyToMany.targetField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") + , annotation.dataSource(), entityClass, relationField); - this.joinTable = annotation.joinTable(); - this.joinSelfColumn = annotation.joinSelfColumn(); - this.joinTargetColumn = annotation.joinTargetColumn(); + this.joinTable = annotation.joinTable(); + this.joinSelfColumn = annotation.joinSelfColumn(); + this.joinTargetColumn = annotation.joinTargetColumn(); - this.orderBy = annotation.orderBy(); - } + this.orderBy = annotation.orderBy(); + } - @Override - public Class getMappingType() { - return Row.class; - } + @Override + public Class getMappingType() { + return Row.class; + } - @Override - public QueryWrapper toQueryWrapper(List selfEntities) { - Set selfFieldValues = getSelfFieldValues(selfEntities); - if (selfFieldValues.isEmpty()) { - return null; - } + @Override + public QueryWrapper toQueryWrapper(List selfEntities) { + Set selfFieldValues = getSelfFieldValues(selfEntities); + if (selfFieldValues.isEmpty()) { + return null; + } - QueryWrapper queryWrapper = QueryWrapper.create().select() - .from(joinTable); - if (selfFieldValues.size() > 1) { - queryWrapper.where(column(joinSelfColumn).in(selfFieldValues)); - } else { - queryWrapper.where(column(joinSelfColumn).eq(selfFieldValues.iterator().next())); - } + QueryWrapper queryWrapper = QueryWrapper.create().select() + .from(joinTable); + if (selfFieldValues.size() > 1) { + queryWrapper.where(column(joinSelfColumn).in(selfFieldValues)); + } else { + queryWrapper.where(column(joinSelfColumn).eq(selfFieldValues.iterator().next())); + } - return queryWrapper; - } + return queryWrapper; + } - @Override - public void join(List selfEntities, List mappingObjectList, BaseMapper mapper) { - List mappingRows = (List) mappingObjectList; - Set targetValues = new LinkedHashSet<>(); - for (Row row : mappingRows) { - Object targetValue = row.getIgnoreCase(joinTargetColumn); - if (targetValue != null) { - targetValues.add(targetValue); - } - } + @Override + public void join(List selfEntities, List mappingObjectList, BaseMapper mapper) { + List mappingRows = (List) mappingObjectList; + Set targetValues = new LinkedHashSet<>(); + for (Row row : mappingRows) { + Object targetValue = row.getIgnoreCase(joinTargetColumn); + if (targetValue != null) { + targetValues.add(targetValue); + } + } - if (targetValues.isEmpty()) { - return; - } + if (targetValues.isEmpty()) { + return; + } - QueryWrapper queryWrapper = QueryWrapper.create().select() - .from(targetTableInfo.getTableNameWithSchema()); - if (targetValues.size() > 1) { - queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(targetValues)); - } else { - queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).eq(targetValues.iterator().next())); - } + QueryWrapper queryWrapper = QueryWrapper.create().select() + .from(getTargetTableWithSchema()); + if (targetValues.size() > 1) { + queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(targetValues)); + } else { + queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).eq(targetValues.iterator().next())); + } - if (StringUtil.isNotBlank(orderBy)) { - queryWrapper.orderBy(orderBy); - } + if (StringUtil.isNotBlank(orderBy)) { + queryWrapper.orderBy(orderBy); + } - List targetObjectList = mapper.selectListByQueryAs(queryWrapper, relationFieldWrapper.getMappingType()); + List targetObjectList = mapper.selectListByQueryAs(queryWrapper, relationFieldWrapper.getMappingType()); - if (CollectionUtil.isNotEmpty(targetObjectList)) { - selfEntities.forEach(selfEntity -> { - Object selfValue = selfFieldWrapper.get(selfEntity); - if (selfValue != null) { - selfValue = selfValue.toString(); - Set targetMappingValues = new HashSet<>(); - for (Row mappingRow : mappingRows) { - if (selfValue.equals(String.valueOf(mappingRow.getIgnoreCase(joinSelfColumn)))) { - Object joinValue = mappingRow.getIgnoreCase(joinTargetColumn); - if (joinValue != null) { - targetMappingValues.add(joinValue.toString()); - } - } - } + if (CollectionUtil.isNotEmpty(targetObjectList)) { + selfEntities.forEach(selfEntity -> { + Object selfValue = selfFieldWrapper.get(selfEntity); + if (selfValue != null) { + selfValue = selfValue.toString(); + Set targetMappingValues = new HashSet<>(); + for (Row mappingRow : mappingRows) { + if (selfValue.equals(String.valueOf(mappingRow.getIgnoreCase(joinSelfColumn)))) { + Object joinValue = mappingRow.getIgnoreCase(joinTargetColumn); + if (joinValue != null) { + targetMappingValues.add(joinValue.toString()); + } + } + } - if (!targetMappingValues.isEmpty()) { - Class wrapType = MapperUtil.getWrapType(relationFieldWrapper.getFieldType()); - Collection collection = (Collection) ClassUtil.newInstance(wrapType); - for (Object targetObject : targetObjectList) { - Object targetValue = targetFieldWrapper.get(targetObject); - if (targetValue != null && targetMappingValues.contains(targetValue.toString())) { - collection.add(targetObject); - } - } - relationFieldWrapper.set(collection, selfEntity); - } - } - }); - } - } + if (!targetMappingValues.isEmpty()) { + Class wrapType = MapperUtil.getWrapType(relationFieldWrapper.getFieldType()); + Collection collection = (Collection) ClassUtil.newInstance(wrapType); + for (Object targetObject : targetObjectList) { + Object targetValue = targetFieldWrapper.get(targetObject); + if (targetValue != null && targetMappingValues.contains(targetValue.toString())) { + collection.add(targetObject); + } + } + relationFieldWrapper.set(collection, selfEntity); + } + } + }); + } + } } diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToOne.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToOne.java index c847fc21..89d0ef7e 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToOne.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ManyToOne.java @@ -23,6 +23,8 @@ class ManyToOne extends ToOneRelation { public ManyToOne(RelationManyToOne annotation, Class entityClass, Field relationField) { super(annotation.selfField() + , annotation.targetSchema() + , annotation.targetTable() , getDefaultPrimaryProperty(annotation.targetField(), getTargetEntityClass(entityClass, relationField) , "@RelationManyToOne.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") , annotation.dataSource() diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToMany.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToMany.java index 944853f2..9103358a 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToMany.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToMany.java @@ -37,6 +37,8 @@ class OneToMany extends AbstractRelation { public OneToMany(RelationOneToMany annotation, Class entityClass, Field relationField) { super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationOneToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") + , annotation.targetSchema() + , annotation.targetTable() , annotation.targetField(), annotation.dataSource(), entityClass, relationField); this.orderBy = annotation.orderBy(); this.limit = annotation.limit(); @@ -49,7 +51,7 @@ class OneToMany extends AbstractRelation { return null; } QueryWrapper queryWrapper = QueryWrapper.create().select() - .from(targetTableInfo.getTableNameWithSchema()); + .from(getTargetTableWithSchema()); if (selfFieldValues.size() > 1) { queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(selfFieldValues)); } else { diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToOne.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToOne.java index d8daca62..45bb9a04 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToOne.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/OneToOne.java @@ -24,6 +24,8 @@ class OneToOne extends ToOneRelation { public OneToOne(RelationOneToOne annotation, Class entityClass, Field relationField) { super(getDefaultPrimaryProperty(annotation.selfField(), entityClass , "@RelationOneToOne.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") + , annotation.targetSchema() + , annotation.targetTable() , annotation.targetField() , annotation.dataSource() , entityClass diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToOneRelation.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToOneRelation.java index 19e64812..aba1042c 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToOneRelation.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToOneRelation.java @@ -27,10 +27,12 @@ import static com.mybatisflex.core.query.QueryMethods.column; class ToOneRelation extends AbstractRelation { - public ToOneRelation(String selfField, String targetField, String dataSource, Class selfEntityClass, Field relationField) { - super(selfField, targetField, dataSource, selfEntityClass, relationField); + public ToOneRelation(String selfField, String targetSchema, String targetTable, String targetField, + String dataSource, Class selfEntityClass, Field relationField) { + super(selfField, targetSchema, targetTable, targetField, dataSource, selfEntityClass, relationField); } + @Override public QueryWrapper toQueryWrapper(List selfEntities) { Set selfFieldValues = getSelfFieldValues(selfEntities); @@ -38,7 +40,7 @@ class ToOneRelation extends AbstractRelation { return null; } QueryWrapper queryWrapper = QueryWrapper.create().select() - .from(targetTableInfo.getTableNameWithSchema()); + .from(getTargetTableWithSchema()); if (selfFieldValues.size() > 1) { queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(selfFieldValues)); } else {