SpringBoot整合MyBatis实战:手把手实现CRUD操作与多数据源切换

🎓博主介绍:Java、Python、js全栈开发 “多面手”,精通多种编程语言和技术,痴迷于人工智能领域。秉持着对技术的热爱与执着,持续探索创新,愿在此分享交流和学习,与大家共进步。
📖DeepSeek-行业融合之万象视界(附实战案例详解100+)
📖全栈开发环境搭建运行攻略:多语言一站式指南(环境搭建+运行+调试+发布+保姆级详解)
👉感兴趣的可以先收藏起来,希望帮助更多的人
在这里插入图片描述

SpringBoot整合MyBatis实战:手把手实现CRUD操作与多数据源切换

一、引言

在当今的软件开发领域,Spring Boot凭借其快速开发、简化配置等优势成为了Java开发的主流框架,而MyBatis作为一款优秀的持久层框架,以其灵活的SQL映射和简单易用的特点深受开发者喜爱。本文将带领技术人员详细了解如何在Spring Boot项目中整合MyBatis,并实现基本的CRUD(创建、读取、更新、删除)操作,同时还会介绍如何实现多数据源的切换。

二、项目环境搭建

2.1 创建Spring Boot项目

可以使用Spring Initializr(https://start.spring.io/ )来快速创建一个Spring Boot项目。在创建项目时,需要添加以下依赖:

  • Spring Web
  • MyBatis Framework
  • MySQL Driver

在选择依赖完成后,点击“Generate”按钮下载项目压缩包,解压后导入到IDE中(如IntelliJ IDEA或Eclipse)。

2.2 配置数据库连接

src/main/resources目录下找到application.properties文件,添加以下数据库连接配置:

spring.datasource.url=jdbc:mysql://localhost:3306/your_database_name?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

your_database_nameyour_usernameyour_password替换为实际的数据库名、用户名和密码。

三、实现CRUD操作

3.1 创建实体类

src/main/java目录下创建对应的实体类,例如创建一个User实体类:

package com.example.demo.entity;

public class User {
    private Integer id;
    private String name;
    private Integer age;

    // 构造函数、Getter和Setter方法
    public User() {}

    public User(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

3.2 创建Mapper接口

创建一个UserMapper接口,用于定义数据库操作方法:

package com.example.demo.mapper;

import com.example.demo.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

@Mapper
public interface UserMapper {
    // 查询所有用户
    @Select("SELECT * FROM user")
    List<User> getAllUsers();

    // 根据ID查询用户
    @Select("SELECT * FROM user WHERE id = #{id}")
    User getUserById(Integer id);

    // 插入用户
    @Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insertUser(User user);

    // 更新用户
    @Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}")
    int updateUser(User user);

    // 删除用户
    @Delete("DELETE FROM user WHERE id = #{id}")
    int deleteUser(Integer id);
}

3.3 创建Service层

创建UserService接口和其实现类UserServiceImpl

// UserService接口
package com.example.demo.service;

import com.example.demo.entity.User;

import java.util.List;

public interface UserService {
    List<User> getAllUsers();
    User getUserById(Integer id);
    int insertUser(User user);
    int updateUser(User user);
    int deleteUser(Integer id);
}

// UserServiceImpl实现类
package com.example.demo.service.impl;

import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> getAllUsers() {
        return userMapper.getAllUsers();
    }

    @Override
    public User getUserById(Integer id) {
        return userMapper.getUserById(id);
    }

    @Override
    public int insertUser(User user) {
        return userMapper.insertUser(user);
    }

    @Override
    public int updateUser(User user) {
        return userMapper.updateUser(user);
    }

    @Override
    public int deleteUser(Integer id) {
        return userMapper.deleteUser(id);
    }
}

3.4 创建Controller层

创建UserController来处理HTTP请求:

package com.example.demo.controller;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    // 获取所有用户
    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }

    // 根据ID获取用户
    @GetMapping("/{id}")
    public User getUserById(@PathVariable Integer id) {
        return userService.getUserById(id);
    }

    // 插入用户
    @PostMapping
    public int insertUser(@RequestBody User user) {
        return userService.insertUser(user);
    }

    // 更新用户
    @PutMapping
    public int updateUser(@RequestBody User user) {
        return userService.updateUser(user);
    }

    // 删除用户
    @DeleteMapping("/{id}")
    public int deleteUser(@PathVariable Integer id) {
        return userService.deleteUser(id);
    }
}

