feat: Relation 注解 targetSchema 和 targetTable 的支持。

This commit is contained in:
开源海哥 2023-07-12 11:32:05 +08:00
parent 677eabdbe5
commit 695a90562b
10 changed files with 195 additions and 114 deletions

View File

@ -34,6 +34,20 @@ public @interface RelationManyToMany {
*/ */
String selfField() default ""; String selfField() default "";
/**
* 目标实体类对应的表的 schema一般关联数据不是 entity而是 vodto 等需要配置此项
*
* @return schema 名称
*/
String targetSchema() default "";
/**
* 目标实体类对应的表一般关联数据不是 entity而是 vodto 等需要配置此项
*
* @return 表名
*/
String targetTable() default "";
/** /**
* 目标实体类的关联属性 * 目标实体类的关联属性
* *

View File

@ -34,6 +34,20 @@ public @interface RelationManyToOne {
*/ */
String selfField(); String selfField();
/**
* 目标实体类对应的表的 schema一般关联数据不是 entity而是 vodto 等需要配置此项
*
* @return schema 名称
*/
String targetSchema() default "";
/**
* 目标实体类对应的表一般关联数据不是 entity而是 vodto 等需要配置此项
*
* @return 表名
*/
String targetTable() default "";
/** /**
* 目标实体类的关联属性 * 目标实体类的关联属性
* *

View File

@ -34,6 +34,20 @@ public @interface RelationOneToMany {
*/ */
String selfField() default ""; String selfField() default "";
/**
* 目标实体类对应的表的 schema一般关联数据不是 entity而是 vodto 等需要配置此项
*
* @return schema 名称
*/
String targetSchema() default "";
/**
* 目标实体类对应的表一般关联数据不是 entity而是 vodto 等需要配置此项
*
* @return 表名
*/
String targetTable() default "";
/** /**
* 目标实体类的关联属性 * 目标实体类的关联属性
* *

View File

@ -34,18 +34,32 @@ public @interface RelationOneToOne {
*/ */
String selfField() default ""; String selfField() default "";
/**
* 目标实体类对应的表的 schema一般关联数据不是 entity而是 vodto 等需要配置此项
*
* @return schema 名称
*/
String targetSchema() default "";
/**
* 目标实体类对应的表一般关联数据不是 entity而是 vodto 等需要配置此项
*
* @return 表名
*/
String targetTable() default "";
/** /**
* 目标实体类的关联属性 * 目标实体类的关联属性
* *
* @return 属性名称 * @return 属性名称
*/ */
String targetField(); String targetField();
/** /**
* 默认使用哪个数据源若系统找不到该指定的数据源时默认使用第一个数据源 * 默认使用哪个数据源若系统找不到该指定的数据源时默认使用第一个数据源
* *
* @return 数据源 * @return 数据源
*/ */
String dataSource() default ""; String dataSource() default "";
} }

View File

