Merge pull request #401 from somethingaw/feat/20240912-customize-handle-unnamecolumn

增加未匹配列的自定义处理拓展接口
This commit is contained in:
Michael Yang 2024-09-12 17:20:30 +08:00 committed by GitHub
commit 2b82c19d8e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 310 additions and 0 deletions

View File

@ -23,6 +23,7 @@ import com.mybatisflex.annotation.UpdateListener;
import com.mybatisflex.core.datasource.FlexDataSource;
import com.mybatisflex.core.dialect.DbType;
import com.mybatisflex.core.exception.FlexAssert;
import com.mybatisflex.core.mybatis.UnMappedColumnHandler;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
@ -109,6 +110,11 @@ public class FlexGlobalConfig {
*/
private String versionColumn;
/**
* 未匹配列处理器
*/
private static UnMappedColumnHandler unMappedColumnHandler;
public boolean isPrintBanner() {
return printBanner;
}
@ -323,6 +329,14 @@ public class FlexGlobalConfig {
this.versionColumn = versionColumn;
}
public static UnMappedColumnHandler getUnMappedColumnHandler() {
return unMappedColumnHandler;
}
public void setUnMappedColumnHandler(UnMappedColumnHandler unMappedColumnHandler) {
this.unMappedColumnHandler = unMappedColumnHandler;
}
public FlexDataSource getDataSource() {
return (FlexDataSource) getConfiguration().getEnvironment().getDataSource();
}

View File

@ -15,6 +15,7 @@
*/
package com.mybatisflex.core.mybatis;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.util.MapUtil;
import org.apache.ibatis.annotations.AutomapConstructor;
import org.apache.ibatis.annotations.Param;
@ -42,6 +43,7 @@ import org.apache.ibatis.session.*;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.apache.ibatis.type.UnknownTypeHandler;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
@ -592,6 +594,18 @@ public class FlexDefaultResultSetHandler extends DefaultResultSetHandler {
}
}
}
else {
if (FlexGlobalConfig.getUnMappedColumnHandler() != null){
// 增加未匹配列自定义处理
final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
for (String unmappedColumnName : unmappedColumnNames) {
// 不明确类型直接取object
final Object value = typeHandlerRegistry.getMappingTypeHandler(UnknownTypeHandler.class).getResult(rsw.getResultSet(), unmappedColumnName);
// 自定义处理未匹配列
FlexGlobalConfig.getUnMappedColumnHandler().handleUnMappedColumn(metaObject, unmappedColumnName, value);
}
}
}
return foundValues;
}

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.core.mybatis;
import org.apache.ibatis.reflection.MetaObject;
/**
* UnMappedColumnHandler
* 自定义未匹配列处理
* @author ArthurWang
* @version 1.0
* @date 2024/9/12 9:16
**/
public interface UnMappedColumnHandler {
void handleUnMappedColumn(MetaObject metaObject, String unmappedColumnName, Object value);
}

View File

