1. 程式人生 > >如何使用多數據源,同時使用jpa和jdbctemplate

如何使用多數據源,同時使用jpa和jdbctemplate

bsp nta utf8 npr gis 控制臺管理 iba ogg 需要

技術分享圖片
spring:
 datasource:
    first:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://xx.xx.xx.xx:xx/xx?characterEncoding=utf8
    driver-class-name: com.mysql.jdbc.Driver
    username: xx
    password: xx
    #配置監控統計攔截的filters,去掉監控界面sql將無法統計,wall用於防火墻
    filters: stat,wall,log4j
    #最大活躍數
    maxActive: 
20 #初始化連接數 initialSize: 1 #最大連接等待超過時間 maxWait: 60000 #打開PSCache,並且指定每個連接PSCache的大小 poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 #通過connectionProperties屬性來打開mergeSql功能;慢SQL記錄 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
minIdle: 1 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: select 1 from dual testWhileIdle: true testOnBorrow: false testOnReturn: false sec: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://xx.xx.xx.xx:3306/xx?characterEncoding=utf8
driver-class-name: com.mysql.jdbc.Driver username: xx password: xx #配置監控統計攔截的filters,去掉監控界面sql將無法統計,wall用於防火墻 filters: stat,wall,log4j #最大活躍數 maxActive: 20 #初始化連接數 initialSize: 1 #最大連接等待超過時間 maxWait: 60000 #打開PSCache,並且指定每個連接PSCache的大小 poolPreparedStatements: true maxPoolPreparedStatementPerConnectionSize: 20 #通過connectionProperties屬性來打開mergeSql功能;慢SQL記錄 connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 minIdle: 1 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: select 1 from dual testWhileIdle: true testOnBorrow: false testOnReturn: false
配置文件

技術分享圖片
@ServletComponentScan
@Configuration
public class DatasourceConfiguration {

    private Logger logger = LoggerFactory.getLogger(DatasourceConfiguration.class);

    @Value("${spring.datasource.first.url}")
    private String firstdevUrl;
    @Value("${spring.datasource.first.username}")
    private String firstUsername;
    @Value("${spring.datasource.first.password}")
    private String firstPassword;

    @Value("${spring.datasource.sec.url}")
    private String secUrl;
    @Value("${spring.datasource.sec.username}")
    private String secUsername;
    @Value("${spring.datasource.sec.password}")
    private String secPassword;



    @Value("com.mysql.jdbc.Driver")
    private String driverClassName;

    @Value("5")
    private int initialSize;

    @Value("5")
    private int minIdle;

    @Value("20")
    private int maxActive;

    @Value("60000")
    private int maxWait;

    /**
     * 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒
     */
    @Value("60000")
    private int timeBetweenEvictionRunsMillis;
    /**
     * 配置一個連接在池中最小生存的時間,單位是毫秒
     */
    @Value("300000")
    private int minEvictableIdleTimeMillis;

    @Value("SELECT 1 FROM DUAL")
    private String validationQuery;

    @Value("true")
    private boolean testWhileIdle;

    @Value("false")
    private boolean testOnBorrow;

    @Value("false")
    private boolean testOnReturn;

    /**
     * 打開PSCache,並且指定每個連接上PSCache的大小
     */
    @Value("true")
    private boolean poolPreparedStatements;

    @Value("20")
    private int maxPoolPreparedStatementPerConnectionSize;
    /**
     * 配置監控統計攔截的filters,去掉後監控界面sql無法統計,‘wall‘用於防火墻
     */
    @Value("stat,wall,log4j")
    private String filters;
    /**
     * 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
     */
    @Value("druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500")
    private String connectionProperties;


    @Bean(name = "secDatasource")
    @Qualifier("secDatasource")
    @ConfigurationProperties(prefix = "spring.datasource.sec")
    public DataSource secDataSource() {
        return getDruidDataSource(secUsername, secPassword, secUrl);
    }

    
    @Bean(name = "firstDatasource")
    @Qualifier("firstDatasource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.first")
    public DataSource firstDataSource() {
        return getDruidDataSource(firstUsername, firstPassword, firstUrl);
    }

   

    private DruidDataSource getDruidDataSource(String username, String password, String url) {
        DruidDataSource datasource = new DruidDataSource();

        datasource.setUrl(url);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);

        //configuration
        datasource.setInitialSize(initialSize);
        datasource.setMinIdle(minIdle);
        datasource.setMaxActive(maxActive);
        datasource.setMaxWait(maxWait);
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setValidationQuery(validationQuery);
        datasource.setTestWhileIdle(testWhileIdle);
        datasource.setTestOnBorrow(testOnBorrow);
        datasource.setTestOnReturn(testOnReturn);
        datasource.setPoolPreparedStatements(poolPreparedStatements);
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
        try {
            datasource.setFilters(filters);
        } catch (SQLException e) {
            logger.error("druid configuration initialization filter : {0}", e);
        }
        datasource.setConnectionProperties(connectionProperties);
        return datasource;
    }

}
配置數據源 技術分享圖片
package com.ipinyou.mip.configuration;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;