@ -40,6 +40,8 @@ abstract class AbstractRelation<SelfEntity> {
protected Field selfField; protected Field selfField;
protected FieldWrapper selfFieldWrapper; protected FieldWrapper selfFieldWrapper;
protected String targetSchema;
protected String targetTable;
protected Field targetField; protected Field targetField;
protected Class<?> targetEntityClass; protected Class<?> targetEntityClass;
protected TableInfo targetTableInfo; protected TableInfo targetTableInfo;
@ -47,7 +49,8 @@ abstract class AbstractRelation<SelfEntity> {
protected String dataSource; protected String dataSource;
public AbstractRelation(String selfField, String targetField, String dataSource, Class<SelfEntity> entityClass, Field relationField) { public AbstractRelation(String selfField, String targetSchema, String targetTable, String targetField,
String dataSource, Class<SelfEntity> entityClass, Field relationField) {
this.selfEntityClass = entityClass; this.selfEntityClass = entityClass;
this.relationField = relationField; this.relationField = relationField;
this.relationFieldWrapper = FieldWrapper.of(entityClass, relationField.getName()); this.relationFieldWrapper = FieldWrapper.of(entityClass, relationField.getName());
@ -59,6 +62,8 @@ abstract class AbstractRelation<SelfEntity> {
this.targetEntityClass = relationFieldWrapper.getMappingType(); this.targetEntityClass = relationFieldWrapper.getMappingType();
this.targetSchema = targetSchema;
this.targetTable = targetTable;
this.targetField = ClassUtil.getFirstField(targetEntityClass, field -> field.getName().equals(targetField)); this.targetField = ClassUtil.getFirstField(targetEntityClass, field -> field.getName().equals(targetField));
this.targetFieldWrapper = FieldWrapper.of(targetEntityClass, targetField); this.targetFieldWrapper = FieldWrapper.of(targetEntityClass, targetField);
@ -159,15 +164,24 @@ abstract class AbstractRelation<SelfEntity> {
return relationFieldWrapper.getMappingType(); return relationFieldWrapper.getMappingType();
} }
public String getDataSource() { public String getDataSource() {
return dataSource; return dataSource;
} }
public void setDataSource(String dataSource) { public void setDataSource(String dataSource) {
this.dataSource = 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(); return FieldWrapper.of(entityClass, relationField.getName()).getMappingType();
} }
@ -186,20 +200,21 @@ abstract class AbstractRelation<SelfEntity> {
} }
/**
/** * Relations 的配置转换为查询的 QueryWrapper
* Relations 的配置转换为查询的 QueryWrapper *
* @param selfEntities 当前的实体类 * @param selfEntities 当前的实体类
* @return QueryWrapper * @return QueryWrapper
*/ */
public abstract QueryWrapper toQueryWrapper(List<SelfEntity> selfEntities); public abstract QueryWrapper toQueryWrapper(List<SelfEntity> selfEntities);
/** /**
* 通过 {@link AbstractRelation#toQueryWrapper(List)} 查询到的结果通过此方法进行内存 join * 通过 {@link AbstractRelation#toQueryWrapper(List)} 查询到的结果通过此方法进行内存 join
* @param selfEntities 当前的实体类列表 *
* @param targetObjectList 查询到的结果 * @param selfEntities 当前的实体类列表
* @param mapper 查询的 Mapper * @param targetObjectList 查询到的结果
*/ * @param mapper 查询的 Mapper
public abstract void join(List<SelfEntity> selfEntities, List<?> targetObjectList, BaseMapper<?> mapper); */
public abstract void join(List<SelfEntity> selfEntities, List<?> targetObjectList, BaseMapper<?> mapper);
} }

View File

@ -31,107 +31,109 @@ import static com.mybatisflex.core.query.QueryMethods.column;
class ManyToMany<SelfEntity> extends AbstractRelation<SelfEntity> { class ManyToMany<SelfEntity> extends AbstractRelation<SelfEntity> {
private String joinTable; private String joinTable;
private String joinSelfColumn; private String joinSelfColumn;
private String joinTargetColumn; private String joinTargetColumn;
private String orderBy; private String orderBy;
public ManyToMany(RelationManyToMany annotation, Class<SelfEntity> entityClass, Field relationField) { public ManyToMany(RelationManyToMany annotation, Class<SelfEntity> entityClass, Field relationField) {
super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationManyToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\""), 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.targetSchema()
annotation.dataSource(), entityClass, relationField); , 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.joinTable = annotation.joinTable();
this.joinSelfColumn = annotation.joinSelfColumn(); this.joinSelfColumn = annotation.joinSelfColumn();
this.joinTargetColumn = annotation.joinTargetColumn(); this.joinTargetColumn = annotation.joinTargetColumn();
this.orderBy = annotation.orderBy(); this.orderBy = annotation.orderBy();
} }
@Override @Override
public Class<?> getMappingType() { public Class<?> getMappingType() {
return Row.class; return Row.class;
} }
@Override @Override
public QueryWrapper toQueryWrapper(List<SelfEntity> selfEntities) { public QueryWrapper toQueryWrapper(List<SelfEntity> selfEntities) {
Set<Object> selfFieldValues = getSelfFieldValues(selfEntities); Set<Object> selfFieldValues = getSelfFieldValues(selfEntities);
if (selfFieldValues.isEmpty()) { if (selfFieldValues.isEmpty()) {
return null; return null;
} }
QueryWrapper queryWrapper = QueryWrapper.create().select() QueryWrapper queryWrapper = QueryWrapper.create().select()
.from(joinTable); .from(joinTable);
if (selfFieldValues.size() > 1) { if (selfFieldValues.size() > 1) {
queryWrapper.where(column(joinSelfColumn).in(selfFieldValues)); queryWrapper.where(column(joinSelfColumn).in(selfFieldValues));
} else { } else {
queryWrapper.where(column(joinSelfColumn).eq(selfFieldValues.iterator().next())); queryWrapper.where(column(joinSelfColumn).eq(selfFieldValues.iterator().next()));
} }
return queryWrapper; return queryWrapper;
} }
@Override @Override
public void join(List<SelfEntity> selfEntities, List<?> mappingObjectList, BaseMapper<?> mapper) { public void join(List<SelfEntity> selfEntities, List<?> mappingObjectList, BaseMapper<?> mapper) {
List<Row> mappingRows = (List<Row>) mappingObjectList; List<Row> mappingRows = (List<Row>) mappingObjectList;
Set<Object> targetValues = new LinkedHashSet<>(); Set<Object> targetValues = new LinkedHashSet<>();
for (Row row : mappingRows) { for (Row row : mappingRows) {
Object targetValue = row.getIgnoreCase(joinTargetColumn); Object targetValue = row.getIgnoreCase(joinTargetColumn);
if (targetValue != null) { if (targetValue != null) {
targetValues.add(targetValue); targetValues.add(targetValue);
} }
} }
if (targetValues.isEmpty()) { if (targetValues.isEmpty()) {
return; return;
} }
QueryWrapper queryWrapper = QueryWrapper.create().select() QueryWrapper queryWrapper = QueryWrapper.create().select()
.from(targetTableInfo.getTableNameWithSchema()); .from(getTargetTableWithSchema());
if (targetValues.size() > 1) { if (targetValues.size() > 1) {
queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(targetValues)); queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(targetValues));
} else { } else {
queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).eq(targetValues.iterator().next())); queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).eq(targetValues.iterator().next()));
} }
if (StringUtil.isNotBlank(orderBy)) { if (StringUtil.isNotBlank(orderBy)) {
queryWrapper.orderBy(orderBy); queryWrapper.orderBy(orderBy);
} }
List<?> targetObjectList = mapper.selectListByQueryAs(queryWrapper, relationFieldWrapper.getMappingType()); List<?> targetObjectList = mapper.selectListByQueryAs(queryWrapper, relationFieldWrapper.getMappingType());
if (CollectionUtil.isNotEmpty(targetObjectList)) { if (CollectionUtil.isNotEmpty(targetObjectList)) {
selfEntities.forEach(selfEntity -> { selfEntities.forEach(selfEntity -> {
Object selfValue = selfFieldWrapper.get(selfEntity); Object selfValue = selfFieldWrapper.get(selfEntity);
if (selfValue != null) { if (selfValue != null) {
selfValue = selfValue.toString(); selfValue = selfValue.toString();
Set<String> targetMappingValues = new HashSet<>(); Set<String> targetMappingValues = new HashSet<>();
for (Row mappingRow : mappingRows) { for (Row mappingRow : mappingRows) {
if (selfValue.equals(String.valueOf(mappingRow.getIgnoreCase(joinSelfColumn)))) { if (selfValue.equals(String.valueOf(mappingRow.getIgnoreCase(joinSelfColumn)))) {
Object joinValue = mappingRow.getIgnoreCase(joinTargetColumn); Object joinValue = mappingRow.getIgnoreCase(joinTargetColumn);
if (joinValue != null) { if (joinValue != null) {
targetMappingValues.add(joinValue.toString()); targetMappingValues.add(joinValue.toString());
} }
} }
} }
if (!targetMappingValues.isEmpty()) { if (!targetMappingValues.isEmpty()) {
Class<?> wrapType = MapperUtil.getWrapType(relationFieldWrapper.getFieldType()); Class<?> wrapType = MapperUtil.getWrapType(relationFieldWrapper.getFieldType());
Collection<Object> collection = (Collection) ClassUtil.newInstance(wrapType); Collection<Object> collection = (Collection) ClassUtil.newInstance(wrapType);
for (Object targetObject : targetObjectList) { for (Object targetObject : targetObjectList) {
Object targetValue = targetFieldWrapper.get(targetObject); Object targetValue = targetFieldWrapper.get(targetObject);
if (targetValue != null && targetMappingValues.contains(targetValue.toString())) { if (targetValue != null && targetMappingValues.contains(targetValue.toString())) {
collection.add(targetObject); collection.add(targetObject);
} }
} }
relationFieldWrapper.set(collection, selfEntity); relationFieldWrapper.set(collection, selfEntity);
} }
} }
}); });
} }
} }
} }

