当前位置:网站首页>To simplify, one annotation completes the database configuration

To simplify, one annotation completes the database configuration

2022-06-09 21:15:00 Get up so early

Today, let's try to use an annotation to complete the database configuration . Final effect :

Start

SpringBoot This framework is very powerful , Maybe some people think SpringBoot Not a framework , It's just Spring Enhanced tools for .

Of course Spring about Java It has an unshakable position .

Like I said before :

Heaven is not born Spring,Java It's like a long night .

But SpringBoot The importance of .

Today is based on SpringBoot To use an annotation to complete the database configuration .

EnableXXX

stay SpringBoot in , You can customize such an annotation @EnableXXX, Is to enable a certain function .

stay @EnableXXX This annotation uses @Import This annotation , You can configure the class , Or something else Spring Things to manage , Injection into Spring Containers .

It looks like this , Use this annotation on the startup class , MybatisExtraConfig.class This class will be injected into Spring In the container . The equivalent of this class is Spring Managed it for you , You can use... In this class @Autowired, Or get containers, etc , and MybatisExtraConfig There is no need to use... On this class @Component Etc .

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MybatisExtraConfig.class)
public @interface EnableMpExtra {
}
 Copy code 

You don't actually use @EnableXXX It's fine too . stay resources Create a new folder in the directory META-INF, Then create a new file spring.factories, And then in spring.factories Set in org.springframework.boot.autoconfigure.EnableAutoConfiguration= Equal to your configuration class . This does not use annotations , When the package is introduced , The configuration class will be automatically loaded .

Dynamic database selection ImportSelector

We can also do that @EnableXXX Add some values to the annotation , When used on the startup class , Set these values , Finally we get these values . These values are the parameters for connecting to the database ,

To get these values , It is indispensable. ImportSelector.

The final comment is like this

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DBSelector.class)
public @interface EnableDbStarter {

    DbType type() default DbType.MySQL;

    String url() default "localhost";

    String port() default "3306";

    String dbName();

    String username() default "root";

    String password();

    String basePackage();
}
 Copy code 

DBSelector

public class DBSelector implements ImportSelector {

    public static String url;
    public static String port;
    public static String dbName;
    public static String username;
    public static String password;
    public static String basePackage;

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableDbStarter.class.getName()));
        DbType type = attributes.getEnum("type");
        url = attributes.getString("url");
        port = attributes.getString("port");
        dbName = attributes.getString("dbName");
        username = attributes.getString("username");
        password = attributes.getString("password");
        basePackage = attributes.getString("basePackage");

        switch (type) {
            case Oracle:
                return new String[]{OracleConfig.class.getName()};
            case MariaDB:
                return new String[]{MariaDBConfig.class.getName()};
            case SqlServer:
                return new String[]{SqlServerConfig.class.getName()};
            case PostgreSQL:
                return new String[]{PostgreSQLConfig.class.getName()};
            case MySQL:
            default:
                return new String[]{MySqlConfig.class.getName()};
        }
    }
}
 Copy code 

This can be done according to the enumeration value , To select the corresponding database configuration . Because other databases do not need , Just one MySQL Of .

Enumeration class

public enum DbType {
    MySQL,
    Oracle,
    PostgreSQL,
    SqlServer,
    MariaDB
}
 Copy code 

MySql Configuration class

There is no above this class @Configuration This annotated , But because we are DBSelector in return This class , So this class can also be Spring Managed . You can see that... Is used in this class @Bean This annotation , It can be used normally .

public class MySqlConfig {

    @Bean("dataSource")
    public DataSource dataSource() {
        try {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql://" + DBSelector.url + ":" + DBSelector.port + "/" + DBSelector.dbName + "?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai");
            dataSource.setUsername(DBSelector.username);
            dataSource.setPassword(DBSelector.password);

            dataSource.setInitialSize(1);
            dataSource.setMaxActive(20);
            dataSource.setMinIdle(1);
            dataSource.setMaxWait(60_000);
            dataSource.setPoolPreparedStatements(true);
            dataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
            dataSource.setTimeBetweenEvictionRunsMillis(60_000);
            dataSource.setMinEvictableIdleTimeMillis(300_000);
            dataSource.setValidationQuery("SELECT 1");
            return dataSource;
        } catch (Throwable throwable) {
            throw new RuntimeException();
        }
    }

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean.setVfs(SpringBootVFS.class);
        factoryBean.setTypeAliasesPackage(DBSelector.basePackage);

        Resource[] mapperResources = new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml");
        factoryBean.setMapperLocations(mapperResources);
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.addInterceptor(new SqlExplainInterceptor());
        // Pagination 
        configuration.addInterceptor(new PaginationInterceptor());
        configuration.setUseGeneratedKeys(true);
        factoryBean.setConfiguration(configuration);
        return factoryBean.getObject();
    }

    @Bean(name = "sqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean(name = "transactionManager")
    public PlatformTransactionManager platformTransactionManager(@Qualifier("dataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "transactionTemplate")
    public TransactionTemplate transactionTemplate(@Qualifier("transactionManager") PlatformTransactionManager transactionManager) {
        return new TransactionTemplate(transactionManager);
    }

}
 Copy code 

The configuration class of other databases is an empty class . It looks like this , Don't elaborate. .

public class OracleConfig {
}
 Copy code 

Usage method

The first one is

The simple point is , Still under this project , establish Controller,Service,Mapper,Domain, Then create a new startup class , Then use... On the startup class @EnableDbStarter This annotation . Is to test in the current project . This method is not recommended , Because I can't see the effect .

The second kind

You can type this project as Jar package , Introduced in other projects . The effect is more intuitive , Of course, if there is maven Private clothes , You can send this item to the private server , Then use... For other projects .

I just sent it to the private server , Then reference it in other projects .

Introduce dependencies , It can be seen that there is much less dependence , No more introduction mysql-connector and druid Of .

Use... On startup classes , Set the database related information on the annotation , Because some values in the annotation have default values , You can write less .

basePackage It's for Mybatis Used to scan aliases .

The overall project structure is as follows , No other configuration .

Start and have a look

Successful launch .

Please

database

.

Come here , Using an annotation completes the configuration of the database .

Interested friends can try other , such as Swagger To configure ,Redis To configure ,Dubbo The configuration, etc. , Finally, it can be simplified to an annotation , I must have a great sense of achievement in the end .

Finally, I would like to welcome official account of you Nanzhao Blog , Learning together , Progress together . come on.

Originality is not easy. , Reprint please indicate the source !!!

原网站

版权声明
本文为[Get up so early]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/160/202206092050049304.html