spring获取AliasFor增强的注解

简介: spring获取AliasFor增强的注解

无论何时,别让你自己卷进去反对他人。——歌德

此处是关于issuehttps://gitee.com/dromara/stream-query/issues/I7BSNV

这里使用的一个自定义的@Table注解+@AliasFor来增强@TableName

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 issue.org.dromara.streamquery.gitee.issue17BSNV;
import com.baomidou.mybatisplus.annotation.TableName;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@TableName
public @interface Table {
  @AliasFor(annotation = TableName.class, attribute = "value")
  String value() default "";
}

然后是

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 issue.org.dromara.streamquery.gitee.issue17BSNV;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
import org.dromara.streamquery.stream.plugin.mybatisplus.engine.mapper.IGenerateMapper;
import java.time.LocalDateTime;
@Data
@Table(value = "user_info")
public class UserInfoWithTableAnnotation implements IGenerateMapper {
  private static final long serialVersionUID = -7219188882388819210L;
  @TableId(value = "id", type = IdType.AUTO)
  private Long id;
  private String name;
  private Integer age;
  private String email;
  @TableLogic(value = "'2001-01-01 00:00:00'", delval = "NOW()")
  private LocalDateTime gmtDeleted;
}

使用时:

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 issue.org.dromara.streamquery.gitee.issue17BSNV;
import org.dromara.streamquery.stream.core.collection.Lists;
import org.dromara.streamquery.stream.plugin.mybatisplus.Database;
import org.dromara.streamquery.stream.plugin.mybatisplus.annotation.AbstractMybatisPlusTestApplication;
import org.dromara.streamquery.stream.plugin.mybatisplus.engine.annotation.EnableMybatisPlusPlugin;
import org.dromara.streamquery.stream.plugin.mybatisplus.engine.mapper.IMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import java.util.Arrays;
import java.util.List;
/**
 * @author VampireAchao
 * @since 2023/6/8
 */
@EnableAutoConfiguration
@EnableMybatisPlusPlugin
class RevisionTest extends AbstractMybatisPlusTestApplication {
  @Test
  void testExecute() {
    UserInfoWithTableAnnotation entity = new UserInfoWithTableAnnotation();
    entity.setName("cat");
    entity.setAge(20);
    entity.setEmail("myEmail");
    UserInfoWithTableAnnotation userInfo = new UserInfoWithTableAnnotation();
    userInfo.setName("ruben");
    List<UserInfoWithTableAnnotation> list = Arrays.asList(userInfo, entity);
    long effectRows = Database.execute(UserInfoWithTableAnnotation.class,
            (IMapper<UserInfoWithTableAnnotation> m) -> m.saveOneSql(list));
    Assertions.assertEquals(2, effectRows);
    Assertions.assertEquals(7, Database.count(UserInfoWithTableAnnotation.class));
    Assertions.assertEquals(
            0L, Database.execute(UserInfoWithTableAnnotation.class,
                    (IMapper<UserInfoWithTableAnnotation> m) -> m.saveOneSql(Lists.empty())));
  }
}

此时发现并没有映射上,这里找表名没有找到。。。

于是我进行了处理

