@Configuration
@Slf4j
public class DataSourceConfiguration {
@Value("${druid.type}")
public Class extends DataSource> dataSourceType;
@Bean(name = "masterDataSource")
@Primary
@ConfigurationProperties(prefix = "druid.master")
public DataSource masterDataSource() {
DataSource masterDataSource = DataSourceBuilder.create().type(dataSourceType).build();
log.info("=====================MASTER======================" + masterDataSource);
return masterDataSource;
}
@Bean(name = "slaveDataSource")
@ConfigurationProperties(prefix = "druid.slave")
public DataSource slaveDataSource() {
DataSource slaveDataSource = DataSourceBuilder.create().type(dataSourceType).build();
log.info("=====================SLAVE======================" + slaveDataSource);
return slaveDataSource;
}
@Bean
public DataSource routingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
@Qualifier("slaveDataSource") DataSource slaveDataSource) {
Map
DataBaseContextHolder.java
public enum DataBaseType {
MASTER, SLAVE
}
private static final ThreadLocal context = new ThreadLocal<>();
public static void setDataBaseType(DataBaseType dataBaseType) {
if (dataBaseType == null) {
throw new NullPointerException();
}
context.set(dataBaseType);
}
public static DataBaseType getDataBaseType() {
return context.get() == null ? DataBaseType.MASTER : context.get();
}
public static void clearDataBaseType() {
context.remove();
}
public class ReadWriteSplitRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataBaseContextHolder.getDataBaseType();
}
}
六、自定义标识,标识什么时候切换数据源(这里使用自定义注解)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ReadOnlyAnnotation {
}
七、AOP拦截,当使用@ReadOnlyAnnotation 时,动态切换至从数据源
@Aspect
@Slf4j
public class ReadOnlyAnnotationInterceptor implements Ordered {
@Around("@annotation(readOnlyAnnotation)")
public Object proceed(ProceedingJoinPoint joinPoint, ReadOnlyAnnotation readOnlyAnnotation) throws Throwable {
try {
log.info("==================开始切换数据源为只读,从数据源==================");
DataBaseContextHolder.setDataBaseType(DataBaseContextHolder.DataBaseType.SLAVE);
Object proceed = joinPoint.proceed();
return proceed;
} finally {
log.info("=================切换为主数据源=========================");
DataBaseContextHolder.clearDataBaseType();
}
}
@Override
public int getOrder() {
return 0;
}
}
八、验证
主从数据库都开启日志,查看日志文件查询哪个库,之后,关闭日志。
#查看是否开启日志记录
SHOW VARIABLES WHERE Variable_name="general_log";
#显示为OFF为关闭
#临时开启日志记录,重启服务器之后失效
SET GLOBAL general_log=ON;
#查看日志的名称
SHOW VARIABLES WHERE Variable_name="general_log_file";
#登录MariaDB服务器,查看日志位置
find / --name "日志名"
tail -f /var/lib/mysql/localhost.log
#主从服务器,都关闭日志
SET GLOBAL general_log=OFF;
<script language="javascript">
$(function (){
var i = 4;$(window).bind("scroll", function (event){
//滚动条到网页头部的 高度,兼容ie,ff,chrome
var top = document.documentElement.s
包冲突是开发过程中很常见的问题:
其表现有:
1.明明在eclipse中能够索引到某个类,运行时却报出找不到类。
2.明明在eclipse中能够索引到某个类的方法,运行时却报出找不到方法。
3.类及方法都有,以正确编译成了.class文件,在本机跑的好好的,发到测试或者正式环境就
抛如下异常:
java.lang.NoClassDefFoundError: Could not in
NAME: gpasswd - administer the /etc/group file
SYNOPSIS:
gpasswd group
gpasswd -a user group
gpasswd -d user group
gpasswd -R group
gpasswd -r group
gpasswd [-A user,...] [-M user,...] g
enquiry mysql version in centos linux
yum list installed | grep mysql
yum -y remove mysql-libs.x86_64
enquiry mysql version in yum repositoryyum list | grep mysql oryum -y list mysql*
install mysq
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.
Below is one possible representation of s1 = "great":
select p.spid,c.object_name,b.session_id,b.oracle_username,b.os_user_name from v$process p,v$session a, v$locked_object b,all_objects c where p.addr=a.paddr and a.process=b.process and c.object_id=b.