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配置等等,最终简化为一个注解就可能实现,最初必定很有成就感.