View File

@ -23,6 +23,8 @@ class ManyToOne<SelfEntity> extends ToOneRelation<SelfEntity> {
public ManyToOne(RelationManyToOne annotation, Class<SelfEntity> entityClass, Field relationField) { public ManyToOne(RelationManyToOne annotation, Class<SelfEntity> entityClass, Field relationField) {
super(annotation.selfField() super(annotation.selfField()
, annotation.targetSchema()
, annotation.targetTable()
, getDefaultPrimaryProperty(annotation.targetField(), getTargetEntityClass(entityClass, relationField) , getDefaultPrimaryProperty(annotation.targetField(), getTargetEntityClass(entityClass, relationField)
, "@RelationManyToOne.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") , "@RelationManyToOne.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"")
, annotation.dataSource() , annotation.dataSource()

View File

@ -37,6 +37,8 @@ class OneToMany<SelfEntity> extends AbstractRelation<SelfEntity> {
public OneToMany(RelationOneToMany annotation, Class<SelfEntity> entityClass, Field relationField) { public OneToMany(RelationOneToMany annotation, Class<SelfEntity> entityClass, Field relationField) {
super(getDefaultPrimaryProperty(annotation.selfField(), entityClass, "@RelationOneToMany.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") 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); , annotation.targetField(), annotation.dataSource(), entityClass, relationField);
this.orderBy = annotation.orderBy(); this.orderBy = annotation.orderBy();
this.limit = annotation.limit(); this.limit = annotation.limit();
@ -49,7 +51,7 @@ class OneToMany<SelfEntity> extends AbstractRelation<SelfEntity> {
return null; return null;
} }
QueryWrapper queryWrapper = QueryWrapper.create().select() QueryWrapper queryWrapper = QueryWrapper.create().select()
.from(targetTableInfo.getTableNameWithSchema()); .from(getTargetTableWithSchema());
if (selfFieldValues.size() > 1) { if (selfFieldValues.size() > 1) {
queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(selfFieldValues)); queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(selfFieldValues));
} else { } else {

View File

@ -24,6 +24,8 @@ class OneToOne<SelfEntity> extends ToOneRelation<SelfEntity> {
public OneToOne(RelationOneToOne annotation, Class<SelfEntity> entityClass, Field relationField) { public OneToOne(RelationOneToOne annotation, Class<SelfEntity> entityClass, Field relationField) {
super(getDefaultPrimaryProperty(annotation.selfField(), entityClass super(getDefaultPrimaryProperty(annotation.selfField(), entityClass
, "@RelationOneToOne.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") , "@RelationOneToOne.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"")
, annotation.targetSchema()
, annotation.targetTable()
, annotation.targetField() , annotation.targetField()
, annotation.dataSource() , annotation.dataSource()
, entityClass , entityClass

View File

@ -27,10 +27,12 @@ import static com.mybatisflex.core.query.QueryMethods.column;
class ToOneRelation<SelfEntity> extends AbstractRelation<SelfEntity> { class ToOneRelation<SelfEntity> extends AbstractRelation<SelfEntity> {
public ToOneRelation(String selfField, String targetField, String dataSource, Class<SelfEntity> selfEntityClass, Field relationField) { public ToOneRelation(String selfField, String targetSchema, String targetTable, String targetField,
super(selfField, targetField, dataSource, selfEntityClass, relationField); String dataSource, Class<SelfEntity> selfEntityClass, Field relationField) {
super(selfField, targetSchema, targetTable, targetField, dataSource, selfEntityClass, relationField);
} }
@Override @Override
public QueryWrapper toQueryWrapper(List<SelfEntity> selfEntities) { public QueryWrapper toQueryWrapper(List<SelfEntity> selfEntities) {
Set<Object> selfFieldValues = getSelfFieldValues(selfEntities); Set<Object> selfFieldValues = getSelfFieldValues(selfEntities);
@ -38,7 +40,7 @@ class ToOneRelation<SelfEntity> extends AbstractRelation<SelfEntity> {
return null; return null;
} }
QueryWrapper queryWrapper = QueryWrapper.create().select() QueryWrapper queryWrapper = QueryWrapper.create().select()
.from(targetTableInfo.getTableNameWithSchema()); .from(getTargetTableWithSchema());
if (selfFieldValues.size() > 1) { if (selfFieldValues.size() > 1) {
queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(selfFieldValues)); queryWrapper.where(column(targetTableInfo.getColumnByProperty(targetField.getName())).in(selfFieldValues));
} else { } else {