当前位置:首页 > 编程技术 > 正文内容

Java与MySQL数据库分库分表实践详解

yc88810个月前 (02-07)编程技术154

Java与MySQL数据库分库分表实践详解

在大型应用中,为了提高数据库性能和可扩展性,常常会采用分库分表的策略。本文将详细介绍如何使用Java语言搭配MySQL数据库进行分库分表,并提供相关的代码实例。

1. 环境准备

确保项目中引入了数据库连接池,例如使用Druid。在pom.xml中添加以下依赖:

<dependency>

    <groupId>com.alibaba</groupId>

    <artifactId>druid</artifactId>

    <version>1.2.6</version>

</dependency>

2. 分库分表策略选择

常见的分库分表策略有垂直切分和水平切分。垂直切分是将数据库按照业务模块划分,每个库负责一个模块;水平切分是将同一表的数据按照一定规则划分到不同的表中。本文以水平切分为例进行演示。

3. 数据库配置

application.properties(或application.yml)中配置多个数据源:

# 数据源1

spring.datasource.ds1.url=jdbc:mysql://localhost:3306/db1

spring.datasource.ds1.username=root

spring.datasource.ds1.password=root

# 数据源2

spring.datasource.ds2.url=jdbc:mysql://localhost:3306/db2

spring.datasource.ds2.username=root

spring.datasource.ds2.password=root

4. 配置数据源和事务管理

在配置类中配置多个数据源和事务管理:

@Configuration

public class DataSourceConfig {


    @Primary

    @Bean(name = "ds1DataSource")

    @ConfigurationProperties(prefix = "spring.datasource.ds1")

    public DataSource dataSource1() {

        return DataSourceBuilder.create().build();

    }


    @Bean(name = "ds2DataSource")

    @ConfigurationProperties(prefix = "spring.datasource.ds2")

    public DataSource dataSource2() {

        return DataSourceBuilder.create().build();

    }


    @Bean(name = "dynamicDataSource")

    public DynamicDataSource dynamicDataSource(@Qualifier("ds1DataSource") DataSource ds1DataSource,

                                               @Qualifier("ds2DataSource") DataSource ds2DataSource) {

        Map<Object, Object> targetDataSources = new HashMap<>();

        targetDataSources.put(DatabaseType.DS1, ds1DataSource);

        targetDataSources.put(DatabaseType.DS2, ds2DataSource);


        DynamicDataSource dynamicDataSource = new DynamicDataSource();

        dynamicDataSource.setTargetDataSources(targetDataSources);

        dynamicDataSource.setDefaultTargetDataSource(ds1DataSource);


        return dynamicDataSource;

    }


    @Bean

    public PlatformTransactionManager transactionManager(@Qualifier("dynamicDataSource") DataSource dataSource) {

        return new DataSourceTransactionManager(dataSource);

    }

}

5. 动态数据源切换

创建一个DynamicDataSource类,继承AbstractRoutingDataSource,用于动态切换数据源:

public class DynamicDataSource extends AbstractRoutingDataSource {


    @Override

    protected Object determineCurrentLookupKey() {

        return DatabaseContextHolder.getDatabaseType();

    }

}

6. 数据库上下文

创建一个DatabaseContextHolder类,用于保存当前线程使用的数据源:

public class DatabaseContextHolder {


    private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();


    public static void setDatabaseType(DatabaseType type) {

        contextHolder.set(type);

    }


    public static DatabaseType getDatabaseType() {

        return contextHolder.get();

    }


    public static void clearDatabaseType() {

        contextHolder.remove();

    }

}

7. 数据库类型枚举

创建一个DatabaseType枚举类,用于定义多数据源的标识:

public enum DatabaseType {

    DS1, DS2;

}

8. 切面配置

创建一个切面类,用于在执行数据库操作前切换数据源:

@Aspect

@Component

public class DataSourceAspect {


    @Before("execution(* com.example.dao.ds1..*.*(..))")

    public void setDataSource1() {

        DatabaseContextHolder.setDatabaseType(DatabaseType.DS1);

    }


    @Before("execution(* com.example.dao.ds2..*.*(..))")

