Mybatis自定义数据类型处理TypeHandler
mybatis依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.starter}</version>
</dependency>
<!-- 翻页插件,自动配置 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<!-- oracle驱动 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.nls</groupId>
<artifactId>orai18n</artifactId>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>在我们application.properties文件中配置mybatis.type-handlers-package=com.xxx.xxx,com.xxx.xxx是typeHandlers的包名
mybatis.type-handlers-package=cn.shhuifu.quickframework.boot.datasource.typeHandler在此路径下创建处理类OracleTimestampHandler把oracle.sql.TIMESTAMP转为java.sql.Timestmap
package cn.shhuifu.quickframework.boot.datasource.typeHandler;
import oracle.sql.TIMESTAMP;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.*;
/**
* @ClassName OracleTimestampHandler
* @Description TIMESTAMP自动转换类型
* @Author LiuQian
* @Date 2022-11-13
**/
@MappedJdbcTypes(JdbcType.TIMESTAMP)
@MappedTypes(TIMESTAMP.class)
public class OracleTimestampHandler extends BaseTypeHandler<Timestamp> {
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Timestamp timestamp, JdbcType jdbcType) throws SQLException {
preparedStatement.setTimestamp(i, timestamp);
}
@Override
public Timestamp getNullableResult(ResultSet resultSet, String s) throws SQLException {
return parse2time(resultSet.getObject(s));
}
@Override
public Timestamp getNullableResult(ResultSet resultSet, int i) throws SQLException {
return parse2time(resultSet.getObject(i));
}
@Override
public Timestamp getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
return parse2time(callableStatement.getObject(i));
}
private Timestamp parse2time(Object value) {
if (value instanceof Date) {
return new Timestamp(((Date) value).getTime());
} else if (value instanceof Time) {
return new Timestamp(((Time) value).getTime());
} else if (value instanceof Timestamp) {
return (Timestamp) value;
} else if(value instanceof TIMESTAMP){
try {
return ((TIMESTAMP)value).timestampValue();
} catch (SQLException throwables) {
return null;
}
}
return null;
}
}其实主要通过MybatisAutoConfiguration自动配置类的方式让SqlSessionFactory在初始化的时候指定包路径,该类内部会引用环境变量MybatisProperties,
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
public class MybatisAutoConfiguration implements InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(MybatisAutoConfiguration.class);
private final MybatisProperties properties;
private final Interceptor[] interceptors;
private final TypeHandler[] typeHandlers;
private final LanguageDriver[] languageDrivers;
private final ResourceLoader resourceLoader;
private final DatabaseIdProvider databaseIdProvider;
private final List<ConfigurationCustomizer> configurationCustomizers;
private final List<SqlSessionFactoryBeanCustomizer> sqlSessionFactoryBeanCustomizers;
public MybatisAutoConfiguration(MybatisProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider, ObjectProvider<TypeHandler[]> typeHandlersProvider, ObjectProvider<LanguageDriver[]> languageDriversProvider, ResourceLoader resourceLoader, ObjectProvider<DatabaseIdProvider> databaseIdProvider, ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider, ObjectProvider<List<SqlSessionFactoryBeanCustomizer>> sqlSessionFactoryBeanCustomizers) {
this.properties = properties;
this.interceptors = (Interceptor[])interceptorsProvider.getIfAvailable();
this.typeHandlers = (TypeHandler[])typeHandlersProvider.getIfAvailable();
this.languageDrivers = (LanguageDriver[])languageDriversProvider.getIfAvailable();
this.resourceLoader = resourceLoader;
this.databaseIdProvider = (DatabaseIdProvider)databaseIdProvider.getIfAvailable();
this.configurationCustomizers = (List)configurationCustomizersProvider.getIfAvailable();
this.sqlSessionFactoryBeanCustomizers = (List)sqlSessionFactoryBeanCustomizers.getIfAvailable();
}
public void afterPropertiesSet() {
this.checkConfigFileExists();
}
private void checkConfigFileExists() {
if (this.properties.isCheckConfigLocation() && StringUtils.hasText(this.properties.getConfigLocation())) {
Resource resource = this.resourceLoader.getResource(this.properties.getConfigLocation());
Assert.state(resource.exists(), "Cannot find config location: " + resource + " (please add config file or check your Mybatis configuration)");
}
}
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(this.properties.getConfigLocation())) {
factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
this.applyConfiguration(factory);
if (this.properties.getConfigurationProperties() != null) {
factory.setConfigurationProperties(this.properties.getConfigurationProperties());
}
if (!ObjectUtils.isEmpty(this.interceptors)) {
factory.setPlugins(this.interceptors);
}
if (this.databaseIdProvider != null) {
factory.setDatabaseIdProvider(this.databaseIdProvider);
}
if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
}
if (this.properties.getTypeAliasesSuperType() != null) {
factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());
}
if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
}
if (!ObjectUtils.isEmpty(this.typeHandlers)) {
factory.setTypeHandlers(this.typeHandlers);
}
if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
factory.setMapperLocations(this.properties.resolveMapperLocations());
}
Set<String> factoryPropertyNames = (Set)Stream.of((new BeanWrapperImpl(SqlSessionFactoryBean.class)).getPropertyDescriptors()).map(FeatureDescriptor::getName).collect(Collectors.toSet());
Class<? extends LanguageDriver> defaultLanguageDriver = this.properties.getDefaultScriptingLanguageDriver();
if (factoryPropertyNames.contains("scriptingLanguageDrivers") && !ObjectUtils.isEmpty(this.languageDrivers)) {
factory.setScriptingLanguageDrivers(this.languageDrivers);
if (defaultLanguageDriver == null && this.languageDrivers.length == 1) {
defaultLanguageDriver = this.languageDrivers[0].getClass();
}
}
if (factoryPropertyNames.contains("defaultScriptingLanguageDriver")) {
factory.setDefaultScriptingLanguageDriver(defaultLanguageDriver);
}
this.applySqlSessionFactoryBeanCustomizers(factory);
return factory.getObject();
}
private void applyConfiguration(SqlSessionFactoryBean factory) {
org.apache.ibatis.session.Configuration configuration = this.properties.getConfiguration();
if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {
configuration = new org.apache.ibatis.session.Configuration();
}
if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {
Iterator var3 = this.configurationCustomizers.iterator();
while(var3.hasNext()) {
ConfigurationCustomizer customizer = (ConfigurationCustomizer)var3.next();
customizer.customize(configuration);
}
}
factory.setConfiguration(configuration);
}
private void applySqlSessionFactoryBeanCustomizers(SqlSessionFactoryBean factory) {
if (!CollectionUtils.isEmpty(this.sqlSessionFactoryBeanCustomizers)) {
Iterator var2 = this.sqlSessionFactoryBeanCustomizers.iterator();
while(var2.hasNext()) {
SqlSessionFactoryBeanCustomizer customizer = (SqlSessionFactoryBeanCustomizer)var2.next();
customizer.customize(factory);
}
}
}
@Bean
@ConditionalOnMissingBean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
ExecutorType executorType = this.properties.getExecutorType();
return executorType != null ? new SqlSessionTemplate(sqlSessionFactory, executorType) : new SqlSessionTemplate(sqlSessionFactory);
}
@Configuration
@Import({MybatisAutoConfiguration.AutoConfiguredMapperScannerRegistrar.class})
@ConditionalOnMissingBean({MapperFactoryBean.class, MapperScannerConfigurer.class})
public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {
public MapperScannerRegistrarNotFoundConfiguration() {
}
public void afterPropertiesSet() {
MybatisAutoConfiguration.logger.debug("Not found configuration for registering mapper bean using @MapperScan, MapperFactoryBean and MapperScannerConfigurer.");
}
}
public static class AutoConfiguredMapperScannerRegistrar implements BeanFactoryAware, EnvironmentAware, ImportBeanDefinitionRegistrar {
private BeanFactory beanFactory;
private Environment environment;
public AutoConfiguredMapperScannerRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (!AutoConfigurationPackages.has(this.beanFactory)) {
MybatisAutoConfiguration.logger.debug("Could not determine auto-configuration package, automatic mapper scanning disabled.");
} else {
MybatisAutoConfiguration.logger.debug("Searching for mappers annotated with @Mapper");
List<String> packages = AutoConfigurationPackages.get(this.beanFactory);
if (MybatisAutoConfiguration.logger.isDebugEnabled()) {
packages.forEach((pkg) -> {
MybatisAutoConfiguration.logger.debug("Using auto-configuration base package '{}'", pkg);
});
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
builder.addPropertyValue("processPropertyPlaceHolders", true);
builder.addPropertyValue("annotationClass", Mapper.class);
builder.addPropertyValue("basePackage", StringUtils.collectionToCommaDelimitedString(packages));
BeanWrapper beanWrapper = new BeanWrapperImpl(MapperScannerConfigurer.class);
Set<String> propertyNames = (Set)Stream.of(beanWrapper.getPropertyDescriptors()).map(FeatureDescriptor::getName).collect(Collectors.toSet());
if (propertyNames.contains("lazyInitialization")) {
builder.addPropertyValue("lazyInitialization", "${mybatis.lazy-initialization:false}");
}
if (propertyNames.contains("defaultScope")) {
builder.addPropertyValue("defaultScope", "${mybatis.mapper-default-scope:}");
}
boolean injectSqlSession = (Boolean)this.environment.getProperty("mybatis.inject-sql-session-on-mapper-scan", Boolean.class, Boolean.TRUE);
if (injectSqlSession && this.beanFactory instanceof ListableBeanFactory) {
ListableBeanFactory listableBeanFactory = (ListableBeanFactory)this.beanFactory;
Optional<String> sqlSessionTemplateBeanName = Optional.ofNullable(this.getBeanNameForType(SqlSessionTemplate.class, listableBeanFactory));
Optional<String> sqlSessionFactoryBeanName = Optional.ofNullable(this.getBeanNameForType(SqlSessionFactory.class, listableBeanFactory));
if (!sqlSessionTemplateBeanName.isPresent() && sqlSessionFactoryBeanName.isPresent()) {
builder.addPropertyValue("sqlSessionFactoryBeanName", sqlSessionFactoryBeanName.get());
} else {
builder.addPropertyValue("sqlSessionTemplateBeanName", sqlSessionTemplateBeanName.orElse("sqlSessionTemplate"));
}
}
builder.setRole(2);
registry.registerBeanDefinition(MapperScannerConfigurer.class.getName(), builder.getBeanDefinition());
}
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
private String getBeanNameForType(Class<?> type, ListableBeanFactory factory) {
String[] beanNames = factory.getBeanNamesForType(type);
return beanNames.length > 0 ? beanNames[0] : null;
}
}
}
本文链接:
/archives/1753525982479
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
刘同学的小站!
喜欢就支持一下吧