日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Springboot+Mybatis+通用Mapper多數(shù)據(jù)源實(shí)現(xiàn)數(shù)據(jù)同步

 Architect_home 2019-04-19

有個(gè)需求需要查詢遠(yuǎn)程數(shù)據(jù)庫(kù),然后將遠(yuǎn)程數(shù)據(jù)庫(kù)中的數(shù)據(jù)抓取到本地,遠(yuǎn)程數(shù)據(jù)庫(kù)中的數(shù)據(jù)是每天都增加的,所以就需要寫個(gè)程序自動(dòng)實(shí)現(xiàn)實(shí)時(shí)抓取。

這里我用到的框架是Springboot2.0+Mybatis+Mapper,涉及的數(shù)據(jù)庫(kù)有SqlServer,Oracle,Mysql

添加依賴

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-quartz</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.quartz-scheduler</groupId>
  8. <artifactId>quartz</artifactId>
  9. <version>2.3.0</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-web</artifactId>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.springframework.boot</groupId>
  17. <artifactId>spring-boot-starter-jdbc</artifactId>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.mybatis.spring.boot</groupId>
  21. <artifactId>mybatis-spring-boot-starter</artifactId>
  22. <version>1.3.1</version>
  23. </dependency>
  24. <!--<dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-data-jpa</artifactId>
  27. </dependency>-->
  28. <dependency>
  29. <groupId>org.springframework.boot</groupId>
  30. <artifactId>spring-boot-devtools</artifactId>
  31. <scope>runtime</scope>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.projectlombok</groupId>
  35. <artifactId>lombok</artifactId>
  36. <optional>true</optional>
  37. </dependency>
  38. <dependency>
  39. <groupId>org.springframework.boot</groupId>
  40. <artifactId>spring-boot-starter-test</artifactId>
  41. <scope>test</scope>
  42. </dependency>
  43. <dependency>
  44. <groupId>commons-lang</groupId>
  45. <artifactId>commons-lang</artifactId>
  46. <version>2.6</version>
  47. </dependency>
  48. <!-- sqlserver -->
  49. <dependency>
  50. <groupId>com.microsoft.sqlserver</groupId>
  51. <artifactId>sqljdbc4</artifactId>
  52. <version>4.4</version>
  53. </dependency>
  54. <!-- oracle -->
  55. <dependency>
  56. <groupId>com.oracle</groupId>
  57. <artifactId>ojdbc14</artifactId>
  58. <version>10.2.0.4.0</version>
  59. </dependency>
  60. <!-- 通用Maper -->
  61. <dependency>
  62. <groupId>tk.mybatis</groupId>
  63. <artifactId>mapper-spring-boot-starter</artifactId>
  64. <version>1.2.4</version>
  65. </dependency>
  66. <!--druid -->
  67. <dependency>
  68. <groupId>com.alibaba</groupId>
  69. <artifactId>druid</artifactId>
  70. <version>1.0.28</version>
  71. </dependency>
  72. <!-- log4j -->
  73. <dependency>
  74. <groupId>org.slf4j</groupId>
  75. <artifactId>slf4j-api</artifactId>
  76. <version>1.7.25</version>
  77. </dependency>

如果沒(méi)有l(wèi)og包,可能在配置文件中的DruidDataSource會(huì)出現(xiàn)錯(cuò)誤提示,但實(shí)際上不會(huì)影響到程序。

application.yml項(xiàng)目配置

