java dbtype_Java实现数据库的读写分离
引言
1、讀寫分離:可以通過Spring提供的AbstractRoutingDataSource類,重寫determineCurrentLookupKey方法,實現動態切換數據源的功能;讀寫分離可以有效減輕寫庫的壓力,又可以把查詢數據的請求分發到不同讀庫;
2、寫數據庫:當調用insert、update、delete及一些實時數據用到的庫;
3、讀數據庫:當調用select查詢數據用到的庫;
4、JaveWeb工程通過AbstractRoutingDataSource類實現讀寫分離;
一、jdbc.properties文件配置讀寫數據源
datasource.type=mysql
datasource.driverClassName=com.mysql.jdbc.Driver
datasource.username=root
#寫庫w.datasource.url=jdbc\:mysql\://127.0.0.1\:3306/ddt?characterEncoding\=utf-8w.datasource.password=write123
#讀庫r.datasource.url=jdbc\:mysql\://IP\:3306/ddt?characterEncoding\=utf-8r.datasource.password=read123
#連接池配置
c3p0.acquireIncrement=3
c3p0.acquireRetryAttempts=10
c3p0.acquireRetryDelay=1000
c3p0.initialPoolSize=20
c3p0.idleConnectionTestPeriod=3600
c3p0.testConnectionOnCheckout=true
c3p0.minPoolSize=10
c3p0.maxPoolSize=80
c3p0.maxStatements=100
c3p0.numHelperThreads=10
c3p0.maxIdleTime=10800
二、application.xml文件
<?xml version="1.0" encoding="UTF-8"?>
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"?xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"?xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd">????
classpath*:jdbc.properties
destroy-method="close">
${datasource.driverClassName}
${r.datasource.url}
${datasource.username}
${r.datasource.password}
${c3p0.acquireIncrement}
${c3p0.acquireRetryAttempts}
${c3p0.acquireRetryDelay}
${c3p0.initialPoolSize}
${c3p0.testConnectionOnCheckout}
${c3p0.minPoolSize}
${c3p0.maxPoolSize}
${c3p0.maxIdleTime}
${c3p0.idleConnectionTestPeriod}
${c3p0.maxStatements}
${c3p0.numHelperThreads}
destroy-method="close">
${datasource.driverClassName}
${w.datasource.url}
${datasource.username}
${w.datasource.password}
${c3p0.acquireIncrement}
${c3p0.acquireRetryAttempts}
${c3p0.acquireRetryDelay}
${c3p0.initialPoolSize}
${c3p0.testConnectionOnCheckout}
${c3p0.minPoolSize}
${c3p0.maxPoolSize}
${c3p0.maxIdleTime}
${c3p0.idleConnectionTestPeriod}
${c3p0.maxStatements}
${c3p0.numHelperThreads}
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
${hibernate.dialect}
${hibernate.connection.autocommit}
${hibernate.show_sql}
${hibernate.format_sql}
${hibernate.hbm2ddl.auto}
utf-8
${hibernate.cache.user_query_cache}
${hibernate.user_second_level_cache}
${hibernate.cache.class}
${hibernate.ehcache_config_file}
三、繼承AbstractRoutingDataSource類的動態數據源類DynamicDataSource
package?com.eb3.ddt;
import?org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public?class?DynamicDataSource extends?AbstractRoutingDataSource {
/**
*?重寫determineCurrentLookupKey方法
*/
@Override
protected?Object determineCurrentLookupKey() {
Object obj = DBHelper.getDbType();
return?obj;
}
}
四、DBHelper工具類
package?com.eb3.ddt;
import?org.apache.commons.lang.StringUtils;
public?class?DBHelper {
private?static?ThreadLocal dbContext = new?ThreadLocal();
//?寫數據源標識
public?final?static?String DB_WRITE = "dataSourceWrite";
//?讀數據源標識
public?final?static?String DB_READ = "dataSourceRead";
/**
*?獲取數據源類型,即是寫數據源,還是讀數據源
*
* @return
*/
public?static?String getDbType() {
String db_type = dbContext.get();
if?(StringUtils.isEmpty(db_type)) {
//?默認是寫數據源
db_type = DB_WRITE;
}
return?db_type;
}
/**
*?設置該線程的數據源類型
*
* @param?str
*/
public?static?void?setDbType(String str) {
dbContext.set(str);
}
}
五、服務層調用
/*@Aspect?此注解會影響數據源切換,運行代碼得知不加的話會先執行DynamicDataSource里的determineCurrentLookupKey方法,后執行Service層里DBHelper.setDbType()方法,導致數據源切換失敗!*/
@Aspect
@Component("userService")public?class?UserServiceImpl extends?BaseServiceImpl implements?UserService {
@Resource
private?UserDao userDao;
@Override
protected?BaseDao getDao() {
return?this.userDao;
}
@Override
public?void?save(User user) {
DBHelper.setDbType(DBHelper.DB_WRITE); //?寫庫?(向數據庫中寫)
this.userDao.save(user);
}
@Override
public?User findByUserName(String username) {
DBHelper.setDbType(DBHelper.DB_READ); //?讀庫?(從數據庫中向外讀)
List userList = this.userDao.findBy("username", username);
return?CollectionUtils.isNotEmpty(userList) ? userList.get(0) : null;
}
}
總結
以上是生活随笔為你收集整理的java dbtype_Java实现数据库的读写分离的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 整数加减_Java计算长整数加
- 下一篇: java中上传文件_Java中文件上传下