自定义注解,使用AOP面向切面编程的思想。将其应用在类上面,一旦请求到该类上面的方法就调用注解里面的方法,执行注解里面的逻辑。
需求:mysql8.0使用group by时因为sql_mode设置为sql_mode='ONLY_FULL_GROUP_BY,NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,导致查询时,项目报错,但是由于某些原因不能在mysql客户端或者navicat中执行set @@sql_mode =‘STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION’; 故只能在在项目启动时设置mysql的sql_mode为
set @@sql_mode ='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
思路一:项目启动时走这个方法(未解决):
新建一个类实现ApplicationRunner,项目启动时走initContext(就是set sql_mode)方法。
package com.hlmx.project.common.handle;
import com.hlmx.common.utils.SpringApplicationContext;
import com.hlmx.project.statistics.mapper.ClassTeaIndicatorInfoResultMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
@Component
@Slf4j
public class ApplicationRunnerImpl implements ApplicationRunner {
@Autowired
private ClassTeaIndicatorInfoResultMapper classTeaIndicatorInfoResultMapper;
@Override
public void run(ApplicationArguments args) throws Exception {
classTeaIndicatorInfoResultMapper.initContext();
log.info("服务器启动完成并完成注册权限!=====================");
}
}
结果:sql_mode没有执行。
尝试过这两种方法都不行,但是如果这个的方法调的是查询方法,或者sql语句是update XXX set 就可以。猜测原因可能是sqlSessionFactory这个时候还没有实例化,故该方法调取不了。
set @@sql_mode ='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'; set @@sql_mode ='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
思路二:自定义一个注解,在注解中实现该方法。将该注解放在类上面。在调取接口时,走注解里面的方法。主要应用AOP的面向切面编程思想,使用切片中的前置通知(请求这个方法前该做哪些事,常运用于日志的记录)实现该功能。(成功!!!)
步骤一:
新建一个自定义注解的接口类
package com.hlmx.project.common.handle;
import java.lang.annotation.*;
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@documented
@Inherited
public @interface InitSqlmode {
}
步骤二:新建一个切面类实现设置数据库sql_mode
package com.xxxx.project.common.handle;
import com.xxx.project.statistics.mapper.ClassTeaIndicatorInfoResultMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
@Slf4j
@Component
@Aspect
public class InitSqlmodeAspect {
@Autowired
private ClassTeaIndicatorInfoResultMapper classTeaIndicatorInfoResultMapper;
@Pointcut("@within(com.xxxx.project.common.handle.InitSqlmode)")
public void initSqlmodeServer(){
}
@Before("initSqlmodeServer()")
public void initContext() {
classTeaIndicatorInfoResultMapper.initContext();
log.info("initContext=============执行完毕");
}
}
步骤三:在方法的实现类上添加该注解,(不知道什么原因在controller层上面添加该注解无效)
package com.xxxx.project.statistics.service.impl;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
@Service
@Slf4j
@InitSqlmode
public class ClassApiServiceImpl implements ClassApiService {}
启动项目测试成功!!!!