String originalTableName = tableInfo.getTableName();
  Annotation[] annotations = tableInfo.getEntityType().getAnnotations();
  for (Annotation annotation : annotations) {
    if (annotation.annotationType().isAnnotationPresent(TableName.class)) {
      Map<String, Object> annotationAttributes =
          AnnotationUtils.getAnnotationAttributes(annotation);
      TableName synthesizedTableName =
          AnnotationUtils.synthesizeAnnotation(
              annotationAttributes, TableName.class, tableInfo.getEntityType());
      String tableNamePropertyName = LambdaHelper.getPropertyName(TableInfo::getTableName);
      String tableNameValue = synthesizedTableName.value();
      ReflectHelper.setFieldValue(tableInfo, tableNamePropertyName, tableNameValue);
      Map<String, TableInfo> tableNameInfoCache =
          ((SerSupp<Map<String, TableInfo>>)
                  () ->
                      SerFunc.<Object, Map<String, TableInfo>>cast()
                          .apply(
                              ReflectHelper.accessible(
                                      TableInfoHelper.class.getDeclaredField(
                                          "TABLE_NAME_INFO_CACHE"))
                                  .get(null)))
              .get();
      tableNameInfoCache.remove(originalTableName);
      tableNameInfoCache.put(tableNameValue, tableInfo);
      break;
    }

完整代码如下:

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 org.dromara.streamquery.stream.plugin.mybatisplus.engine.handler;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.handlers.PostInitTableInfoHandler;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.dromara.streamquery.stream.core.lambda.LambdaHelper;
import org.dromara.streamquery.stream.core.lambda.function.SerFunc;
import org.dromara.streamquery.stream.core.lambda.function.SerSupp;
import org.dromara.streamquery.stream.core.reflect.ReflectHelper;
import org.springframework.core.annotation.AnnotationUtils;
import java.lang.annotation.Annotation;
import java.util.Map;
/**
 * @author VampireAchao
 * @since 2023/3/20 18:10
 */
public class JsonPostInitTableInfoHandler implements PostInitTableInfoHandler {
  /**
   * 参与 TableInfo 初始化
   *
   * @param tableInfo TableInfo
   * @param configuration Configuration
   */
  @Override
  public void postTableInfo(TableInfo tableInfo, Configuration configuration) {
    PostInitTableInfoHandler.super.postTableInfo(tableInfo, configuration);
    String originalTableName = tableInfo.getTableName();
    Annotation[] annotations = tableInfo.getEntityType().getAnnotations();
    for (Annotation annotation : annotations) {
      if (annotation.annotationType().isAnnotationPresent(TableName.class)) {
        Map<String, Object> annotationAttributes =
            AnnotationUtils.getAnnotationAttributes(annotation);
        TableName synthesizedTableName =
            AnnotationUtils.synthesizeAnnotation(
                annotationAttributes, TableName.class, tableInfo.getEntityType());
        String tableNamePropertyName = LambdaHelper.getPropertyName(TableInfo::getTableName);
        String tableNameValue = synthesizedTableName.value();
        ReflectHelper.setFieldValue(tableInfo, tableNamePropertyName, tableNameValue);
        Map<String, TableInfo> tableNameInfoCache =
            ((SerSupp<Map<String, TableInfo>>)
                    () ->
                        SerFunc.<Object, Map<String, TableInfo>>cast()
                            .apply(
                                ReflectHelper.accessible(
                                        TableInfoHelper.class.getDeclaredField(
                                            "TABLE_NAME_INFO_CACHE"))
                                    .get(null)))
                .get();
        tableNameInfoCache.remove(originalTableName);
        tableNameInfoCache.put(tableNameValue, tableInfo);
        break;
      }
    }
    for (TableFieldInfo fieldInfo : tableInfo.getFieldList()) {
      if (fieldInfo.getTypeHandler() == null) {
        continue;
      }
      if (tableInfo.getResultMap() == null) {
        return;
      }
      ResultMap resultMap = configuration.getResultMap(tableInfo.getResultMap());
      for (ResultMapping resultMapping : resultMap.getResultMappings()) {
        TypeHandler<?> handler = resultMapping.getTypeHandler();
        if (handler instanceof AbstractJsonFieldHandler) {
          AbstractJsonFieldHandler<?> typeHandler = (AbstractJsonFieldHandler<?>) handler;
          typeHandler.setTableInfo(tableInfo);
          typeHandler.setFieldInfo(fieldInfo);
        }
      }
    }
  }
}

然后通过AnnotationUtils.*synthesizeAnnotation*解决了这个问题

完整代码:

https://gitee.com/dromara/stream-query/commit/f4c15fdca66c5e6037644b0888e2b756eb5db25a

相关文章
|
2月前
|
XML Java 数据格式
SpringBoot入门(8) - 开发中还有哪些常用注解
SpringBoot入门(8) - 开发中还有哪些常用注解
61 0
|
3月前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
244 3
|
25天前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
168 73
|
20天前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
49 21
|
25天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
25天前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
2月前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
102 4
SpringBoot必须掌握的常用注解!
|
2月前
|
前端开发 Java Spring
Spring MVC核心:深入理解@RequestMapping注解
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的核心,它将HTTP请求映射到控制器的处理方法上。本文将深入探讨`@RequestMapping`注解的各个方面,包括其注解的使用方法、如何与Spring MVC的其他组件协同工作,以及在实际开发中的应用案例。
55 4
|
2月前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
188 2
|
2月前
|
前端开发 Java Spring
探索Spring MVC:@Controller注解的全面解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序的基石之一。它不仅简化了控制器的定义,还提供了一种优雅的方式来处理HTTP请求。本文将全面解析`@Controller`注解,包括其定义、用法、以及在Spring MVC中的作用。
70 2