!443 feat:增强 VO 类支持重名映射,以及共用实体类监听器。

Merge pull request !443 from 王帅/main
This commit is contained in:
王帅 2024-04-07 04:07:16 +00:00 committed by Gitee
commit cd6c27bb2f
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 331 additions and 58 deletions

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022-2023, 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.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* VOView Object
*
* @author 王帅
* @since 2024-04-02
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewObject {
/**
* 对应的 <b>实体类</b> 引用
*
* @return 实体类引用
*/
Class<?> ref();
/**
* 是否复制引用类 {@code @Table} 注解上的内容默认为{@code true}
*
* @return 是否复制属性
*/
boolean copyTableProps() default true;
}

View File

@ -15,15 +15,7 @@
*/ */
package com.mybatisflex.core.table; package com.mybatisflex.core.table;
import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.*;
import com.mybatisflex.annotation.ColumnAlias;
import com.mybatisflex.annotation.ColumnMask;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.InsertListener;
import com.mybatisflex.annotation.NoneListener;
import com.mybatisflex.annotation.SetListener;
import com.mybatisflex.annotation.Table;
import com.mybatisflex.annotation.UpdateListener;
import com.mybatisflex.core.BaseMapper; import com.mybatisflex.core.BaseMapper;
import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.exception.FlexExceptions; import com.mybatisflex.core.exception.FlexExceptions;
@ -31,53 +23,20 @@ import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.query.QueryColumn; import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryCondition; import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.util.ClassUtil; import com.mybatisflex.core.util.*;
import com.mybatisflex.core.util.CollectionUtil;
import com.mybatisflex.core.util.Reflectors;
import com.mybatisflex.core.util.StringUtil;
import org.apache.ibatis.io.ResolverUtil; import org.apache.ibatis.io.ResolverUtil;
import org.apache.ibatis.reflection.Reflector; import org.apache.ibatis.reflection.Reflector;
import org.apache.ibatis.reflection.TypeParameterResolver; import org.apache.ibatis.reflection.TypeParameterResolver;
import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.*;
import org.apache.ibatis.type.TypeException;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.apache.ibatis.type.UnknownTypeHandler;
import com.mybatisflex.core.util.MapUtil;
import java.lang.reflect.Constructor; import java.lang.reflect.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.sql.Time; import java.sql.Time;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.Instant; import java.time.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZonedDateTime;
import java.time.chrono.JapaneseDate; import java.time.chrono.JapaneseDate;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -222,7 +181,29 @@ public class TableInfoFactory {
// 初始化表名 // 初始化表名
Table table = entityClass.getAnnotation(Table.class); Table table = entityClass.getAnnotation(Table.class);
if (table != null) { if (table == null) {
ViewObject vo = entityClass.getAnnotation(ViewObject.class);
if (vo != null) {
TableInfo refTableInfo = ofEntityClass(vo.ref());
// 设置 VO 类对应的真实的表名
tableInfo.setSchema(refTableInfo.getSchema());
tableInfo.setTableName(refTableInfo.getTableName());
// @Table 注解的属性复制到 VO 类当中
if (vo.copyTableProps()) {
tableInfo.setComment(refTableInfo.getComment());
tableInfo.setCamelToUnderline(refTableInfo.isCamelToUnderline());
tableInfo.setDataSource(refTableInfo.getDataSource());
tableInfo.setOnSetListeners(refTableInfo.getOnSetListeners());
tableInfo.setOnInsertColumns(refTableInfo.getOnInsertColumns());
tableInfo.setOnUpdateListeners(refTableInfo.getOnUpdateListeners());
}
} else {
// 默认为类名转驼峰下划线
String tableName = StringUtil.camelToUnderline(entityClass.getSimpleName());
tableInfo.setTableName(tableName);
}
} else {
tableInfo.setSchema(table.schema()); tableInfo.setSchema(table.schema());
tableInfo.setTableName(table.value()); tableInfo.setTableName(table.value());
tableInfo.setCamelToUnderline(table.camelToUnderline()); tableInfo.setCamelToUnderline(table.camelToUnderline());
@ -255,10 +236,6 @@ public class TableInfoFactory {
if (StringUtil.isNotBlank(table.dataSource())) { if (StringUtil.isNotBlank(table.dataSource())) {
tableInfo.setDataSource(table.dataSource()); tableInfo.setDataSource(table.dataSource());
} }
} else {
// 默认为类名转驼峰下划线
String tableName = StringUtil.camelToUnderline(entityClass.getSimpleName());
tableInfo.setTableName(tableName);
} }
// 初始化字段相关 // 初始化字段相关

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2022-2023, 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.alisa;
import com.mybatisflex.annotation.ViewObject;
/**
* 部门
*
* @author 王帅
* @since 2023-11-16
*/
@ViewObject(ref = SysDept.class)
public class DeptVO extends BaseEntity {
private Integer id;
private String deptName;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Override
public String toString() {
return "SysDept{" +
"id=" + id +
", deptName='" + deptName + '\'' +
'}' + super.toString();
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2022-2023, 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.alisa;
import com.mybatisflex.annotation.ViewObject;
/**
* 角色
*
* @author 王帅
* @since 2023-11-16
*/
@ViewObject(ref = SysRole.class)
public class RoleVO extends BaseEntity {
private Integer id;
private String roleKey;
private String roleName;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getRoleKey() {
return roleKey;
}
public void setRoleKey(String roleKey) {
this.roleKey = roleKey;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
@Override
public String toString() {
return "SysRole{" +
"id=" + id +
", roleKey='" + roleKey + '\'' +
", roleName='" + roleName + '\'' +
'}' + super.toString();
}
}

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2022-2023, 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.alisa;
import com.mybatisflex.annotation.ColumnAlias;
import com.mybatisflex.annotation.ViewObject;
import java.util.Date;
import java.util.List;
/**
* 用户
*
* @author 王帅
* @since 2023-11-16
*/
@ViewObject(ref = SysUser.class)
public class UserVO extends BaseEntity {
private Integer id;
private String userName;
@ColumnAlias("user_age")
private Integer age;
private Date birthday;
private List<SysRole> roleList;
private List<SysDept> deptList;
public List<SysRole> getRoleList() {
return roleList;
}
public void setRoleList(List<SysRole> roleList) {
this.roleList = roleList;
}
public List<SysDept> getDeptList() {
return deptList;
}
public void setDeptList(List<SysDept> deptList) {
this.deptList = deptList;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "SysUser{" +
"id=" + id +
", userName='" + userName + '\'' +
", age=" + age +
", birthday=" + birthday +
", roleList=" + roleList +
", deptList=" + deptList +
'}' + super.toString();
}
}

View File

@ -16,10 +16,13 @@
package com.mybatisflex.test.mapper; package com.mybatisflex.test.mapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.mybatisflex.core.FlexGlobalConfig; import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.test.alisa.SysUser; import com.mybatisflex.test.alisa.SysUser;
import com.mybatisflex.test.alisa.UserVO;
import org.apache.ibatis.mapping.ResultMap; import org.apache.ibatis.mapping.ResultMap;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -63,7 +66,7 @@ class AlisaTest {
.select(SYS_USER.DEFAULT_COLUMNS) .select(SYS_USER.DEFAULT_COLUMNS)
.select(SYS_ROLE.DEFAULT_COLUMNS) .select(SYS_ROLE.DEFAULT_COLUMNS)
.from(SYS_USER.as("u")) .from(SYS_USER.as("u"))
.leftJoin(SYS_ROLE).as("r").on(SYS_USER.ID.eq(1)); .leftJoin(SYS_ROLE.as("r")).on(SYS_USER.ID.eq(1));
printList(queryWrapper); printList(queryWrapper);
} }
@ -75,8 +78,8 @@ class AlisaTest {
.select(SYS_ROLE.DEFAULT_COLUMNS) .select(SYS_ROLE.DEFAULT_COLUMNS)
.select(SYS_DEPT.DEFAULT_COLUMNS) .select(SYS_DEPT.DEFAULT_COLUMNS)
.from(SYS_USER.as("u")) .from(SYS_USER.as("u"))
.leftJoin(SYS_ROLE).as("r").on(SYS_USER.ID.eq(1)) .leftJoin(SYS_ROLE.as("r")).on(SYS_USER.ID.eq(1))
.leftJoin(SYS_DEPT).as("d").on(SYS_USER.ID.eq(1)); .leftJoin(SYS_DEPT.as("d")).on(SYS_USER.ID.eq(1));
printList(queryWrapper); printList(queryWrapper);
} }
@ -89,8 +92,8 @@ class AlisaTest {
.select(SYS_DEPT.DEFAULT_COLUMNS) .select(SYS_DEPT.DEFAULT_COLUMNS)
.select(SYS_USER.DEFAULT_COLUMNS) .select(SYS_USER.DEFAULT_COLUMNS)
.from(SYS_USER.as("u")) .from(SYS_USER.as("u"))
.leftJoin(SYS_ROLE).as("r").on(SYS_USER.ID.eq(1)) .leftJoin(SYS_ROLE.as("r")).on(SYS_USER.ID.eq(1))
.leftJoin(SYS_DEPT).as("d").on(SYS_USER.ID.eq(1)); .leftJoin(SYS_DEPT.as("d")).on(SYS_USER.ID.eq(1));
printList(queryWrapper); printList(queryWrapper);
} }
@ -126,7 +129,7 @@ class AlisaTest {
.select(SYS_USER.ID, SYS_USER.USER_NAME, SYS_USER.AGE, SYS_USER.BIRTHDAY) .select(SYS_USER.ID, SYS_USER.USER_NAME, SYS_USER.AGE, SYS_USER.BIRTHDAY)
.select(SYS_ROLE.CREATE_BY.as("sys_role$create_by")) .select(SYS_ROLE.CREATE_BY.as("sys_role$create_by"))
.from(SYS_USER.as("u")) .from(SYS_USER.as("u"))
.leftJoin(SYS_ROLE).as("r").on(SYS_USER.ID.eq(1)); .leftJoin(SYS_ROLE.as("r")).on(SYS_USER.ID.eq(1));
Object[] objects = FlexGlobalConfig.getDefaultConfig() Object[] objects = FlexGlobalConfig.getDefaultConfig()
.getConfiguration() .getConfiguration()
@ -145,4 +148,22 @@ class AlisaTest {
printList(queryWrapper); printList(queryWrapper);
} }
@Test
void test07() throws JsonProcessingException {
QueryWrapper queryWrapper = QueryWrapper.create()
.select(SYS_USER.DEFAULT_COLUMNS)
.select(SYS_ROLE.DEFAULT_COLUMNS)
.select(SYS_DEPT.DEFAULT_COLUMNS)
.from(SYS_USER.as("u"))
.leftJoin(SYS_ROLE.as("r")).on(SYS_USER.ID.eq(1))
.leftJoin(SYS_DEPT.as("d")).on(SYS_USER.ID.eq(1));
ObjectWriter objectWriter = objectMapper.writerWithDefaultPrettyPrinter();
String userList1 = objectWriter.writeValueAsString(userMapper.selectListByQuery(queryWrapper));
String userList2 = objectWriter.writeValueAsString(userMapper.selectListByQueryAs(queryWrapper, UserVO.class));
Assertions.assertEquals(userList1, userList2);
}
} }