Low的开始
个人不太喜欢xml,xml当然是好的了,青菜萝卜各有所爱 .
于是尝试了下全注解的方式使用springboot mybatis druid多数据源
-----------------------------------------------------------------------------------------
Code
1. yml配置
两个数据源配置,是 同服务器(localhost),同类型(Mysql)不同库(dog,cat) ↓↓↓
spring:
datasource:
beginner:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/beginner?useSSL=true&characterEncoding=utf-8
username: dogcat
password: 123456
cat:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/cat?useSSL=true&characterEncoding=utf-8
username: dogcat
password: 123456
2. 配置数据源
Beginner 数据源 extends DruidDBConfig(工具类,代码在后面) ↓↓↓
PlatformTransactionManager 事务管理 和 头部的@EnableTransactionManagement一起用
@Configuration @EnableTransactionManagement public class DBBeginnerConfiguration extends DruidDBConfig { @Value("${spring.datasource.beginner.url}") private String url; @Value("${spring.datasource.beginner.username}") private String username; @Value("${spring.datasource.beginner.password}") private String password; // 注册 spring.datasource.beginner 下配置的基础数据源 @Bean(name = "datasourceBeginner", initMethod = "init", destroyMethod = "close") @Primary public DruidDataSource dataSource() { return super.buildDataSource(url, username, password); } @Bean @Primary public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } }
Cat数据源 和上面一样, 就是少了@Primary注解,代码如下: ↓↓↓
@Configuration @EnableTransactionManagement public class DBCatConfiguration extends DruidDBConfig { @Value("${spring.datasource.cat.url}") private String url; @Value("${spring.datasource.cat.username}") private String username; @Value("${spring.datasource.cat.password}") private String password; // 注册 spring.datasource.dogMapping 下配置的基础数据源 @Bean(name = "datasourceCat", initMethod = "init", destroyMethod = "close") public DruidDataSource dataSource() { return super.buildDataSource(url, username, password); } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } }
PS: 可能有人会问SqlSessionFactory呢,怎么操作DataSource呢,没有xml不需要, (SqlSessionFactory后续API都是基于XML实现对应的CURD),个人初学理解,如果有错,请留言指教,谢谢大家
3. 工具引入类
用于方便设置一堆属性, ↓↓↓
@Import-->DruidManageConfig.class (Druid的管理类)
@EnableConfigurationProperties(DruidDbProperties.class) 里面是一堆属性值的设置
@Configuration @EnableConfigurationProperties(DruidDbProperties.class) @Import({DruidManageConfig.class}) public class DruidDBConfig { @Resource private DruidDbProperties druidDbProperties; public DruidDataSource buildDataSource(String url, String username, String password) { if (StringUtils.isEmpty(url)) { throw new MyException(-2,"Path:DruidDBConfig.buildDataSource DataSource Url lose"); } DruidDataSource datasource = new DruidDataSource(); datasource.setUrl(url); datasource.setUsername(username); datasource.setPassword(password); datasource.setDriverClassName(druidDbProperties.getDriverClassName()); datasource.setInitialSize(druidDbProperties.getInitialSize()); datasource.setMinIdle(druidDbProperties.getMinIdle()); datasource.setMaxActive(druidDbProperties.getMaxActive()); datasource.setMaxWait(druidDbProperties.getMaxWait()); datasource.setTimeBetweenEvictionRunsMillis(druidDbProperties.getTimeBetweenEvictionRunsMillis()); datasource.setMinEvictableIdleTimeMillis(druidDbProperties.getMinEvictableIdleTimeMillis()); datasource.setValidationQuery(druidDbProperties.getValidationQuery()); datasource.setTestWhileIdle(druidDbProperties.isTestWhileIdle()); datasource.setTestOnBorrow(druidDbProperties.isTestOnBorrow()); datasource.setTestOnReturn(druidDbProperties.isTestOnReturn()); datasource.setConnectProperties(druidDbProperties.getProperties()); try { datasource.setFilters(druidDbProperties.getFilters()); } catch (SQLException e) { throw new MyException(-3,"Path:DruidDBConfig.buildDataSource Druid Filters Error"); } datasource.setConnectionProperties(druidDbProperties.getConnectionProperties()); return datasource; } }
4. 属性值 配置文件
@ConfigurationProperties(prefix = "druid") public class DruidDbProperties { private String driverClassName = "com.mysql.jdbc.Driver"; //初始化时建立物理连接的个数初始化发生在显示调用init方法,或者第一次getConnection时 private int initialSize = 10; //最小连接池数量 private int minIdle = 50; //最大连接池数量 private int maxActive = 300; //获取连接时最大等待时间,单位毫秒配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁 private int maxWait = 60000; /** * 有两个含义: * 1: Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接 * 2: testWhileIdle的判断依据,详细看testWhileIdle属性的说明 */ private int timeBetweenEvictionRunsMillis = 60000; //连接保持空闲而不被驱逐的最长时间 private int minEvictableIdleTimeMillis = 3600000; /** * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x' * 如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用 */ private String validationQuery = "SELECT 1"; /** * 建议配置为true,不影响性能,并且保证安全性 * 申请连接的时候检测, * 如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效 */ private boolean testWhileIdle = true; //申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 private boolean testOnBorrow = false; //归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 private boolean testOnReturn = false; /** * 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有: 监控统计用的filter:stat 日志用的filter:log4j * 防御sql注入的filter:wall * 1.stat,wall,log4j * 2.mergeStat,config,wall */ private String filters = "mergeStat,config,wall"; private String connectionProperties; private Properties properties=new Properties(){ { put("druid.stat.mergeSql", "true"); put("druid.stat.slowSqlMillis", "5000"); } }; //白名单 private String allow; //黑名单 private String deny; private String username = "admin"; private String password = "123456"; //getter & setter... }
5. Druid 管理
@EnableConfigurationProperties(DruidDbProperties.class) @EnableAspectJAutoProxy(proxyTargetClass = true) public class DruidManageConfig { @Resource private DruidDbProperties druidDbProperties; //druid监控视图配置 @Bean public ServletRegistrationBean druidServlet() { ServletRegistrationBean reg = new ServletRegistrationBean(); reg.setServlet(new StatViewServlet()); reg.addUrlMappings("/druid/*"); if (!StringUtils.isEmpty(druidDbProperties.getAllow())) { reg.addInitParameter("allow", druidDbProperties.getAllow()); // 白名单 } if (!StringUtils.isEmpty(druidDbProperties.getDeny())) { reg.addInitParameter("deny", druidDbProperties.getDeny()); // 黑名单 } reg.addInitParameter("loginUsername", druidDbProperties.getUsername()); reg.addInitParameter("loginPassword", druidDbProperties.getPassword()); return reg; } /** * 配置监控拦截器 * 过滤不需要监控的后缀 * @return */ @Bean public FilterRegistrationBean filterRegistrationBean() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new WebStatFilter()); filterRegistrationBean.addUrlPatterns("/*"); filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); return filterRegistrationBean; } //监听Spring 1.定义拦截器 @Bean public DruidStatInterceptor druidStatInterceptor() { return new DruidStatInterceptor(); } //定义切入点 @Bean public JdkRegexpMethodPointcut druidStatPointcut() { JdkRegexpMethodPointcut druidStatPointcut = new JdkRegexpMethodPointcut(); String patterns = "com.beginner.mapper.*.*"; druidStatPointcut.setPatterns(patterns); return druidStatPointcut; } //定义通知类 @Bean public Advisor druidStatAdvisor() { return new DefaultPointcutAdvisor(druidStatPointcut(), druidStatInterceptor()); } }
6. 搞完了,测一下
Beginner 实体类:
public class Beginners { private Long id; private String name; private String remark; //...... }
Cat 实体类:
public class Cats { private Long id; private String name; private String remark; }
没区别是因为懒...灰白色的自言自语,绝对看不到, 如果你看到了,以下操作都是一样的
接口 Mapper : ↓↓↓
这里注意的是主库是beginner,所有对主库进行操作,是直接操作
其他库的操作,需要在表名前面加库名(库名.表明),也就是.yml配置中spring.datasource.url中库的名字
@Mapper public interface BeginnersMapper { @Insert("insert into beginners(name,remark) values(#{name},#{remark})") int insert(Beginners beginners); }
@Mapper public interface CatsMapper { @Insert("insert into cat.cats(name,remark) values(#{name},#{remark})") int insert(Cats cats); }
测试 Controller : ↓↓↓
@RestController @RequestMapping("/two") public class TwoController { @Autowired private BeginnersMapper beginnersMapper; @Autowired private CatsMapper catsMapper; @GetMapping("/beginners") public Result beginners_insert() { Beginners beginners = new Beginners(); beginners.setName("beginners"); beginners.setRemark("beginners_remark"); beginnersMapper.insert(beginners); return ResultUtil.success(); } @GetMapping("/cats") public Result cats_insert() { Cats cats = new Cats(); cats.setName("cats"); cats.setRemark("cats_remark"); catsMapper.insert(cats); return ResultUtil.success(); } }
有尝试过 同服务器,不同类型库,但是失败了,因为没有找到不用xml的方式,如果有,请指教留言,谢谢大家
Low 的写法完成,如果有更方便的操作,请大家赐教,谢谢大家
--------------------------------------------------------------------------------------------------