乐趣区

关于web:开课吧WEB全栈架构师进阶指南30期

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;

@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()};
    }
}

}
复制代码
这个可能根据枚举值, 来抉择对应的数据库配置. 因为其余数据库临时不需要, 就只写了一个 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 配置等等, 最终简化为一个注解就可能实现, 最初必定很有成就感.

退出移动版