@ -23,6 +23,7 @@ import com.mybatisflex.core.datasource.DataSourceProperty;
import com.mybatisflex.core.mybatis.FlexConfiguration;
import com.mybatisflex.spring.boot.ConfigurationCustomizer;
import com.mybatisflex.spring.boot.MyBatisFlexCustomizer;
import com.mybatisflex.test.unmapped.MyUnMappedColumnHandler;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.springframework.context.annotation.Configuration;
@ -55,6 +56,7 @@ public class MyConfigurationCustomizer implements ConfigurationCustomizer, MyBat
return value;
};
DataSourceManager.setDecipher(decipher);
globalConfig.setUnMappedColumnHandler(new MyUnMappedColumnHandler());
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test.model;
import lombok.Getter;
import lombok.Setter;
import java.util.Map;
/**
* UnMappedBaseEntity
*
* @author wy
* @version 1.0
* @date 2024/9/12 11:36
**/
@Getter
@Setter
public class UnmappedBaseEntity {
protected Map<String, Object> unmappedMap;
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test.model;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.CollectionUtils;
/**
* UnMapped
*
* @author wy
* @version 1.0
* @date 2024/9/12 11:28
**/
@Getter
@Setter
@Table("tb_unmapped_user")
public class UnmappedUser extends UnmappedBaseEntity {
@Id(keyType = KeyType.Auto)
private Long id;
private Integer age;
private String name;
@Override
public String toString() {
return "UnmappedUser{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
(CollectionUtils.isEmpty(unmappedMap) ? "" : ", unmappedMap=" + unmappedMap.toString())
+ '}';
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test.unmapped;
import com.mybatisflex.core.mybatis.UnMappedColumnHandler;
import com.mybatisflex.test.model.UnmappedBaseEntity;
import org.apache.ibatis.reflection.MetaObject;
import java.util.HashMap;
import java.util.Map;
/**
* MyUnMappedColumnHandler
*
* @author wy
* @version 1.0
* @date 2024/9/12 11:34
**/
public class MyUnMappedColumnHandler implements UnMappedColumnHandler {
@Override
public void handleUnMappedColumn(MetaObject metaObject, String unmappedColumnName, Object value) {
if (metaObject.getOriginalObject() instanceof UnmappedBaseEntity){
Object object = metaObject.getValue("unmappedMap");
if(object == null){
Map<String, Object> map = new HashMap<>();
map.put(unmappedColumnName, value);
metaObject.setValue("unmappedMap", map);
}else {
((Map)object).put(unmappedColumnName, value);
}
}
}
}

View File

@ -0,0 +1,21 @@
-- ----------------------------
-- Table structure for tb_unmapped_user
-- ----------------------------
DROP TABLE IF EXISTS `tb_unmapped_user`;
CREATE TABLE `tb_unmapped_user`
(
`id` bigint primary key AUTO_INCREMENT,
`name` varchar(100) NULL DEFAULT NULL,
`age` int NULL DEFAULT NULL,
`code` int NULL DEFAULT NULL
)
-- ----------------------------
-- Records of tb_unmapped_user
-- ----------------------------
INSERT INTO `tb_unmapped_user`
VALUES (1, '张三', 28, 64);
INSERT INTO `tb_unmapped_user`
VALUES (2, '李四', 15, 128);
INSERT INTO `tb_unmapped_user`
VALUES (3, '王五', 9, 256);

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test.mapper;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.test.model.UnmappedUser;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import static com.mybatisflex.test.model.table.UnmappedUserTableDef.UNMAPPED_USER;
/**
* UnMappedUserMapperTest
*
* @author wy
* @version 1.0
* @date 2024/9/12 11:39
**/
@SpringBootTest
@SuppressWarnings("all")
public class UnmappedUserMapperTest {
@Autowired
private UnmappedUserMapper unmappedUserMapper;
/**
* 额外字段查询数据库中有但是实体类中没有
* 应用前端具有一定查询数据库能力时不改后端代码情况下返回新增字段数据
*/
@Test
void testExtraColumn() {
QueryWrapper queryWrapper = QueryWrapper.create()
.select(UNMAPPED_USER.ID, UNMAPPED_USER.AGE, UNMAPPED_USER.NAME,
// 额外字段查询
new QueryColumn("code"))
.where(UNMAPPED_USER.ID.in(1, 2, 3));
List<UnmappedUser> unmappedUserList = unmappedUserMapper.selectListByQuery(queryWrapper);
System.out.println(unmappedUserList);
}
/**
* 同名字段
* 多数据源下同表同名字段不同含义或者需要同时展示
*/
@Test
void testSameColumn() {
// 可能多数据源下会存在同表同名字段不同值
QueryWrapper queryWrapper = QueryWrapper.create()
.select(UNMAPPED_USER.ID, UNMAPPED_USER.AGE, UNMAPPED_USER.NAME,
// 同名字段重置
UNMAPPED_USER.NAME.as("ext_name"))
.where(UNMAPPED_USER.ID.in(1, 2, 3));
List<UnmappedUser> unmappedUserList = unmappedUserMapper.selectListByQuery(queryWrapper);
System.out.println(unmappedUserList);
}
/**
* 计算或者处理的字段
* sql中进行处理的字段不直接映射到实体类上的域
*/
@Test
void testCalColumn() {
QueryWrapper queryWrapper = QueryWrapper.create()
.select(UNMAPPED_USER.ID, UNMAPPED_USER.NAME, UNMAPPED_USER.AGE,
// 字段计算结果
QueryMethods.case_()
.when(UNMAPPED_USER.AGE.ge(18)).then("adult")
.when(UNMAPPED_USER.AGE.le(14)).then("child")
.else_("juvenile")
.end()
.as("age_group"))
.where(UNMAPPED_USER.ID.in(1, 2, 3));
List<UnmappedUser> unmappedUserList = unmappedUserMapper.selectListByQuery(queryWrapper);
System.out.println(unmappedUserList);
}
}