网站开发周期定义,郑州网站建设微信小程序,免费网站加速软件,网站建设前期情况说明springboot3.2.4Mybatis-plus在graalvm21环境下打包exe
前提条件为之前已经能直接打包springboot3.2.4项目了然后在此基础上接入Mybatis-plus#xff0c;然后能够正常进行打包exe并且执行#xff0c;参考之前的文章进行打包
核心配置如下
package com.example.demo.config…springboot3.2.4Mybatis-plus在graalvm21环境下打包exe
前提条件为之前已经能直接打包springboot3.2.4项目了然后在此基础上接入Mybatis-plus然后能够正常进行打包exe并且执行参考之前的文章进行打包
核心配置如下
package com.example.demo.config;import com.baomidou.mybatisplus.annotation.IEnum;
import com.baomidou.mybatisplus.core.MybatisParameterHandler;
import com.baomidou.mybatisplus.core.MybatisXMLLanguageDriver;
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.handlers.CompositeEnumTypeHandler;
import com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.baomidou.mybatisplus.extension.handlers.GsonTypeHandler;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;
import org.apache.ibatis.cache.decorators.FifoCache;
import org.apache.ibatis.cache.decorators.LruCache;
import org.apache.ibatis.cache.decorators.SoftCache;
import org.apache.ibatis.cache.decorators.WeakCache;
import org.apache.ibatis.cache.impl.PerpetualCache;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.executor.statement.BaseStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.javassist.util.proxy.ProxyFactory;
import org.apache.ibatis.javassist.util.proxy.RuntimeSupport;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl;
import org.apache.ibatis.logging.jdk14.Jdk14LoggingImpl;
import org.apache.ibatis.logging.log4j2.Log4j2Impl;
import org.apache.ibatis.logging.nologging.NoLoggingImpl;
import org.apache.ibatis.logging.slf4j.Slf4jImpl;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.reflection.TypeParameterResolver;
import org.apache.ibatis.scripting.defaults.RawLanguageDriver;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution;
import org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor;
import org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.core.ResolvableType;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;/*** author lyk* since 2024-03-30*/
Configuration(proxyBeanMethods false)
ImportRuntimeHints(MyBatisNativeConfiguration.MyBaitsRuntimeHintsRegistrar.class)
public class MyBatisNativeConfiguration {BeanMyBatisBeanFactoryInitializationAotProcessor myBatisBeanFactoryInitializationAotProcessor() {return new MyBatisBeanFactoryInitializationAotProcessor();}Beanstatic MyBatisMapperFactoryBeanPostProcessor myBatisMapperFactoryBeanPostProcessor() {return new MyBatisMapperFactoryBeanPostProcessor();}static class MyBaitsRuntimeHintsRegistrar implements RuntimeHintsRegistrar {Overridepublic void registerHints(RuntimeHints hints, ClassLoader classLoader) {Stream.of(RawLanguageDriver.class,// TODO 增加了MybatisXMLLanguageDriver.classXMLLanguageDriver.class, MybatisXMLLanguageDriver.class,RuntimeSupport.class,ProxyFactory.class,Slf4jImpl.class,Log.class,JakartaCommonsLoggingImpl.class,Log4j2Impl.class,Jdk14LoggingImpl.class,StdOutImpl.class,NoLoggingImpl.class,SqlSessionFactory.class,PerpetualCache.class,FifoCache.class,LruCache.class,SoftCache.class,WeakCache.class,//TODO 增加了MybatisSqlSessionFactoryBean.classSqlSessionFactoryBean.class, MybatisSqlSessionFactoryBean.class,ArrayList.class,HashMap.class,TreeSet.class,HashSet.class).forEach(x - hints.reflection().registerType(x, MemberCategory.values()));Stream.of(org/apache/ibatis/builder/xml/*.dtd,org/apache/ibatis/builder/xml/*.xsd).forEach(hints.resources()::registerPattern);hints.serialization().registerType(SerializedLambda.class);hints.serialization().registerType(SFunction.class);hints.serialization().registerType(java.lang.invoke.SerializedLambda.class);hints.reflection().registerType(SFunction.class);hints.reflection().registerType(SerializedLambda.class);hints.reflection().registerType(java.lang.invoke.SerializedLambda.class);hints.proxies().registerJdkProxy(StatementHandler.class);hints.proxies().registerJdkProxy(Executor.class);hints.proxies().registerJdkProxy(ResultSetHandler.class);hints.proxies().registerJdkProxy(ParameterHandler.class);// hints.reflection().registerType(MybatisPlusInterceptor.class);hints.reflection().registerType(AbstractWrapper.class,MemberCategory.values());hints.reflection().registerType(LambdaQueryWrapper.class,MemberCategory.values());hints.reflection().registerType(LambdaUpdateWrapper.class,MemberCategory.values());hints.reflection().registerType(UpdateWrapper.class,MemberCategory.values());hints.reflection().registerType(QueryWrapper.class,MemberCategory.values());hints.reflection().registerType(BoundSql.class,MemberCategory.DECLARED_FIELDS);hints.reflection().registerType(RoutingStatementHandler.class,MemberCategory.DECLARED_FIELDS);hints.reflection().registerType(BaseStatementHandler.class,MemberCategory.DECLARED_FIELDS);hints.reflection().registerType(MybatisParameterHandler.class,MemberCategory.DECLARED_FIELDS);hints.reflection().registerType(IEnum.class,MemberCategory.INVOKE_PUBLIC_METHODS);// register typeHandlerhints.reflection().registerType(CompositeEnumTypeHandler.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);hints.reflection().registerType(FastjsonTypeHandler.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);hints.reflection().registerType(GsonTypeHandler.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);hints.reflection().registerType(JacksonTypeHandler.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);hints.reflection().registerType(MybatisEnumTypeHandler.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS);}}static class MyBatisBeanFactoryInitializationAotProcessorimplements BeanFactoryInitializationAotProcessor, BeanRegistrationExcludeFilter {private final SetClass? excludeClasses new HashSet();MyBatisBeanFactoryInitializationAotProcessor() {excludeClasses.add(MapperScannerConfigurer.class);}Override public boolean isExcludedFromAotProcessing(RegisteredBean registeredBean) {return excludeClasses.contains(registeredBean.getBeanClass());}Overridepublic BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {String[] beanNames beanFactory.getBeanNamesForType(MapperFactoryBean.class);if (beanNames.length 0) {return null;}return (context, code) - {RuntimeHints hints context.getRuntimeHints();for (String beanName : beanNames) {BeanDefinition beanDefinition beanFactory.getBeanDefinition(beanName.substring(1));PropertyValue mapperInterface beanDefinition.getPropertyValues().getPropertyValue(mapperInterface);if (mapperInterface ! null mapperInterface.getValue() ! null) {Class? mapperInterfaceType (Class?) mapperInterface.getValue();if (mapperInterfaceType ! null) {registerReflectionTypeIfNecessary(mapperInterfaceType, hints);hints.proxies().registerJdkProxy(mapperInterfaceType);hints.resources().registerPattern(mapperInterfaceType.getName().replace(., /).concat(.xml));registerMapperRelationships(mapperInterfaceType, hints);}}}};}private void registerMapperRelationships(Class? mapperInterfaceType, RuntimeHints hints) {Method[] methods ReflectionUtils.getAllDeclaredMethods(mapperInterfaceType);for (Method method : methods) {if (method.getDeclaringClass() ! Object.class) {ReflectionUtils.makeAccessible(method);registerSqlProviderTypes(method, hints, SelectProvider.class, SelectProvider::value, SelectProvider::type);registerSqlProviderTypes(method, hints, InsertProvider.class, InsertProvider::value, InsertProvider::type);registerSqlProviderTypes(method, hints, UpdateProvider.class, UpdateProvider::value, UpdateProvider::type);registerSqlProviderTypes(method, hints, DeleteProvider.class, DeleteProvider::value, DeleteProvider::type);Class? returnType MyBatisMapperTypeUtils.resolveReturnClass(mapperInterfaceType, method);registerReflectionTypeIfNecessary(returnType, hints);MyBatisMapperTypeUtils.resolveParameterClasses(mapperInterfaceType, method).forEach(x - registerReflectionTypeIfNecessary(x, hints));}}}SafeVarargsprivate T extends Annotation void registerSqlProviderTypes(Method method, RuntimeHints hints, ClassT annotationType, FunctionT, Class?... providerTypeResolvers) {for (T annotation : method.getAnnotationsByType(annotationType)) {for (FunctionT, Class? providerTypeResolver : providerTypeResolvers) {registerReflectionTypeIfNecessary(providerTypeResolver.apply(annotation), hints);}}}private void registerReflectionTypeIfNecessary(Class? type, RuntimeHints hints) {if (!type.isPrimitive() !type.getName().startsWith(java)) {hints.reflection().registerType(type, MemberCategory.values());}}}static class MyBatisMapperTypeUtils {private MyBatisMapperTypeUtils() {// NOP}static Class? resolveReturnClass(Class? mapperInterface, Method method) {Type resolvedReturnType TypeParameterResolver.resolveReturnType(method, mapperInterface);return typeToClass(resolvedReturnType, method.getReturnType());}static SetClass? resolveParameterClasses(Class? mapperInterface, Method method) {return Stream.of(TypeParameterResolver.resolveParamTypes(method, mapperInterface)).map(x - typeToClass(x, x instanceof Class ? (Class?) x : Object.class)).collect(Collectors.toSet());}private static Class? typeToClass(Type src, Class? fallback) {Class? result null;if (src instanceof Class?) {if (((Class?) src).isArray()) {result ((Class?) src).getComponentType();} else {result (Class?) src;}} else if (src instanceof ParameterizedType) {ParameterizedType parameterizedType (ParameterizedType) src;int index (parameterizedType.getRawType() instanceof Class Map.class.isAssignableFrom((Class?) parameterizedType.getRawType()) parameterizedType.getActualTypeArguments().length 1) ? 1 : 0;Type actualType parameterizedType.getActualTypeArguments()[index];result typeToClass(actualType, fallback);}if (result null) {result fallback;}return result;}}static class MyBatisMapperFactoryBeanPostProcessor implements MergedBeanDefinitionPostProcessor, BeanFactoryAware {private static final org.apache.commons.logging.Log LOG LogFactory.getLog(MyBatisMapperFactoryBeanPostProcessor.class);private static final String MAPPER_FACTORY_BEAN org.mybatis.spring.mapper.MapperFactoryBean;private ConfigurableBeanFactory beanFactory;Overridepublic void setBeanFactory(BeanFactory beanFactory) {this.beanFactory (ConfigurableBeanFactory) beanFactory;}Overridepublic void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class? beanType, String beanName) {if (ClassUtils.isPresent(MAPPER_FACTORY_BEAN, this.beanFactory.getBeanClassLoader())) {resolveMapperFactoryBeanTypeIfNecessary(beanDefinition);}}private void resolveMapperFactoryBeanTypeIfNecessary(RootBeanDefinition beanDefinition) {if (!beanDefinition.hasBeanClass() || !MapperFactoryBean.class.isAssignableFrom(beanDefinition.getBeanClass())) {return;}if (beanDefinition.getResolvableType().hasUnresolvableGenerics()) {Class? mapperInterface getMapperInterface(beanDefinition);if (mapperInterface ! null) {// Exposes a generic type information to context for prevent early initializingConstructorArgumentValues constructorArgumentValues new ConstructorArgumentValues();constructorArgumentValues.addGenericArgumentValue(mapperInterface);beanDefinition.setConstructorArgumentValues(constructorArgumentValues);beanDefinition.setTargetType(ResolvableType.forClassWithGenerics(beanDefinition.getBeanClass(), mapperInterface));}}}private Class? getMapperInterface(RootBeanDefinition beanDefinition) {try {return (Class?) beanDefinition.getPropertyValues().get(mapperInterface);}catch (Exception e) {LOG.debug(Fail getting mapper interface type., e);return null;}}}
}
package com.example.demo.config;import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** author lyk* since 2024-03-30*/
Configuration
//TODO 如果使用这个方式的话,记得一定要指定sqlSessionTemplateRef或sqlSessionFactoryRef https://github.com/mybatis/spring-boot-starter/wiki/Quick-Start-for-building-native-image#how-to-use-mapperscan
MapperScan(basePackages com.example.demo.mapper, sqlSessionTemplateRef sqlSessionTemplate)
public class MybatisPlusConfig {Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor plusInterceptor new MybatisPlusInterceptor();//plusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));//TODO 3.5.3.1 以下插件多的话,可能会报异常,这个在最新版本修改. https://github.com/baomidou/mybatis-plus/issues/5532
// plusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
// plusInterceptor.addInnerInterceptor(new IllegalSQLInnerInterceptor());
// plusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return plusInterceptor;}}
demo地址如下
https://gitee.com/lgbisha/springboot3-mybatis-plus/tree/master