download:开课吧-WEB全栈架构师进阶指南(30期)

大道至简,一个注解实现数据库配置
明天来试试使用一个注解实现数据库配置.最终成果:

开始
SpringBoot这个框架还是挺厉害的,或者有些人认为SpringBoot不算一个框架,它只是Spring的增强工具.
当然Spring对于Java而言有着不可动摇的地位.
就像我之前说的:

天不生Spring,Java万古如长夜.

可是SpringBoot的重要性也不能熟视无睹.
明天就基于SpringBoot来实现使用一个注解来实现数据库配置.
EnableXXX
在SpringBoot中,可能自定义这样一个注解@EnableXXX,就是启用某种功能.
在@EnableXXX这个注解上使用@Import这个注解,就可能把配置类,或者什么其余需要Spring治理的货色,注入到Spring容器.
就像上面这样,在启动类上使用这个注解, MybatisExtraConfig.class这个类就会注入到Spring容器中.相当于这个类就由Spring帮你治理了,你可能在这个类里使用@Autowired,或者获取容器等,而且MybatisExtraConfig这个类上不需要使用@Component等注解.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MybatisExtraConfig.class)
public @interface EnableMpExtra {
}
复制代码
其实不使用@EnableXXX也可能.在resources目录下新建一个文件夹META-INF,而后再新建一个文件spring.factories,而后在spring.factories中设置org.springframework.boot.autoconfigure.EnableAutoConfiguration=等于你的配置类.这样不使用注解,在包被引入的时候,就会主动加载配置类.
动静抉择数据库 ImportSelector
咱们也可能在@EnableXXX注解里加一些值,在启动类上使用的时候,设置这些值,最终咱们取到这些值.这些值就是连接数据库的各种参数,
要获取这些值,就少不了ImportSelector.
最初注解是这样的
@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();

}
复制代码
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;@Overridepublic 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()};    }}

}
复制代码
这个可能根据枚举值,来抉择对应的数据库配置.因为其余数据库临时不需要,就只写了一个MySQL的.
枚举类
public enum DbType {

MySQL,Oracle,PostgreSQL,SqlServer,MariaDB

}
复制代码
MySql配置类
这个类下面是没有@Configuration这个注解的,可是因为咱们在DBSelector中return了这个类,所以这个类也可能被Spring治理的.可能看到这个类中使用了@Bean这个注解,是可能失常使用的.
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());    //分页    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);}

}
复制代码
其余数据库的配置类就是一个空类.就像上面这样,不细说了.
public class OracleConfig {
}
复制代码
使用方法
第一种
简略点就是,还是在这个我的项目下,创建Controller,Service,Mapper,Domain,而后新建启动类,而后在启动类上使用@EnableDbStarter这个注解.就是在以后我的项目中测试.不推荐这种方法,因为看不出来成果.
第二种
可能把这个我的项目打成Jar包,在其余我的项目引入.成果比较直观一点,当然如果有maven私服,可能把这个我的项目发到私服,而后再其余我的项目使用.
我就是发到了私服,而后在其余我的项目中引用.
引入依赖,可能看到依赖也少了很多,不必再引入mysql-connector和druid的.

在启动类上使用,在注解上设置数据库相干的信息,因为注解有些值有默认值,就可能少写一点啦.
basePackage是给Mybatis用来扫描别名的.

整个我的项目结构如下,没有其余配置.

启动看一下

启动胜利.
请求一下

数据库
.
到这里,使用一个注解就实现了数据库的配置.
感兴趣的小伙伴可能试试其余的,比如Swagger配置,Redis配置,Dubbo配置等等,最终简化为一个注解就可能实现,最初必定很有成就感.