    public void setDataSource2() {

        DatabaseContextHolder.setDatabaseType(DatabaseType.DS2);

    }


    @After("execution(* com.example.dao..*.*(..))")

    public void restoreDataSource() {

        DatabaseContextHolder.clearDatabaseType();

    }

}

9. 编写DAO层代码

在DAO层中按照业务需求使用不同的数据源:

@Repository

public interface UserMapper {


    @DataSource(DatabaseType.DS1)

    List<User> getAllUsersFromDS1();


    @DataSource(DatabaseType.DS2)

    List<User> getAllUsersFromDS2();


    // 其他数据操作方法

}

10. 示例代码

以Spring Boot为例,编写一个简单的Controller进行测试:

@RestController

@RequestMapping("/user")

public class UserController {


    @Autowired

    private UserMapper userMapper;


    @GetMapping("/getAllUsersFromDS1")

    public List<User> getAllUsersFromDS1() {

        return userMapper.getAllUsersFromDS1();

    }


    @GetMapping("/getAllUsersFromDS2")

    public List<User> getAllUsersFromDS2() {

        return userMapper.getAllUsersFromDS2();

    }

}

以上是一个基本的Java与MySQL数据库分库分表的实践,通过配置多数据源、动态切换数据源,实现了水平切分的策略。在实际应用中,可以根据业务需求和数据库规模进一步优化和拓展。希望这份详细的代码实例对你理解Java与MySQL分库分表有所帮助。

本站发布的内容若侵犯到您的权益,请邮件联系站长删除,我们将及时处理!


从您进入本站开始,已表示您已同意接受本站【免责声明】中的一切条款!


本站大部分下载资源收集于网络,不保证其完整性以及安全性,请下载后自行研究。


本站资源仅供学习和交流使用,版权归原作者所有,请勿商业运营、违法使用和传播!请在下载后24小时之内自觉删除。


若作商业用途,请购买正版,由于未及时购买和付费发生的侵权行为,使用者自行承担,概与本站无关。


本文链接:https://www.10zhan.com/biancheng/10985.html

分享给朋友:

“Java与MySQL数据库分库分表实践详解” 的相关文章

【说站】Thymeleaf报错Error resolving template “XXX”

【说站】Thymeleaf报错Error resolving template “XXX”

修改了一下开源项目的目录结构访问突然报错Error resolving template “XXX”可能原因有如下三种:第一种可能:原因:在使用springboot的过程中,如果使用thymeleaf...

【说站】用一句话就可以去除宝塔面板操作上的二次验证

【说站】用一句话就可以去除宝塔面板操作上的二次验证

用过宝塔的朋友应该都会发现,现在宝塔面板有些鸡肋的功能,删除文件、删除数据库、删除站点等操作都需要做计算题!不仅加了几秒的延时等待,还无法跳过!这时候就会有朋友在想,如何去除宝塔面板的二次验证,此篇文...

【说站】Centos8.0如何配置静态IP详解及永久关闭防火墙

【说站】Centos8.0如何配置静态IP详解及永久关闭防火墙

这篇文章主要介绍了详解Centos8 配置静态IP的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来学习一下!1. 查看自己的网关地址点击虚...

【说站】电脑安装MySQL时出现starting the server失败原因及解决方案

【说站】电脑安装MySQL时出现starting the server失败原因及解决方案

今天在安装MySQL时出现starting the server失败,经过查询分析得出以下结论,记录一下操作步骤。原因分析:如果电脑是第一次安装MySQL,一般不会出现这样的报错。如下图所示。star...

【说站】Java从resources读取文件内容的方法有哪些

【说站】Java从resources读取文件内容的方法有哪些

本文主要介绍的是java读取resource目录下文件的方法,比如这是你的src目录的结构├── main│ ├── java│ │ └── ...

【说站】linux中redis如何以redis用户重启?

【说站】linux中redis如何以redis用户重启?

通过上图我们可以看到,目前状态是已经以 redis 用户启动着,我想修改下 redis 的密码,然后怎么以 redis 用户重启呢?redis 是 nologin 用户,不能通过 su redis 切...