jsp 语言 JSP 与 MyBatis 实现数据库分库分表示例

JSP阿木 发布于 2025-07-03 17 次阅读


JSP 与 MyBatis 实现数据库分库分表示例

随着互联网技术的飞速发展,企业应用的数据量越来越大,传统的单库单表架构已经无法满足日益增长的数据处理需求。为了提高系统的性能和可扩展性,数据库分库分表技术应运而生。本文将结合 JSP 和 MyBatis 框架,实现一个简单的数据库分库分表示例,帮助读者了解如何在实际项目中应用这一技术。

环境准备

在开始之前,我们需要准备以下环境:

1. JDK 1.8 或更高版本

2. MySQL 5.7 或更高版本

3. Tomcat 8.5 或更高版本

4. MyBatis 3.5.2 或更高版本

5. Maven 3.6.3 或更高版本

项目结构

以下是项目的目录结构:


src/


|-- main/


| |-- java/


| | |-- com/


| | | |-- example/


| | | | |-- controller/


| | | | | |-- UserAction.java


| | | | |-- mapper/


| | | | | |-- UserMapper.java


| | | | |-- model/


| | | | | |-- User.java


| | | | |-- service/


| | | | | |-- UserService.java


| | | | |-- SpringConfig.java


| |-- resources/


| | |-- mybatis/


| | | |-- mapper/


| | | | |-- UserMapper.xml


| | |-- db.properties


| |-- web.xml


|-- test/


| |-- java/


| | |-- com/


| | | |-- example/


| | | | |-- UserMapperTest.java


|-- pom.xml


数据库设计

为了演示分库分表技术,我们假设有两个数据库,分别存储不同类型的数据:

1. `user_db`:存储普通用户数据

2. `admin_db`:存储管理员数据

以下是两个数据库的表结构:

sql

CREATE TABLE `user_db`.`user` (


`id` INT NOT NULL AUTO_INCREMENT,


`username` VARCHAR(50) NOT NULL,


`password` VARCHAR(50) NOT NULL,


PRIMARY KEY (`id`)


);

CREATE TABLE `admin_db`.`admin` (


`id` INT NOT NULL AUTO_INCREMENT,


`username` VARCHAR(50) NOT NULL,


`password` VARCHAR(50) NOT NULL,


PRIMARY KEY (`id`)


);


MyBatis 配置

在 `resources/mybatis/mapper` 目录下创建 `UserMapper.xml` 文件,配置 MyBatis 的映射信息:

xml

<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<mapper namespace="com.example.mapper.UserMapper">


<select id="selectUser" resultType="com.example.model.User">


SELECT FROM user_db.user WHERE id = {id}


</select>


<select id="selectAdmin" resultType="com.example.model.User">


SELECT FROM admin_db.admin WHERE id = {id}


</select>


</mapper>


在 `resources/db.properties` 文件中配置数据库连接信息:

properties

数据库连接信息


user_db.driver=com.mysql.cj.jdbc.Driver


user_db.url=jdbc:mysql://localhost:3306/user_db?useSSL=false&serverTimezone=UTC


user_db.username=root


user_db.password=root

admin_db.driver=com.mysql.cj.jdbc.Driver


admin_db.url=jdbc:mysql://localhost:3306/admin_db?useSSL=false&serverTimezone=UTC


admin_db.username=root


admin_db.password=root


Spring 配置

在 `src/main/java/com/example/SpringConfig.java` 文件中配置 Spring 和 MyBatis 的整合:

java

package com.example;

import org.mybatis.spring.annotation.MapperScan;


import org.springframework.context.annotation.Bean;


import org.springframework.context.annotation.Configuration;


import org.springframework.context.annotation.PropertySource;


import org.springframework.core.env.Environment;


import org.springframework.jdbc.datasource.DriverManagerDataSource;


import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;


import java.util.HashMap;


import java.util.Map;

@Configuration


@PropertySource("classpath:db.properties")


