springboot整合多数据源

最近同事有个小项目让我写写,其实刚开始的时候,我是拒绝的,因为总不能说,你让我写我就写吧。而且这个事情还得java写。好吧,关注springboot已经很久很久了,光说不练嘴把式。据说springboot是一个相当简单,相当容易框架,把java多年来一直饱受诟病的多配置文件这个优点给升华了。一直没实践过,于是乎这就是一个的机会。

项目内容其实很简单就是从三个数据库取数据,整合后写入一个第三方接口。从三个数据库读取数据,自然是先定义三个数据源,不多说,贴代码。

读配置文件 DataSourceConfig.java 

package net.springboot.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
 
import javax.sql.DataSource;
 
@Configuration
public class DataSourceConfig {
 
    //spring.datasource.primary 
    //配置文件 application.properties 中的项对应即可,

    @Bean(name = "primaryDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
    	return DataSourceBuilder.create().build();
    }
 
    //类似于primaryDataSource
    @Bean(name = "secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource secondaryDataSource() {
    	return DataSourceBuilder.create().build();
    }
    
    //类似于primaryDataSource
    @Bean(name = "thirdDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.third")
    public DataSource thirdDataSource() {
    	try
    	{
    		return DataSourceBuilder.create().build();
    	}
    	catch(Exception e)
    	{
    		return null;
    	}
    }
}

PrimaryConfig.java

package net.springboot.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
 
@Configuration
//开启事务管理
@EnableTransactionManagement
@EnableJpaRepositories(
		//在这个JpaRepositories中用到的事务管理器,这里是Ref,即引用
		transactionManagerRef = "PrimaryTransactionManager",
		//实体类工厂
        entityManagerFactoryRef = "PrimaryEntityManagerFactory",
        //JpaRepositories所在的包名,这也是为什么我们要细分包名的原因
        basePackages = {"net.springboot.repository.sqlserver"}) //设置Repository所在位置
public class PrimaryConfig {
 
    //这个与 DataSourceConfig.java 中定义的类型匹配上,简单看看估计就明白了
    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;
 
    @Autowired
    private JpaProperties jpaProperties;
 
    //配置实体类工厂
    @Bean(name = "PrimaryEntityManagerFactory")
    //在数据源的配置中,我们将Local配置成了主库,所以必须在这里有@Primary注解
    @Primary
    public LocalContainerEntityManagerFactoryBean PrimaryEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        //创建一个工厂
        return builder
                .dataSource(primaryDataSource)        //数据源实例,在这里指的就是localDatasource这个实例
                .properties(jpaProperties.getProperties()) //加Jpa的属性配置加入进来
                .packages("net.springboot.entity.sqlserver") //实体类包名
                //.persistenceUnit("localPersistenceUnit") 
                .build();
    }
    
    @Bean(name = "PrimaryTransactionManager")
    //和上面一样,必须要有该注解
    @Primary
    public PlatformTransactionManager PrimaryTransactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(PrimaryEntityManagerFactory(builder).getObject());
    }
}

SecondaryConfig.java,ThirdConfig.java 其实差不多的,这里就不贴了,注意两个地方就行

basePackages = {"net.springboot.repository.sqlserver"}) //设置Repository的包,就是所在位置位置

packages("net.springboot.entity.sqlserver") //设置实体的包

 

package net.springboot.entity.sqlserver;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "t_realtime_data")
public class User
{
	@Id 
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="ID")
	private String id;
	
	@Column(name="CODE")
	private String code;
	
	@Column(name="BRUSHCARDTIME")
	private Date brushcardtime;
	
	@Column(name="AREANO")
	private String areano;
	
	@Column(name="CATE")
	private Integer cate;
	
	public User()
	{
	}

	public String getId()
	{
		return id;
	}

	public void setId(String id)
	{
		this.id = id;
	}

	public String getCode()
	{
		return code;
	}

	public void setCode(String code)
	{
		this.code = code;
	}
	
	public Date getBrushcardtime()
	{
		return brushcardtime;
	}

	public void setBrushcardtime(Date brushcardtime)
	{
		this.brushcardtime = brushcardtime;
	}

	public String getAreano()
	{
		return areano;
	}

	public void setAreano(String areano)
	{
		this.areano = areano;
	}
	
	public Integer getCate()
	{
		return cate;
	}

	public void setCate(Integer cate)
	{
		this.cate = cate;
	}
}

贴一个 sqlserver 实体类的代码,至于mysql和postsql的实体类差不多的,就没必要贴,相信大家都会写

package net.springboot.repository.sqlserver;

import org.springframework.data.jpa.repository.JpaRepository;
import net.springboot.entity.sqlserver.User;

public interface UserRepository extends JpaRepository<User, String>
{
	
	User findByCode(String code);

}

贴一下sqlserver的Repository的类,这个相当于hibernate框架的dao类型,有了JPA你就开始腰不酸,腿不痛了,这个东西看上去是个接口,也确实是个接口,但是只用自己写方法,jpa会帮你具体实现,是不是有点高大上啊。

