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 41990ae9..68e523e3 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 @@ -67,6 +67,14 @@ public @interface RelationManyToMany { */ String targetField() default ""; + /** + * 目标实体类的字段绑定 + *

+ * 当字段不为空串时,只进行某个字段赋值(使用对应字段类型接收) + * @return 属性名称 + */ + String targetFieldBind() default ""; + /** * 当映射是一个 map 时,使用哪个内容来当做 map 的 Key * @return 指定的列 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 cfbb8d0d..287a177b 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 @@ -67,6 +67,14 @@ public @interface RelationManyToOne { */ String targetField() default ""; + /** + * 目标实体类的字段绑定 + *

+ * 当字段不为空串时,只进行某个字段赋值(使用对应字段类型接收) + * @return 属性名称 + */ + String targetFieldBind() 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 eeafeb08..91aafab0 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 @@ -67,6 +67,14 @@ public @interface RelationOneToMany { */ String targetField(); + /** + * 目标实体类的字段绑定 + *

+ * 当字段不为空串时,只进行某个字段赋值(使用对应字段类型接收) + * @return 属性名称 + */ + String targetFieldBind() default ""; + /** * 当映射是一个 map 时,使用哪个内容来当做 map 的 Key * @return 指定的列 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 528e910c..b12d6759 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 @@ -67,6 +67,14 @@ public @interface RelationOneToOne { */ String targetField(); + /** + * 目标实体类的字段绑定 + *

+ * 当字段不为空串时,只进行某个字段赋值(使用对应字段类型接收) + * @return 属性名称 + */ + String targetFieldBind() 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 472b5e73..653614da 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 @@ -46,6 +46,8 @@ abstract class AbstractRelation { protected String targetSchema; protected String targetTable; protected Field targetField; + protected String targetFieldBind; + protected boolean onlyTargetFieldBind; protected Class targetEntityClass; protected TableInfo targetTableInfo; protected FieldWrapper targetFieldWrapper; @@ -62,7 +64,7 @@ abstract class AbstractRelation { protected QueryColumn conditionColumn; protected String[] selectColumns; - public AbstractRelation(String selfField, String targetSchema, String targetTable, String targetField, + public AbstractRelation(String selfField, String targetSchema, String targetTable, String targetField, String targetFieldBind, String joinTable, String joinSelfColumn, String joinTargetColumn, String dataSource, Class entityClass, Field relationField, String extraCondition, String[] selectColumns @@ -82,25 +84,33 @@ abstract class AbstractRelation { this.selfField = ClassUtil.getFirstField(entityClass, field -> field.getName().equals(selfField)); this.selfFieldWrapper = FieldWrapper.of(entityClass, selfField); - - this.targetEntityClass = relationFieldWrapper.getMappingType(); + //以使用者注解配置为主 + this.targetTableInfo = StringUtil.isBlank(targetTable) ? TableInfoFactory.ofEntityClass(relationFieldWrapper.getMappingType()) : TableInfoFactory.ofTableName(targetTable); + this.targetEntityClass = targetTableInfo != null ? targetTableInfo.getEntityClass() : relationFieldWrapper.getMappingType(); this.targetSchema = targetSchema; - this.targetTable = targetTable; + this.targetTable = targetTableInfo != null ? targetTableInfo.getTableName() : targetTable; this.targetField = ClassUtil.getFirstField(targetEntityClass, field -> field.getName().equals(targetField)); this.targetFieldWrapper = FieldWrapper.of(targetEntityClass, targetField); - this.targetTableInfo = TableInfoFactory.ofEntityClass(targetEntityClass); + this.targetFieldBind = targetFieldBind; + this.onlyTargetFieldBind = StringUtil.isNotBlank(targetFieldBind); this.conditionColumn = column(targetTable, targetTableInfo.getColumnByProperty(this.targetField.getName())); - if (ArrayUtil.isNotEmpty(selectColumns)) { - if (ArrayUtil.contains(selectColumns, conditionColumn.getName())) { - this.selectColumns = selectColumns; - } else { - //需要追加 conditionColumn,因为进行内存 join 的时候,需要用到这个内容进行对比 - this.selectColumns = ArrayUtil.concat(selectColumns, new String[]{conditionColumn.getName()}); + if (onlyTargetFieldBind) { + //仅绑定字段时只需要查询关联列和该字段列即可 + this.selectColumns = new String[]{conditionColumn.getName(), targetTableInfo != null ? targetTableInfo.getColumnByProperty(this.targetFieldBind) : StringUtil.camelToUnderline(this.targetFieldBind)}; + } else { + if (ArrayUtil.isNotEmpty(selectColumns)) { + if (ArrayUtil.contains(selectColumns, conditionColumn.getName())) { + this.selectColumns = selectColumns; + } else { + //需要追加 conditionColumn,因为进行内存 join 的时候,需要用到这个内容进行对比 + this.selectColumns = ArrayUtil.concat(selectColumns, new String[]{conditionColumn.getName()}); + } } + } initExtraCondition(extraCondition); @@ -249,6 +259,22 @@ abstract class AbstractRelation { this.targetTable = targetTable; } + public String getTargetFieldBind() { + return targetFieldBind; + } + + public void setTargetFieldBind(String targetFieldBind) { + this.targetFieldBind = targetFieldBind; + } + + public boolean isOnlyTargetFieldBind() { + return onlyTargetFieldBind; + } + + public void setOnlyTargetFieldBind(boolean onlyTargetFieldBind) { + this.onlyTargetFieldBind = onlyTargetFieldBind; + } + public String getJoinTable() { return joinTable; } 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 7fcddb21..69fbd813 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 @@ -26,6 +26,7 @@ class ManyToMany extends ToManyRelation { , annotation.targetSchema() , annotation.targetTable() , getDefaultPrimaryProperty(annotation.targetField(), getTargetEntityClass(entityClass, relationField), "@RelationManyToMany.targetField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") + , annotation.targetFieldBind() , annotation.joinTable() , annotation.joinSelfColumn() , annotation.joinTargetColumn() 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 45d71ac8..a49071c5 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 @@ -27,6 +27,7 @@ class ManyToOne extends ToOneRelation { , annotation.targetTable() , getDefaultPrimaryProperty(annotation.targetField(), getTargetEntityClass(entityClass, relationField) , "@RelationManyToOne.selfField can not be empty in field: \"" + entityClass.getName() + "." + relationField.getName() + "\"") + , annotation.targetFieldBind() , annotation.joinTable() , annotation.joinSelfColumn() , annotation.joinTargetColumn() 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 fc5a642c..a50cc48e 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 @@ -27,6 +27,7 @@ class OneToMany extends ToManyRelation { , annotation.targetSchema() , annotation.targetTable() , annotation.targetField() + , annotation.targetFieldBind() , annotation.joinTable() , annotation.joinSelfColumn() , annotation.joinTargetColumn() 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 9e410ec0..bf90c3a1 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 @@ -27,6 +27,7 @@ class OneToOne extends ToOneRelation { , annotation.targetSchema() , annotation.targetTable() , annotation.targetField() + , annotation.targetFieldBind() , annotation.joinTable() , annotation.joinSelfColumn() , annotation.joinTargetColumn() diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/RelationManager.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/RelationManager.java index 8bb15149..26cb6ce1 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/RelationManager.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/RelationManager.java @@ -359,8 +359,9 @@ public class RelationManager { DataSourceKey.use(configDsKey); } + //仅绑定字段:As目标实体类 不进行字段绑定:As映射类型 QueryWrapper queryWrapper = relation.buildQueryWrapper(targetValues); - List targetObjectList = mapper.selectListByQueryAs(queryWrapper, relation.getMappingType()); + List targetObjectList = mapper.selectListByQueryAs(queryWrapper, relation.isOnlyTargetFieldBind() ? relation.getTargetEntityClass() : relation.getMappingType()); if (CollectionUtil.isNotEmpty(targetObjectList)) { //递归查询 diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java index 694c3ca6..f8f2e8ae 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/relation/ToManyRelation.java @@ -31,11 +31,11 @@ class ToManyRelation extends AbstractRelation { protected long limit = 0; - public ToManyRelation(String selfField, String targetSchema, String targetTable, String targetField, + public ToManyRelation(String selfField, String targetSchema, String targetTable, String targetField, String targetFieldBind, String joinTable, String joinSelfColumn, String joinTargetColumn, String dataSource, Class selfEntityClass, Field relationField, String extraCondition, String[] selectColumns) { - super(selfField, targetSchema, targetTable, targetField, + super(selfField, targetSchema, targetTable, targetField, targetFieldBind, joinTable, joinSelfColumn, joinTargetColumn, dataSource, selfEntityClass, relationField, extraCondition, selectColumns @@ -101,7 +101,12 @@ class ToManyRelation extends AbstractRelation { for (Object targetObject : targetObjectList) { Object targetValue = targetFieldWrapper.get(targetObject); if (targetValue != null && targetMappingValues.contains(targetValue.toString())) { - collection.add(targetObject); + if (onlyTargetFieldBind) { + //仅绑定某个字段 + collection.add(FieldWrapper.of(targetObject.getClass(), targetFieldBind).get(targetObject)); + } else { + collection.add(targetObject); + } } } relationFieldWrapper.set(collection, selfEntity); 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 86690955..f04de754 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 @@ -16,6 +16,7 @@ package com.mybatisflex.core.relation; import com.mybatisflex.core.row.Row; +import com.mybatisflex.core.util.FieldWrapper; import java.lang.reflect.Field; import java.util.List; @@ -23,10 +24,10 @@ import java.util.List; class ToOneRelation extends AbstractRelation { - public ToOneRelation(String selfField, String targetSchema, String targetTable, String targetField, + public ToOneRelation(String selfField, String targetSchema, String targetTable, String targetField, String targetFieldBind, String joinTable, String joinSelfColumn, String joinTargetColumn, String dataSource, Class selfEntityClass, Field relationField, String[] selectColumns) { - super(selfField, targetSchema, targetTable, targetField, + super(selfField, targetSchema, targetTable, targetField, targetFieldBind, joinTable, joinSelfColumn, joinTargetColumn, dataSource, selfEntityClass, relationField, null, selectColumns @@ -53,7 +54,12 @@ class ToOneRelation extends AbstractRelation { for (Object targetObject : targetObjectList) { Object targetValue = targetFieldWrapper.get(targetObject); if (targetValue != null && targetMappingValue.equals(targetValue.toString())) { - relationFieldWrapper.set(targetObject, selfEntity); + if (onlyTargetFieldBind) { + //仅绑定某个字段 + relationFieldWrapper.set(FieldWrapper.of(targetObject.getClass(), targetFieldBind).get(targetObject), selfEntity); + } else { + relationFieldWrapper.set(targetObject, selfEntity); + } break; } } diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/java/com/mybatisflex/test/model/UserVO5.java b/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/java/com/mybatisflex/test/model/UserVO5.java new file mode 100644 index 00000000..7589fbdd --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-spring-boot-test/src/main/java/com/mybatisflex/test/model/UserVO5.java @@ -0,0 +1,96 @@ +package com.mybatisflex.test.model; + +import com.mybatisflex.annotation.*; + +import java.io.Serializable; +import java.util.List; + +/** + * 字段绑定测试 + * @author Ice 2023/09/16 + * @version 1.0 + */ +@Table("tb_user") +public class UserVO5 implements Serializable { + private static final long serialVersionUID = 474700189859144273L; + + @Id + private Integer userId; + private String userName; + private String password; + + @RelationOneToOne( + selfField = "userId", + targetTable = "tb_id_card", + targetField = "id", + targetFieldBind = "idNumber" + ) + private String idNumberCustomFieldName; + + @RelationOneToMany( + selfField = "userId", + targetTable = "tb_user_order", + targetField = "userId", + targetFieldBind = "orderId" + ) + private List orderIdList; + + @RelationManyToMany( + selfField = "userId", + targetTable = "tb_role", + targetField = "roleId", + targetFieldBind = "roleName", + joinTable = "tb_user_role", + joinSelfColumn = "user_id", + joinTargetColumn = "role_id" + ) + private List roleNameList; + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getIdNumberCustomFieldName() { + return idNumberCustomFieldName; + } + + public void setIdNumberCustomFieldName(String idNumberCustomFieldName) { + this.idNumberCustomFieldName = idNumberCustomFieldName; + } + + public List getOrderIdList() { + return orderIdList; + } + + public void setOrderIdList(List orderIdList) { + this.orderIdList = orderIdList; + } + + public List getRoleNameList() { + return roleNameList; + } + + public void setRoleNameList(List roleNameList) { + this.roleNameList = roleNameList; + } +} diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-test/src/test/java/com/mybatisflex/test/mapper/UserMapperTest.java b/mybatis-flex-test/mybatis-flex-spring-boot-test/src/test/java/com/mybatisflex/test/mapper/UserMapperTest.java index 43b3e340..1ed5227e 100644 --- a/mybatis-flex-test/mybatis-flex-spring-boot-test/src/test/java/com/mybatisflex/test/mapper/UserMapperTest.java +++ b/mybatis-flex-test/mybatis-flex-spring-boot-test/src/test/java/com/mybatisflex/test/mapper/UserMapperTest.java @@ -280,4 +280,10 @@ class UserMapperTest { System.err.println(user); } + @Test + public void testFieldBindRelations() { + List userVO5List = userMapper.selectListWithRelationsByQueryAs(QueryWrapper.create(), UserVO5.class); + System.out.println(userVO5List); + } + }