也可以用application.properties格式配置,但是感覺(jué)yml格式看起來(lái)比較直觀.

  1. ##端口
  2. server:
  3. port:8081
  4. logging:
  5. level:
  6. cn.javabb.bootdemo.mapper: info
  7. spring:
  8. remote-datasource:
  9. url: jdbc:sqlserver://66.66.66.66:1433;DatabaseName=dbName
  10. username: sa
  11. password: 123
  12. #使用Druid的數(shù)據(jù)源
  13. type: com.alibaba.druid.pool.DruidDataSource
  14. driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
  15. filters: stat
  16. maxActive: 20
  17. initialSize: 1
  18. maxWait: 60000
  19. minIdle: 1
  20. timeBetweenEvictionRunsMillis: 60000
  21. minEvictableIdleTimeMillis: 300000
  22. validationQuery: select 'x'
  23. testWhileIdle: true
  24. testOnBorrow: false
  25. testOnReturn: false
  26. poolPreparedStatements: true
  27. maxOpenPreparedStatements: 20
  28. local-datasource:
  29. url: jdbc:sqlserver://77.77.77.77:1433;DatabaseName=dbName
  30. username: sa
  31. password: 1234
  32. #使用Druid的數(shù)據(jù)源
  33. type: com.alibaba.druid.pool.DruidDataSource
  34. driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
  35. filters: stat
  36. maxActive: 20
  37. initialSize: 1
  38. maxWait: 60000
  39. minIdle: 1
  40. timeBetweenEvictionRunsMillis: 60000
  41. minEvictableIdleTimeMillis: 300000
  42. validationQuery: select 'x'
  43. testWhileIdle: true
  44. testOnBorrow: false
  45. testOnReturn: false
  46. poolPreparedStatements: true
  47. maxOpenPreparedStatements: 20
  48. oracle-datasource:
  49. url: jdbc:oracle:thin:@88.88.88.88:1521/sid
  50. username: tiger
  51. password: tiger
  52. #使用Druid的數(shù)據(jù)源
  53. type: com.alibaba.druid.pool.DruidDataSource
  54. driver-class-name: oracle.jdbc.driver.OracleDriver
  55. filters: stat
  56. maxActive: 20
  57. initialSize: 1
  58. maxWait: 60000
  59. minIdle: 1
  60. timeBetweenEvictionRunsMillis: 60000
  61. minEvictableIdleTimeMillis: 300000
  62. validationQuery: select 'x'
  63. testWhileIdle: true
  64. testOnBorrow: false
  65. testOnReturn: false
  66. poolPreparedStatements: true
  67. maxOpenPreparedStatements: 20
  68. #Mybatis
  69. mybatis:
  70. configuration:
  71. map-underscore-to-camel-case: true
  72. mapper-locations: classpath:mapper/*.xml
  73. typeAliasesPackage: cn.javabb.**.entity
  74. #Mapper
  75. mapper:
  76. mappers:
  77. - cn.javabb.bootdemo.base.BaseMapper
  78. not-empty: false
  79. identity: sqlserver
  80. before: true

其中remote-datasource,oracle-datasource和local-datasource為兩個(gè)不同的數(shù)據(jù)源,mybatis配置和通用mapper配置一樣的,如果不需要用到通用mapper可以去掉配置。

application啟動(dòng)類:

  1. @EnableAsync
  2. @EnableScheduling
  3. @ServletComponentScan
  4. @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class, MybatisAutoConfiguration.class})
  5. public class BootDemoApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(BootDemoApplication.class, args);
  8. }
  9. }

注解說(shuō)明:

@EnableAsync:開(kāi)啟異步任務(wù)支持,如果不需要可以去掉

@EnableScheduling:開(kāi)啟定時(shí)任務(wù)支持

@ServletComponentScan:用來(lái)掃描mapper

@SpringBootApplication:springboot注解支持

注意:如果項(xiàng)目依賴中有,mybatis-spring-boot-starter,會(huì)默認(rèn)自動(dòng)根據(jù)配置文件配置mybatis,如果剛開(kāi)始項(xiàng)目沒(méi)有配置DataSource,啟動(dòng)項(xiàng)目就會(huì)報(bào)錯(cuò),在這里去掉DataSource的默認(rèn)自動(dòng)配置類不加載,使項(xiàng)目在使用的時(shí)候選擇去DataSource。

數(shù)據(jù)源配置

有幾個(gè)數(shù)據(jù)源配置幾個(gè)DataSource

配置第一個(gè)數(shù)據(jù)源:local-datasource

  1. import org.apache.ibatis.session.SqlSessionFactory;
  2. import org.mybatis.spring.SqlSessionFactoryBean;
  3. import org.springframework.beans.factory.annotation.Qualifier;
  4. import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
  5. import org.springframework.boot.context.properties.ConfigurationProperties;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  9. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
  10. import tk.mybatis.spring.annotation.MapperScan;
  11. import javax.sql.DataSource;
  12. @Configuration
  13. @MapperScan(basePackages = "cn.javabb.bootdemo.mapper.local",sqlSessionFactoryRef = "localSqlSessionFactory")
  14. public class LocalDataSourceConfig {
  15. @Bean(name = "localDataSource")
  16. @ConfigurationProperties("spring.local-datasource")
  17. public DataSource localDataSource(){
  18. return DataSourceBuilder.create().build();
  19. }
  20. @Bean(name = "localSqlSessionFactory")
  21. public SqlSessionFactory sqlSessionFactory(@Qualifier("localDataSource") DataSource dataSource) throws Exception {
  22. SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
  23. sessionFactoryBean.setDataSource(dataSource);
  24. sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
  25. .getResources("classpath*:mapper/local/*.xml"));
  26. return sessionFactoryBean.getObject();
  27. }
  28. @Bean(name = "localTransactionManager")
  29. public DataSourceTransactionManager localTransactionManager(){
  30. return new DataSourceTransactionManager(localDataSource());
  31. }
  32. }

spring.local-datasource 為application.yml中配置的數(shù)據(jù)源名稱

classpath*:mapper/local/*.xml 指定local數(shù)據(jù)源的mybatis的xml文件位置

原本一個(gè)數(shù)據(jù)源的時(shí)候,可以在啟動(dòng)程序的時(shí)候加載DataSource,但是這里是多數(shù)據(jù)源,需要為每個(gè)數(shù)據(jù)源配置DataSource,并且需要添加MapperScan注解,(因?yàn)檫@里是使用的通用Mapper,所以引入的class應(yīng)該是mapper的,import tk.mybatis.spring.annotation.MapperScan;,如果沒(méi)用就引入org的MapperScan)

basePackages這里的包路徑是需要用到這個(gè)數(shù)據(jù)源的路徑,這個(gè)包下所有的接口文件都會(huì)使用這個(gè)local數(shù)據(jù)源

配置第二個(gè)數(shù)據(jù)源:remote-datasource

  1. @Configuration
  2. @MapperScan(basePackages = "cn.javabb.bootdemo.mapper.remote",sqlSessionFactoryRef = "remoteSqlSessionFactory")
  3. public class RemoteDataSourceConfig {
  4. @Bean(name = "remoteDataSource")
  5. @Primary
  6. @ConfigurationProperties("spring.remote-datasource")
  7. public DataSource remoteDataSource(){
  8. return DataSourceBuilder.create().build();
  9. }
  10. @Bean(name = "remoteSqlSessionFactory")
  11. @Primary
  12. public SqlSessionFactory sqlSessionFactory(@Qualifier("remoteDataSource") DataSource dataSource) throws Exception {
  13. SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
  14. sessionFactoryBean.setDataSource(dataSource);
  15. sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
  16. .getResources("classpath*:mapper/remote/*.xml"));
  17. return sessionFactoryBean.getObject();
  18. }
  19. @Bean(name = "remoteTransactionManager")
  20. @Primary
  21. public DataSourceTransactionManager remoteTransactionManager(){
  22. return new DataSourceTransactionManager(remoteDataSource());
  23. }
  24. }

@Primary指定默認(rèn)數(shù)據(jù)源。

配置第三個(gè)數(shù)據(jù)源:oracle-datasource

  1. @Configuration
  2. @MapperScan(basePackages = "cn.javabb.bootdemo.mapper.oracle",sqlSessionFactoryRef = "oracleSqlSessionFactory")
  3. public class OracleDataSourceConfig {
  4. @Bean(name = "oracleDataSource")
  5. @ConfigurationProperties("spring.oracle-datasource")
  6. public DataSource oracleDataSource(){
  7. return DataSourceBuilder.create().build();
  8. }
  9. @Bean(name = "oracleSqlSessionFactory")
  10. public SqlSessionFactory sqlSessionFactory(@Qualifier("oracleDataSource") DataSource dataSource) throws Exception {
  11. SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
  12. sessionFactoryBean.setDataSource(dataSource);
  13. sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
  14. .getResources("classpath*:mapper/oracle/*.xml"));
  15. return sessionFactoryBean.getObject();
  16. }
  17. @Bean(name = "oracleTransactionManager")
  18. public DataSourceTransactionManager oracleTransactionManager(){
  19. return new DataSourceTransactionManager(oracleDataSource());
  20. }
  21. }

接下來(lái)所有的接口都應(yīng)該按照不同的數(shù)據(jù)源放置,對(duì)應(yīng)的xml也需要按照不同的數(shù)據(jù)源分開(kāi)。

按照我項(xiàng)目的實(shí)際例子:

Mapper(使用local數(shù)據(jù)源,下面所有的方法都會(huì)在local數(shù)據(jù)源中查詢)

  1. import cn.javabb.bootdemo.entity.*;
  2. import org.apache.ibatis.annotations.Mapper;
  3. import org.springframework.dao.DataAccessException;
  4. import org.springframework.stereotype.Component;
  5. /**
  6. * @Author QINB imqinbao@163.com
  7. * @CreateDate 2019/1/18/018 13:08
  8. * @Since V1.0
  9. */
  10. @Component
  11. @Mapper
  12. public interface StLocalMapper {
  13. int insertPptnOne(StPptn pptn);
  14. int insertRiverOne(StRiver river);
  15. int insertRsvrOne(StRsvr rsvr);
  16. }