大概是实现方法如下:

    @Query(value = "select * from v_device", nativeQuery = true)
    List<DeviceData> findmydata();

说白了,就是自己写个sql语句查询,当然这个也可以搞个以前hibernate所支持HQL语句,这个有心人自己去实践吧。

然后三个数据库的数据查询出来,剩下的事情就是整合到一起

package net.springboot.service;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import net.springboot.comm.DateTimeUtile;
import net.springboot.comm.LogHelper;
import net.springboot.comm.StringUtil;
import net.springboot.entity.mysql.MyRealData;
import net.springboot.entity.postsql.vRecordData;
import net.springboot.entity.sqlserver.RealData;
import net.springboot.repository.mysql.MyRealDataRepository;
import net.springboot.repository.postsql.RecordDataRepository;
import net.springboot.repository.sqlserver.RealdataRepository;

@Component
public class ScheduledService {
	
	 private final static Logger logger = LoggerFactory.getLogger(ScheduledService.class);
	
	@Autowired
	MysqlRepository mysqlRepository; //这个类得自己写哦,参考sqlserver
	
	@Autowired
	PostsqlRepository postsqlRepository; //这个类得自己写哦 参考sqlserver
	
	@Autowired
	UserRepository userRepository //sqlserverRepository;
	
  
    //定时任务,这个可以自己改
   //这个表示延迟1000毫秒后执行,任务执行完6000毫秒之后执
     @Scheduled(initialDelay=1000, fixedDelay = 6000) 
    public void scheduled2() {
    	
    	GatherSqlserverData(); 
    	
        //GathermysqlData
        
        //GatherpostsqlData
       	
        //调第三方接口,这个不写了  todo...

    	logger.info("GatherData success");
    	
    }
    
    
    private void GatherSqlserverData() 
    {
    	try 
    	{
    		List<RealData> list = this.realdataRepo.findAll();
    		//to do anything 
    	}
    	catch(Exception e)
    	{
    		LogHelper.log("TranData fail" + e.getMessage());
    	}
    }    
}

    最后是启动代码,springboot基本上都是这个样子,没啥特别的。

package net.springboot;

import java.util.Collections;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;

//webapp访问路径,可以自己定义
//MyDataWebApp 这个类名是自己定义,随便改

@EnableScheduling
@SpringBootApplication
public class MyDataWebApp {

	public static void main(String[] args) {
		SpringApplication app = new SpringApplication(MyDataWebApp .class);
		app.setDefaultProperties(Collections.singletonMap("server.servlet.context-path", "/webapp"));

		app.run(args);
	}
}

pom文件的的主要部分,剩下自己想要啥再加点啥

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

        <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
			<exclusions>
      			<exclusion>
         			<groupId>org.springframework.boot</groupId>
         			<artifactId>spring-boot-starter-logging</artifactId>
      			</exclusion>
   			</exclusions>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		
		<dependency>
			<groupId>com.microsoft.sqlserver</groupId>
			<artifactId>mssql-jdbc</artifactId>
			<scope>runtime</scope>
		</dependency>
		
		
		<dependency>
    		<groupId>org.postgresql</groupId>
    		<artifactId>postgresql</artifactId>
    		<scope>runtime</scope>
		</dependency>
		
		<dependency>
    		<groupId>mysql</groupId>
    		<artifactId>mysql-connector-java</artifactId>
    		<scope>runtime</scope>
		</dependency>

resources 下的配置文件 application.properties大概如下,配置三个数据库是一件麻烦事情,这个想实践就得不怕麻烦,还有数据库连接属性种方言与数据库版本有关系哦

#由DataSourceConfig.java 来解析,具体怎么解析,怎么实现,可以看看springboot源码

#sqlserver
spring.datasource.primary.jdbc-url=jdbc:sqlserver://127.0.0.1:1433;database=test
spring.datasource.primary.username=sa
spring.datasource.primary.password=sa
spring.datasource.primary.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.properties.hibernate.primary.dialect=org.hibernate.dialect.SQLServer2008Dialect

#postsql
spring.datasource.secondary.jdbc-url=jdbc:postgresql://127.0.0.1:5432/test
spring.datasource.secondary.username=postgres
spring.datasource.secondary.password=postgres
spring.datasource.secondary.driverClassName=org.postgresql.Driver
spring.jpa.properties.hibernate.secondary.dialect=org.hibernate.dialect.PostgreSQLDialect

#mysql
spring.datasource.third.jdbc-url=jdbc:mysql://127.0.0.1:3306/rlsb-sys?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.third.username=root
spring.datasource.third.password=root
spring.datasource.third.driverClassName=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.third.dialect=org.hibernate.dialect.MySQL57Dialect

 

到这里基本上就结束了,这个其实还算简单,mysql,postsql的Repository类和实体类这里就不写,其实都差不多的。感觉很简单吧,其实是很多很多事情框架帮我们做了。

说明一下,很多很多事情多个数据源种如果其中一个无法连接,系统以jar方式运行的时候,建立连接池时会抛错哦。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值