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