当前位置:网站首页>jeecg master-slave database read-write separation configuration "recommended collection"
jeecg master-slave database read-write separation configuration "recommended collection"
2022-07-31 15:49:00 【Full stack programmer webmaster】
大家好,又见面了,我是你们的朋友全栈君.
1、修改Dbconfig.properties数据库配置文件: 注意:The names of the attributes of the slave library should be distinguished from the attribute names of the master library,The property name will be used later in the configuration file.
#数据库配置 主库-写入库
#MySQL
hibernate.dialect=org.hibernate.dialect.MySQLDialect
validationQuery.sqlserver=SELECT 1
jdbc.url=jdbc\:mysql\://127.0.0.1\:3306/database001?useUnicode\=true&characterEncoding\=UTF-8
jdbc.username=root
jdbc.password=root
jdbc.dbType=mysql
#数据库配置 从库-读库
#MySQL
jdbc.url.slave=jdbc\:mysql\://127.0.0.1\:3306/database002?useUnicode\=true&characterEncoding\=UTF-8
jdbc.username.slave=root
jdbc.password.slave=root
jdbc.dbType.slave=mysql
#更新|创建|验证数据库表结构|不作改变 默认update(create,validate,none)
hibernate.hbm2ddl.auto=none
2、修改spring-mvc-hibernate.xml配置文件 2.1、配置数据源2:Copy the original data source configuration,做以下修改: 1) 数据源的名称name需要重新命名; 2) Set the link property of the database to Dbconfig.properties中数据源2的属性值.
<!-- 配置数据源2 -->
<bean name="dataSource_slave" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url.jeewx.slave}" />
<property name="username" value="${jdbc.username.jeewx.slave}" />
<property name="password" value="${jdbc.password.jeewx.slave}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="0" />
<!-- 连接池最大使用连接数量 -->
<property name="maxActive" value="250" />
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="20" />
<!-- 连接池最小空闲 -->
<property name="minIdle" value="5" />
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="60000" />
<!-- <property name="poolPreparedStatements" value="true" /> <property
name="maxPoolPreparedStatementPerConnectionSize" value="33" /> -->
<property name="validationQuery" value="${validationQuery.sqlserver}" />
<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" />
<!-- 开启Druid的监控统计功能 -->
<property name="filters" value="stat" />
<!--<property name="filters" value="mergeStat" /> -->
<!-- OracleThe connection is to get field annotations -->
<property name="connectProperties">
<props>
<prop key="remarksReporting">true</prop>
</props>
</property>
</bean>
2.2、Configure the data source set:
<!-- 数据源集合 -->
<bean id="dataSource"
class="org.jeecgframework.core.extend.datasource.DynamicDataSource">
<property name="targetDataSources">
<map key-type="org.jeecgframework.core.extend.datasource.DataSourceType">
<entry key="dataSource_jeecg" value-ref="dataSource_jeecg" />
<entry key="dataSource_slave" value-ref="dataSource_slave" />
<!-- <entry key="mapdataSource" value-ref="mapdataSource" /> -->
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource_jeecg" />
</bean>
2.3、定义AOPslicer,关于AOPThe grammar of Baidu can be consulted by yourself,The focus is on the following: (1) org.jeecgframework.core.interceptors.DataSourceAspect类需要实现,This class is mainly used to dynamically switch the database; (2) The expressions here are mainly set for this packageCommonServiceAll methods are faceted; (3) DataSourceAspect类中必须实现before方法,The specific implementation of dynamic switching of the database is controlled here.
<!-- 定义AOP切面处理器 -->
<bean class="org.jeecgframework.core.interceptors.DataSourceAspect" id="dataSourceAspect" />
<aop:config>
<!-- 定义切面,CommonService的所有方法 -->
<aop:pointcut id="txPointcut" expression="execution(* org.jeecgframework.core.common.service.*.*(..))" />
<!-- 将切面应用到自定义slicer上,-9999保证该切面优先级最高执行 -->
<aop:aspect ref="dataSourceAspect" order="-9999">
<aop:before method="before" pointcut-ref="txPointcut" />
</aop:aspect>
</aop:config>
3、实现类org.jeecgframework.core.interceptors.DataSourceAspect:
package org.jeecgframework.core.interceptors;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.jeecgframework.core.extend.datasource.DataSourceContextHolder;
/**
* 定义数据源的AOP切面,通过该Service的方法名判断是应该走读库还是写库
*
* @author yaoxy
*
*/
public class DataSourceAspect {
/**
* 在进入Service方法之前执行
*
* @param point 切面对象
*/
public void before(JoinPoint point) {
// 获取到当前执行的方法名
String methodName = point.getSignature().getName();
if (isSlave(methodName)) {
// 标记为读库
DataSourceContextHolder.markSlave();
} else {
// 标记为写库
DataSourceContextHolder.markMaster();
}
}
/**
* 判断是否为读库
*
* @param methodName
* @return
*/
private Boolean isSlave(String methodName) {
// 方法名以query、find、get开头的方法名走从库
return StringUtils.startsWithAny(methodName, "query","find","get");
}
}
实现原理: 1) 判断AOP切面处理的CommonServiceWhether the name of the method called in the class contains the query keyword at the beginning; 2) 如果CommonServiceThe called method contains the query keyword,调用DataSourceContextHolderSwitch the library to read from the library,Otherwise switch to the main library for write operations. 4、DataSourceContextHolderAdded the method of master-slave switching
ackage org.jeecgframework.core.extend.datasource;
/**
*类名:DataSourceContextHolder.java
*功能:Class to get and set the context,主要负责改变上下文数据源的名称
*/
public class DataSourceContextHolder {
//读库对应的数据源key
private static final ThreadLocal contextHolder=new ThreadLocal();
public static void setDataSourceType(DataSourceType dataSourceType){
contextHolder.set(dataSourceType);
}
public static DataSourceType getDataSourceType(){
return (DataSourceType) contextHolder.get();
}
public static void clearDataSourceType(){
contextHolder.remove();
}
/**
* 标记写库
*/
public static void markMaster(){
setDataSourceType(DataSourceType.dataSource_jeecg);
}
/**
* 标记读库
*/
public static void markSlave(){
setDataSourceType(DataSourceType.dataSource_slave);
}
}
5、Enumeration class for data sourcesDataSourcetypeAppend the newly added slave database data source name to
package org.jeecgframework.core.extend.datasource;
public enum DataSourceType {
dataSource_jeecg,dataSource_enter,dataSource4,mapdataSource,dataSource_slave
//dataSource_jeecg:主库名,dataSource_slave:从库名.
}
总结: The read and write analysis of the application layer involves the following5个文件,see folder【Application layer read-write separation setting file】:
实现的原理:利用Spring AOPThe principle of slice processing,Before the method that operates on the database is executed, it is judged whether to read or write according to the name of the method,进行主从/Switch between read and write databases.
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/127994.html原文链接:https://javaforall.cn
边栏推荐
猜你喜欢
全新宝马3系上市,安全、舒适一个不落
6-22 Vulnerability exploit - postgresql database password cracking
WPF project - basic usage of controls entry, you must know XAML
6-22漏洞利用-postgresql数据库密码破解
WeChat chat record search in a red envelope
The 2nd China PWA Developer Day
Foreign media right, apple on May be true in inventory
Internet banking stolen?This article tells you how to use online banking safely
Kubernetes原理剖析与实战应用手册,太全了
leetcode303 Weekly Match Replay
随机推荐
[CUDA study notes] First acquaintance with CUDA
[MySQL] Mysql paradigm and the role of foreign keys
Tencent Cloud Deployment----DevOps
国内市场上的BI软件,到底有啥区别
Applicable scenario of multi-master replication (2) - client and collaborative editing that require offline operation
Getting Started with TextBlock Control Basic Tools Usage, Get Started
数据表插入数据insert into
Linux查看redis版本(查看mongodb版本)
工程水文学复习资料
BGP综合实验(建立对等体、路由反射器、联邦、路由宣告及聚合)
mysql black window ~ build database and build table
Destruction order of thread_local variables
为什么黑客领域几乎一片男生?
mysql黑窗口~建库建表
数据库的范式(第一范式,第二范式,第三范式,BCNF范式)「建议收藏」
01 Encounter typescript, build environment
How does automated testing create business value?
基于ABP实现DDD
arm按键控制led灯闪烁(嵌入式按键实验报告)
多主复制的适用场景(1)-多IDC