@MapperScan("com.example.mapper")


public class SpringConfig {

private final Environment env;

public SpringConfig(Environment env) {


this.env = env;


}

@Bean


public DataSource dataSource() {


AbstractRoutingDataSource dataSource = new AbstractRoutingDataSource() {


@Override


protected Object determineCurrentLookupKey() {


return DataSourceContextHolder.getDbType();


}


};

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


dataSourceMap.put("user_db", createDataSource(env.getProperty("user_db.driver"), env.getProperty("user_db.url"), env.getProperty("user_db.username"), env.getProperty("user_db.password")));


dataSourceMap.put("admin_db", createDataSource(env.getProperty("admin_db.driver"), env.getProperty("admin_db.url"), env.getProperty("admin_db.username"), env.getProperty("admin_db.password")));

dataSource.setTargetDataSources(dataSourceMap);


dataSource.setDefaultTargetDataSource(dataSourceMap.get("user_db"));


return dataSource;


}

private DriverManagerDataSource createDataSource(String driver, String url, String username, String password) {


DriverManagerDataSource dataSource = new DriverManagerDataSource();


dataSource.setDriverClassName(driver);


dataSource.setUrl(url);


dataSource.setUsername(username);


dataSource.setPassword(password);


return dataSource;


}


}


数据库路由

在 `src/main/java/com/example/mapper/UserMapper.java` 文件中,定义一个 `DataSourceContextHolder` 类,用于存储当前线程的数据库类型:

java

package com.example.mapper;

public class DataSourceContextHolder {


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

public static void setDbType(String dbType) {


contextHolder.set(dbType);


}

public static String getDbType() {


return contextHolder.get();


}

public static void clearDbType() {


contextHolder.remove();


}


}


在 `src/main/java/com/example/service/UserService.java` 文件中,修改 `selectUser` 和 `selectAdmin` 方法,根据用户类型设置数据库类型:

java

package com.example.service;

import com.example.mapper.UserMapper;


import com.example.model.User;


import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.stereotype.Service;

@Service


public class UserService {

@Autowired


private UserMapper userMapper;

public User selectUser(int id) {


DataSourceContextHolder.setDbType("user_db");


return userMapper.selectUser(id);


}

public User selectAdmin(int id) {


DataSourceContextHolder.setDbType("admin_db");


return userMapper.selectAdmin(id);


}


}


JSP 页面

在 `src/main/webapp/WEB-INF/jsp` 目录下创建 `user.jsp` 和 `admin.jsp` 页面,分别用于展示用户和管理员信息:

jsp

<!-- user.jsp -->


<%@ page contentType="text/html;charset=UTF-8" language="java" %>


<html>


<head>


<title>User Information</title>


</head>


<body>


<h1>User Information</h1>


<%


UserService userService = (UserService) application.getAttribute("userService");


User user = userService.selectUser(1);


if (user != null) {


%>


<p>Username: ${user.getUsername()}</p>


<p>Password: ${user.getPassword()}</p>


<%


} else {


%>


<p>User not found.</p>


<%


}


%>


</body>


</html>


jsp

<!-- admin.jsp -->


<%@ page contentType="text/html;charset=UTF-8" language="java" %>


<html>


<head>


<title>Admin Information</title>


</head>


<body>


<h1>Admin Information</h1>


<%


UserService userService = (UserService) application.getAttribute("userService");


User admin = userService.selectAdmin(1);


if (admin != null) {


%>


<p>Username: ${admin.getUsername()}</p>


<p>Password: ${admin.getPassword()}</p>


<%


} else {


%>


<p>Admin not found.</p>


<%


}


%>


</body>


</html>


总结

本文通过 JSP 和 MyBatis 框架,实现了一个简单的数据库分库分表示例。在实际项目中,我们可以根据业务需求,灵活地调整数据库路由策略,提高系统的性能和可扩展性。希望本文能对您有所帮助。