StLocalMapper

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "http:///dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="cn.javabb.bootdemo.mapper.local.StLocalMapper">
  4. <insert id="insertBatch" parameterType="java.util.List">
  5. insert into ST_PPTN_R_copy1(stcd,tm,drp,intv,pdr,dyp,wth,tmdown)
  6. values
  7. <foreach collection="list" item="item" index="index" separator=",">
  8. (#{item.stcd},#{item.tm},#{item.drp},#{item.intv},#{item.pdr},#{item.dyp},#{item.wth},#{item.tmdown})
  9. </foreach>
  10. </insert>
  11. <insert id="insertPptnOne" parameterType="cn.javabb.bootdemo.entity.StPptn">
  12. insert into ST_pptn_R(stcd,tm,drp,intv,pdr,dyp,wth,tmdown)
  13. values (#{stcd},#{tm},#{drp},#{intv},#{pdr},#{dyp},#{wth},#{tmdown})
  14. </insert>
  15. <insert id="insertRiverOne" parameterType="cn.javabb.bootdemo.entity.StRiver">
  16. insert into ST_river_R(STCD,TM,Z,Q,XSA,XSAVV,XSMXV,FLWCHRCD,WPTN,MSQMT,MSAMT,MSVMT,TMDOWN)
  17. values (#{STCD},#{TM},#{Z},#{Q},#{XSA},#{XSAVV},#{XSMXV},#{FLWCHRCD},#{WPTN},#{MSQMT},#{MSAMT},#{MSVMT},#{TMDOWN})
  18. </insert>
  19. <insert id="insertRsvrOne" parameterType="cn.javabb.bootdemo.entity.StRsvr">
  20. insert into ST_rsvr_R(STCD,TM,RZ,INQ,W,BLRZ,OTQ,RWCHRCD,RWPTN,INQDR,MSQMT,TMDOWN)
  21. values (#{STCD},#{TM},#{RZ},#{INQ},#{W},#{BLRZ},#{OTQ},#{RWCHRCD},#{RWPTN},#{INQDR},#{MSQMT},#{TMDOWN})
  22. </insert>
  23. </mapper>

編寫一個(gè)service調(diào)用方法就行了

  1. @Slf4j
  2. @Service
  3. public class StDataSynService {
  4. @Autowired
  5. StLocalMapper stLocalMapper;
  6. @Async
  7. public void pptnSyn(){
  8. String nowDate = DateFormatUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss");
  9. String yesterDay = DateFormatUtils.format(DateUtils.addDays(new Date(),-day),"yyyy-MM-dd HH:mm:ss");
  10. log.info("[{}]掃描Pptn同步數(shù)據(jù)....",nowDate);
  11. //需要同步的數(shù)據(jù),往前推一個(gè)小時(shí)
  12. List<StPptn> remoteList = stRemoteMapper.listPptnRemote(nowDate,yesterDay);
  13. int total = 0;
  14. if(null!=remoteList && remoteList.size()>0){
  15. total = remoteList.size();
  16. log.info("獲取Pptn數(shù)據(jù):{}條。",total);
  17. Long startTM = System.currentTimeMillis();
  18. //執(zhí)行同步
  19. int n=0;
  20. for(StPptn pptn:remoteList){
  21. n += stLocalMapper.insertPptnOne(pptn);
  22. }
  23. if(n>0){
  24. if(n == total){
  25. log.info("Pptn同步成功.用時(shí):{}秒,需要同步記錄:{},成功:{}",(System.currentTimeMillis()-startTM)/1000,total,n);
  26. }else{
  27. log.info("Pptn同步成功.用時(shí):{}秒,需要同步記錄:{},成功:{},失敗:{}",(System.currentTimeMillis()-startTM)/1000,total,n,(total-n));
  28. }
  29. }
  30. }else{
  31. log.info("Pptn無(wú)數(shù)據(jù)同步");
  32. }
  33. }
  34. }

@Async:表示這個(gè)方法是異步執(zhí)行,可以去掉,自己去調(diào)用service這個(gè)方法就行了。

上面的例子中我并沒(méi)有用到通用Mapper,其實(shí)調(diào)用通用Mapper的方法會(huì)更簡(jiǎn)單一點(diǎn)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多