3.5 测试CRUD操作

启动Spring Boot应用程序,使用Postman或其他API测试工具对UserController的各个接口进行测试,验证CRUD操作是否正常。

四、实现多数据源切换

4.1 添加第二个数据源配置

application.properties文件中添加第二个数据源的配置:

# 第二个数据源配置
spring.datasource.second.url=jdbc:mysql://localhost:3306/your_second_database_name?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.second.username=your_second_username
spring.datasource.second.password=your_second_password
spring.datasource.second.driver-class-name=com.mysql.cj.jdbc.Driver

同样,将相关信息替换为实际的值。

4.2 创建数据源配置类

创建DataSourceConfig类来配置多个数据源:

package com.example.demo.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.first", sqlSessionFactoryRef = "firstSqlSessionFactory")
public class DataSourceConfig {
    // 主数据源
    @Primary
    @Bean(name = "firstDataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource firstDataSource() {
        return DataSourceBuilder.create().build();
    }

    // 第二个数据源
    @Bean(name = "secondDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.second")
    public DataSource secondDataSource() {
        return DataSourceBuilder.create().build();
    }

    // 第一个数据源的SqlSessionFactory
    @Primary
    @Bean(name = "firstSqlSessionFactory")
    public SqlSessionFactory firstSqlSessionFactory(@Qualifier("firstDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/first/*.xml"));
        return sessionFactory.getObject();
    }

    // 第二个数据源的SqlSessionFactory
    @Bean(name = "secondSqlSessionFactory")
    public SqlSessionFactory secondSqlSessionFactory(@Qualifier("secondDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/second/*.xml"));
        return sessionFactory.getObject();
    }
}

4.3 创建动态数据源路由

创建DynamicDataSource类来实现动态数据源的切换:

package com.example.demo.config;

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

import java.util.Map;

public class DynamicDataSource extends AbstractRoutingDataSource {
    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSource();
    }
}

4.4 创建数据源上下文持有者

创建DataSourceContextHolder类来保存当前使用的数据源:

package com.example.demo.config;

public class DataSourceContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    public static void setDataSource(String dataSource) {
        contextHolder.set(dataSource);
    }

    public static String getDataSource() {
        return contextHolder.get();
    }

    public static void clearDataSource() {
        contextHolder.remove();
    }
}

4.5 创建数据源切换注解

创建DataSourceSwitch注解,用于在方法上指定使用的数据源:

package com.example.demo.annotation;

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSourceSwitch {
    String value() default "firstDataSource";
}

4.6 创建数据源切换切面

创建DataSourceSwitchAspect切面类,根据注解切换数据源:

package com.example.demo.aspect;

import com.example.demo.annotation.DataSourceSwitch;
import com.example.demo.config.DataSourceContextHolder;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class DataSourceSwitchAspect {
    @Before("@annotation(com.example.demo.annotation.DataSourceSwitch)")
    public void before(JoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        DataSourceSwitch dataSourceSwitch = method.getAnnotation(DataSourceSwitch.class);
        if (dataSourceSwitch != null) {
            DataSourceContextHolder.setDataSource(dataSourceSwitch.value());
        }
    }

    @After("@annotation(com.example.demo.annotation.DataSourceSwitch)")
    public void after(JoinPoint point) {
        DataSourceContextHolder.clearDataSource();
    }
}

4.7 使用数据源切换注解

在需要切换数据源的方法上添加@DataSourceSwitch注解,例如:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    @DataSourceSwitch("secondDataSource")
    public List<User> getUsersFromSecondDataSource() {
        return userMapper.getAllUsers();
    }
}

五、总结

通过以上步骤,我们完成了Spring Boot与MyBatis的整合,并实现了基本的CRUD操作和多数据源的切换。在实际开发中,我们可以根据业务需求灵活运用这些技术,提高系统的性能和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fanxbl957

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值