/**
 * 這樣的方式不需要添加註解:@ServletComponentScan
 * Created by Administrator on 2018/2/28.
 */
@Configuration
public class DruidConfiguration {

    @Bean
    public ServletRegistrationBean statViewServlet(){
        //創建Servlet,註冊實體
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
        //設置ip白名單
        servletRegistrationBean.addInitParameter("allow","xx.xx.xx.xx");
        //設置ip黑名單,如果deny和allow共同存在時,deny優先於allow
        servletRegistrationBean.addInitParameter("deny","xx.xx.xx.xx");
        //設置控制臺管理用戶
        servletRegistrationBean.addInitParameter("loginUsername","xxx");
        servletRegistrationBean.addInitParameter("loginPassword","xxx");
        //是否可以重置數據
        servletRegistrationBean.addInitParameter("resetEnable","false");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean statFilter(){
        //創建過濾器
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        //設置過濾器過濾路徑
        filterRegistrationBean.addUrlPatterns("/*");
        //忽略過濾形式
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}
設置數據源的過濾器 技術分享圖片
package com.ipinyou.mip.configuration;

import java.util.Map;

import javax.persistence.EntityManager;
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.HibernateSettings;
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(entityManagerFactoryRef = "entityManagerFactoryPrimary",
        transactionManagerRef = "transactionManagerPrimary",
        basePackages = {"xx.xx.xxx","xx.xx.xx"})//設置dao(repo)所在位置
public class JpaConfiguration {

    @Autowired
    @Qualifier("firstDatasource")
    private DataSource firstDataSource;
    
    @Primary
    @Bean(name = "entityManagerFirst")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
    }

    @Autowired
    private JpaProperties jpaProperties;

    private Map<String, Object> getVendorProperties() {
        return jpaProperties.getHibernateProperties(new HibernateSettings());
    }

    /**
     * 設置實體類所在位置
     */
    @Primary
    @Bean(name = "entityManagerFactoryPrimary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(mipdevDataSource)
                .packages("xx.xx.xx.xx")
                .properties(getVendorProperties())
                .persistenceUnit("firstManageFactory")
                .properties(getVendorProperties())
                .build();
    }

    @Primary
    @Bean(name = "transactionManagerPrimary")
    public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }
}
firstJpaConfiguration 技術分享圖片
package com.ipinyou.mip.configuration;

import java.util.Map;

import javax.persistence.EntityManager;
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.HibernateSettings;
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.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(entityManagerFactoryRef = "entityManagerFactorySec",
        transactionManagerRef = "transactionManagerSec",
        basePackages = {"xx.xx.xx"})//設置dao(repo)所在位置
public class JpaSecConfiguration {

    @Autowired
    @Qualifier("secDatasource")
    private DataSource secDatasource;
    
    @Bean(name = "entityManagerAmp")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryAmp(builder).getObject().createEntityManager();
    }

    @Autowired
    private JpaProperties jpaProperties;

    private Map<String, Object> getVendorProperties() {
        return jpaProperties.getHibernateProperties(new HibernateSettings());
    }

    /**
     * 設置實體類所在位置
     */
    @Bean(name = "entityManagerFactorySec")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryAmp(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(secDatasource)
                .packages("xx.xx.xx")
                .properties(getVendorProperties())
                .persistenceUnit("secManageFactory")
                .properties(getVendorProperties())
                .build();
    }

    @Bean(name = "transactionManagerSec")
    public PlatformTransactionManager transactionManagerAmp(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactorySec(builder).getObject());
    }
}
secJpaConfiguration 技術分享圖片
package com.ipinyou.mip.configuration;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;

@Configuration
@Import(DatasourceConfiguration.class)
public class JdbcTemplateConfiguration {
    @Bean(name = "secJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate(
            @Qualifier("secDatasource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }


    @Bean(name = "firstJdbcTemplate")
    public JdbcTemplate threeJdbcTemplate(
            @Qualifier("firstDatasource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}
JdbcTemplateConfiguration 技術分享圖片
/**
 * 提供了一系列數據庫查詢方法
 *
 * @author guodong.zhang
 */
public class CommonDao<E, PK extends Serializable> {

    @PersistenceContext(unitName = "secManageFactory")
    protected EntityManager em;
   /**
     * 相當於jdbctemplate的queryForlist 返回List<Map<String, Object>>
     *
     * @param sql
     * @return
     */
    public List<Map<String, Object>> queryForList(String sql) {
        Query nativeQuery = em.createNativeQuery(sql);
        nativeQuery.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<Map<String,Object>> resultList = nativeQuery.getResultList();
        return resultList;
    }
}
具體使用

如何使用多數據源,同時使用jpa和jdbctemplate