`
征途2010
  • 浏览: 248084 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

基于druid和spring的动态数据库以及读写分离

阅读更多

spring与druid可以实现动态数据源,夸库查询,读写分离等功能。现在说一下配置:

1、需要配置多个spring数据源

spring-data.xml

<!-- 动态数据源 -->
	<bean id="dynamicDataSource" class="com.myproject.common.db.util.DynamicDataSource">
		<!-- 通过key-value关联数据源 -->
		<property name="targetDataSources">
			<map>
				<entry value-ref="dataSourceWrite" key="dataSourceWrite"></entry>
				<entry value-ref="dataSourceRead" key="dataSourceRead"></entry>
			</map>
		</property>
		<property name="defaultTargetDataSource" ref="dataSourceWrite" />
	</bean>

	<!--mybatis与Spring整合 -->
	<bean id="sqlSessionFactory" name="sqlSessionFactory"
		class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="configLocation" value="classpath:mybatis.xml"></property>
		<property name="mapperLocations" value="classpath*:mapper/*.xml" />
		<property name="dataSource" ref="dynamicDataSource" />
	</bean>

	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg index="0" ref="sqlSessionFactory" />
	</bean>
	
	
	<bean id="transactionManager"  
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dynamicDataSource" />  
    </bean>  
    
    <tx:annotation-driven transaction-manager="transactionManager" /> 

	<!-- 数据源(DruidDataSource) -->
	<bean id="dataSourceWrite" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<property name="url" value="${urlOracle}" />
		<property name="username" value="${usernameOracle}" />
		<property name="password" value="${passwordOracle}" />
		<!-- 初始化连接大小 -->
		<property name="initialSize" value="5" />
		<!-- 连接池最大使用连接数量 -->
		<property name="maxActive" value="200" />
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="5" />
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="60000" />
		<!-- <property name="poolPreparedStatements" value="true" /> <property 
			name="maxPoolPreparedStatementPerConnectionSize" value="33" /> -->
		<!-- <property name="validationQuery" value="${jdbc.validationQuery}" /> -->
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
		<property name="testWhileIdle" value="true" />
		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="25200000" />
		<!-- 打开removeAbandoned功能 -->
		<property name="removeAbandoned" value="true" />
		<!-- 1800秒,也就是30分钟 -->
		<property name="removeAbandonedTimeout" value="1800" />
		<!-- 关闭abanded连接时输出错误日志 -->
		<property name="logAbandoned" value="true" />
		<!-- 监控数据库 -->
		<!-- <property name="filters" value="mergeStat" /> -->
		<property name="filters" value="stat" />
		<property name="defaultAutoCommit" value="true" />
	</bean>
	
	<bean id="dataSourceRead" class="com.alibaba.druid.pool.DruidDataSource"
		init-method="init" destroy-method="close">
		<property name="url" value="${urlMysql}" />
		<property name="username" value="${usernameMysql}" />
		<property name="password" value="${passwordMysql}" />
		<!-- 初始化连接大小 -->
		<property name="initialSize" value="5" />
		<!-- 连接池最大使用连接数量 -->
		<property name="maxActive" value="200" />
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="5" />
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="60000" />
		<!-- <property name="poolPreparedStatements" value="true" /> <property 
			name="maxPoolPreparedStatementPerConnectionSize" value="33" /> -->
		<!-- <property name="validationQuery" value="${jdbc.validationQuery}" /> -->
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
		<property name="testWhileIdle" value="true" />
		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="25200000" />
		<!-- 打开removeAbandoned功能 -->
		<property name="removeAbandoned" value="true" />
		<!-- 1800秒,也就是30分钟 -->
		<property name="removeAbandonedTimeout" value="1800" />
		<!-- 关闭abanded连接时输出错误日志 -->
		<property name="logAbandoned" value="true" />
		<!-- 监控数据库 -->
		<!-- <property name="filters" value="mergeStat" /> -->
		<property name="filters" value="stat" />
		<property name="defaultAutoCommit" value="true" />
	</bean>

 2、需要写一个DynamicDataSource类继承AbstractRoutingDataSource,并实现determineCurrentLookupKey方法

 

 

public class DynamicDataSource extends AbstractRoutingDataSource {  
	  
    
    /** 
     *  
     * override determineCurrentLookupKey 
     * <p> 
     * Title: determineCurrentLookupKey 
     * </p> 
     * <p> 
     * Description: 自动查找datasource 
     * </p> 
     *  
     * @return 
     */  
    @Override  
    protected Object determineCurrentLookupKey() {  
        return DBContextHolder.getDSType();  
    }  
  
}  

 

 

3、参考spring事务管理,使用线程变量来切换数据源

 

public class DBContextHolder {

	/**
	 * 线程threadlocal
	 */
	private static ThreadLocal<String> contextHolder = new ThreadLocal<>();
	private static Logger logger = LoggerFactory
			.getLogger(DBContextHolder.class);

	public static String getDSType() {
		try {

		} catch (Exception e) {
			e.printStackTrace();
			logger.error("get DBTYPE faild with error:[" + e.getMessage() + "]");
		}

		String db = contextHolder.get();
		 if (db == null) {
		 db =UrlConnect.getKey(ConfigHelper.getToWriteKey());// 默认是读写库
		 }
		return db;
	}

	/**
	 * 
	 * 设置本线程的dbtype
	 * 
	 * @param str
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	public static boolean setDSType(String str) {
		try {
			clearDBType();
			if (str != null&&!str.equals("")) {
				contextHolder.set(str);
				logger.info("change thread[" + str + "] success!");
				return true;
			} else {
				logger.info("change thread[" + str + "] faild!");
				return false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("change thread[" + str + "] faild!");
			return false;
		}
	}

	/**
	 * clearDBType
	 * 
	 * @Title: clearDBType
	 * @Description: 清理连接类型
	 */
	public static void clearDSType() {
		contextHolder.remove();
	}
}

 

 

4、在dao中切换数据源

@Repository
public class BaseDAO extends SqlSessionDaoSupport {
       @Resource
	private SqlSessionTemplate sqlSessionTemplate;
@Resource
	public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
		super.setSqlSessionTemplate(sqlSessionTemplate);
	}

public  <T> PageList<T> selectPublicListPage(String countSqlID,String sqlID,
			PageList<T> page, Object obj) {
		DBContextHolder.setDbType("dataSourceRead");
		//查询总数
		Integer total = this.getSqlSession().selectOne(countSqlID, obj);
		RowBounds rowBounds=new RowBounds(page.getFirstResult(),page.getPageSize());
		// 查询列表信息
		List<T> list = this.getSqlSession().selectList(
				sqlID, obj,rowBounds);
		page.setTotalRecord(total!=null?total:0);
		page.setDataSource(list);
		page.setTotalPage((total + page.getPageSize() - 1)
				/ page.getPageSize());
		return page;
	}

	public int insert(String sqlID, Object paramObj) {
		DBContextHolder.setDbType("dataSourceWrite");
		return this.getSqlSession().insert(sqlID, paramObj);
	}


}

 

 

 

 

 

分享到:
评论

相关推荐

    springboot+mybatis+druid+redis实现数据库读写分离和缓存

    在现代Web应用开发中,数据库读写分离和缓存技术是提高系统性能和可扩展性的关键策略。本项目采用SpringBoot、MyBatis、Druid和Redis这四个核心技术来实现这一目标。以下将详细讲解这些组件如何协同工作,以及它们...

    Mybatis读写分离 mysql数据库 Druid连接池

    数据库是mysql,采用druid连接池。 读写分离采用插件的形式实现的,优点是不需要写源注解,不需要写分开的Mapper.xml。 如果只有主库的话,那么会创建两个地址相同的连接池,写主库,读从库。 注意:没有使用Spring...

    Mysql主从集群搭建方法,以及基于spring boot注解式数据库读写分离代码示例.zip

    Spring Boot是流行的Java开发框架,提供了便捷的方式来配置和使用数据库,包括实现数据库读写分离。 1. **MySQL主从复制原理**: 主从复制的核心是binlog(二进制日志),主节点的所有更改操作都会记录在binlog中...

    数据库读写分离demo

    数据库读写分离是一种常见的优化策略,它通过将数据的读取操作和写入操作分散到不同的数据库服务器上,以提高系统的并发处理能力和响应速度。在大型应用系统中,由于读操作通常远多于写操作,读写分离可以显著降低主...

    springboot+mybatis+mysql实现读写分离.zip

    springboot+mybatis+mysql实现读写...先在建好mysql主从数据库的配置,然后在代码中根据读写分离或强制读取master数据库中的数据 mysql数据库设置主从,参考: https://my.oschina.net/zhangmaoyuan/blog/3120556

    SpringBoot集成Spring Data JPA及读写分离

    SpringBoot集成Spring Data JPA及读写分离是现代Java Web应用程序中常见的技术组合,用于高效地管理和处理数据库操作。Spring Boot简化了应用的初始化和配置,而Spring Data JPA则进一步降低了使用Java Persistence ...

    源码主要用于学习通过SpringBoot结合AOP简单实现数据库读写分离,数据源使用Alibaba Druid,数据.zip

    在本项目中,我们主要探讨如何使用SpringBoot与AOP(面向切面编程)来实现一个简单的数据库读写分离方案,同时利用阿里巴巴的Druid数据源。数据库读写分离是提高系统性能和可扩展性的重要手段,它将读操作和写操作...

    数据库读写分离(aop方式完整实现)

    最近项目要支持读写分离, 网上找了很多,但都是不太完整,我自己整理了下供大家参考。 我的项目使用的框架: springMvc+spring+hibernate+springJPA+maven, 数据库连接池用阿里的druid。

    Sharding-JDBC教程:Spring Boot整合Sharding-JDBC实现分库分表+读写分离.docx

    Sharding-JDBC可以与Spring Boot进行整合,以实现数据库分库分表和读写分离。 四、Sharding-JDBC的配置 Sharding-JDBC的配置主要通过.properties文件或.yaml文件实现。在.properties文件中,我们可以设置数据库的...

    springmvc-mybatis 整合druid多数据源配置读写实现读写分离,windows上mysql主从复制

    通过上述步骤,我们可以实现基于SpringMVC、MyBatis和Druid的读写分离,以及Windows上的MySQL主从复制。这将大大提高系统的可伸缩性和可用性,降低单点故障的风险。在实际项目中,还可以根据业务需求进一步优化,...

    springboot+mybatis-plus+shardingsphere 实现读写分离

    本项目以"springboot+mybatis-plus+shardingsphere 实现读写分离"为主题,结合了Spring Boot的快速开发能力、MyBatis-Plus的简化数据操作以及ShardingSphere的分布式数据库解决方案,旨在提高系统的读取性能和可扩展...

    50-Spring Boot读写分离1

    总的来说,Spring Boot的读写分离配置涉及到数据源配置、动态切换、事务管理和中间件的配合。通过这样的设计,我们可以充分利用数据库的读写分离特性,提高系统的读取性能,同时保证数据的一致性。在实际开发中,...

    Spring配置动态数据源实现读写分离的方法

    在Spring框架中,实现数据库的读写分离是提高系统性能的一种常见策略,它可以将读操作和写操作分散到不同的数据源上,减轻主数据库的压力。本文将详细介绍如何利用Spring配置动态数据源来实现这一功能。 首先,我们...

    SpringMVC + 德鲁伊+mybatis +mysql 读写分离

    SpringMVC、德鲁伊(Druid)、MyBatis 和 MySQL 是四个在Java Web开发中常用的组件,它们各自承担着不同的职责,而将它们结合在一起则可以构建出一个高效、可扩展的数据库读写分离解决方案。 SpringMVC是Spring框架...

    Sharding-JDBC教程:Spring Boot整合Sharding-JDBC实现读写分离.docx

    在实际项目中,为了提高系统的稳定性和处理能力,我们常常需要对数据库进行读写分离和分片处理。通过 Spring Boot 和 Sharding-JDBC 的结合,可以轻松地实现这些需求。 ##### 1. Maven 配置 首先,在项目的 `pom....

    springboot+druid+mybatis多数据源动态切换案例

    当这些技术结合在一起处理多数据源和动态切换时,可以实现读写分离,提高系统的性能和稳定性。 本案例中,"springboot+druid+mybatis多数据源动态切换"主要涉及以下几个核心知识点: 1. **SpringBoot多数据源配置*...

    Spring+MyBatis实现数据库读写分离方案

    通过以上步骤,我们可以实现Spring+MyBatis的数据库读写分离方案,有效地提升系统性能和可用性,但同时也需要注意其维护成本和扩展性问题。在实际项目中,需要根据业务需求和资源情况进行权衡选择。

    基于mybatis,springboot开箱即用的读写分离插件.zip

    总之,这个项目为开发者提供了一个实践数据库读写分离的模板,通过学习和使用,可以加深对Spring Boot和MyBatis整合、数据库连接池、事务管理、读写策略以及分布式系统设计的理解。对于正在寻找毕业设计项目的同学来...

    springboot+mybatis的读写分离

    在IT行业中,数据库读写分离是一种常见的优化策略,它能够有效地提高系统的并发处理能力和数据安全性。本示例将深入探讨如何结合SpringBoot、MyBatis和Druid连接池实现这一功能。 首先,SpringBoot以其简洁的配置和...

    springboot+dubbo分布式架构,提供分布式缓存、分布式锁、分布式Session、读写分离

    aop切换数据库实现读写分离。Transtraction注解事务。 MVC: 基于spring mvc注解,Rest风格Controller。Exception统一管理。 缓存和Session:注解redis缓存数据,Spring-session和redis实现分布式session同步,重启...

Global site tag (gtag.js) - Google Analytics