共计 5499 个字符,预计需要花费 14 分钟才能阅读完成。
download:奈学教育 -P8 百万 Java 架构师 3 期
大道至简, 一个注解实现数据库配置
明天来试试使用一个注解实现数据库配置. 最终成果:
开始
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 配置等等, 最终简化为一个注解就可能实现, 最初必定很有成就感.