【MyBatis】mybatis的使用及与spring的集成

MyBatis 是一个流行的 Java 数据持久化框架,它提供了对数据库操作的简化方式。与 Hibernate 等全功能 ORM 框架不同,MyBatis 不会映射 Java 对象与数据库表之间的关系,而是关注于 SQL 的编写与执行。因此,它特别适用于那些需要对 SQL 语句进行精细控制的应用程序。

本文将详细介绍如何使用 MyBatis,包括其基本配置、使用 Mapper 进行数据库操作以及与 Spring 的集成。

目录

  1. MyBatis 简介
  2. 环境准备
  3. 基本配置
  4. 使用 XML 配置文件
  5. 使用注解配置
  6. 与 Spring 的集成
  7. 示例项目
  8. 总结

MyBatis 简介

MyBatis 是一个优秀的持久化层框架,它主要关注于:

  • SQL 语句的复用和组织:通过 XML 或注解来定义 SQL。
  • 动态 SQL:支持在 SQL 中使用动态逻辑。
  • 自动映射:结果集可以自动映射到 Java 对象。
  • 灵活性:允许使用原始 SQL,适用于需要精确控制的数据库操作。
  • 缓存支持:支持一级缓存和二级缓存。

环境准备

在开始之前,确保已经安装并配置好以下环境:

  • JDK: Java 8 或更高版本
  • Maven: 作为构建工具
  • MySQL: 数据库示例
  • IDE: IntelliJ IDEA 或 Eclipse

依赖配置

pom.xml 文件中添加以下依赖:

<dependencies>
    <!-- MyBatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.13</version>
    </dependency>

    <!-- MyBatis Spring 支持 -->
    <dependency>
        <groupId>org.mybatis.spring</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.3.1</version>
    </dependency>

    <!-- MySQL JDBC 驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.34</version>
    </dependency>

    <!-- Spring 相关依赖 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.22</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.22</version>
    </dependency>

    <!-- 数据源 -->
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
        <version>5.0.1</version>
    </dependency>

    <!-- 日志 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.36</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.36</version>
    </dependency>
</dependencies>

基本配置

1. 创建数据库和表

在 MySQL 中创建一个名为 testdb 的数据库和一个名为 users 的表:

CREATE DATABASE testdb;

USE testdb;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(50) NOT NULL,
    email VARCHAR(100)
);

2. 配置 MyBatis

MyBatis 使用 XML 文件或注解来配置映射信息。下面是基本的 XML 配置文件示例:

mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 数据库环境配置 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/testdb?useSSL=false&amp;serverTimezone=UTC"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 映射器配置 -->
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

解析

  • transactionManager:指定事务管理器类型。常用的有 JDBCMANAGED
  • dataSource:配置数据源,POOLED 表示使用连接池。
  • mappers:指定 Mapper 映射文件的路径。

3. 编写实体类

User.java

package com.example.entity;

public class User {
    private Integer id;
    private String username;
    private String password;
    private String email;

    // Getters and Setters

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

4. 编写 Mapper 接口和 XML 配置文件

Mapper 接口

UserMapper.java

package com.example.mapper;

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

import java.util.List;

public interface UserMapper {

    @Insert("INSERT INTO users (username, password, email) VALUES (#{username}, #{password}, #{email})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    void insertUser(User user);

    @Select("SELECT * FROM users WHERE id = #{id}")
    User selectUserById(@Param("id") int id);

    @Select("SELECT * FROM users")
    List<User> selectAllUsers();

    @Update("UPDATE users SET username = #{username}, password = #{password}, email = #{email} WHERE id = #{id}")
    void updateUser(User user);

    @Delete("DELETE FROM users WHERE id = #{id}")
    void deleteUser(@Param("id") int id);
}
XML 配置文件

UserMapper.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">
    
    <insert id="insertUser" parameterType="com.example.entity.User" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO users (username, password, email)
        VALUES (#{username}, #{password}, #{email})
    </insert>

    <select id="selectUserById" parameterType="int" resultType="com.example.entity.User">
        SELECT * FROM users WHERE id = #{id}
    </select>

    <select id="selectAllUsers" resultType="com.example.entity.User">
        SELECT * FROM users
    </select>

    <update id="updateUser" parameterType="com.example.entity.User">
        UPDATE users
        SET username = #{username},
            password = #{password},
            email = #{email}
        WHERE id = #{id}
    </update>

    <delete id="deleteUser" parameterType="int">
        DELETE FROM users WHERE id = #{id}
    </delete>

</mapper>

解析

  • namespace:指定 Mapper 接口的完全限定名,用于与 XML 文件关联。
  • parameterType:指定参数类型,可以是简单类型(如 intString)或 Java 类。
  • resultType:指定返回结果类型,通常是 Java 类或简单类型。
  • useGeneratedKeys:设置为 true 时,MyBatis 会自动获取数据库生成的主键值。

使用 XML 配置文件

在 MyBatis 中,SQL 语句可以通过 XML 文件进行配置,这是一种常见的方式。以下是如何

使用 XML 配置文件来管理数据库操作。

1. 配置 SQL 语句

UserMapper.xml 文件中,我们已经定义了各种 SQL 语句,接下来是如何在代码中使用它们。

2. 配置 SqlSessionFactory

SqlSessionFactory 是 MyBatis 的核心对象之一,用于创建 SqlSession 实例。我们需要通过配置文件来创建它。

MyBatisUtil.java
package com.example.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.session.SqlSession;

import java.io.IOException;
import java.io.InputStream;

public class MyBatisUtil {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        String resource = "mybatis-config.xml";
        try (InputStream inputStream = Resources.getResourceAsStream(resource)) {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

3. 使用 Mapper 执行数据库操作

接下来,我们使用 MyBatisUtil 工具类来获取 SqlSession 实例,并通过 Mapper 接口执行数据库操作。

MainApp.java
package com.example;

import com.example.entity.User;
import com.example.mapper.UserMapper;
import com.example.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class MainApp {

    public static void main(String[] args) {
        try (SqlSession sqlSession = MyBatisUtil.getSqlSession()) {
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

            // 创建用户
            User user = new User();
            user.setUsername("john_doe");
            user.setPassword("password123");
            user.setEmail("john.doe@example.com");
            userMapper.insertUser(user);
            sqlSession.commit(); // 提交事务
            System.out.println("User created with ID: " + user.getId());

            // 查询用户
            User retrievedUser = userMapper.selectUserById(user.getId());
            System.out.println("Retrieved User: " + retrievedUser.getUsername());

            // 更新用户
            retrievedUser.setPassword("new_password123");
            userMapper.updateUser(retrievedUser);
            sqlSession.commit();
            System.out.println("User updated.");

            // 查询所有用户
            List<User> allUsers = userMapper.selectAllUsers();
            allUsers.forEach(u -> System.out.println("User: " + u.getUsername()));

            // 删除用户
            userMapper.deleteUser(user.getId());
            sqlSession.commit();
            System.out.println("User deleted.");
        }
    }
}

解析

  • 获取 SqlSession:通过 MyBatisUtil.getSqlSession() 获取 SqlSession 实例。
  • 获取 Mapper 接口:通过 sqlSession.getMapper(UserMapper.class) 获取 Mapper 实例。
  • 执行操作:调用 Mapper 接口的方法执行数据库操作,如 insertUser()selectUserById() 等。
  • 事务管理:调用 sqlSession.commit() 提交事务,sqlSession.rollback() 回滚事务。

使用注解配置

除了使用 XML 配置文件外,MyBatis 还支持通过注解直接在 Mapper 接口中定义 SQL 语句。以下是如何使用注解进行配置。

1. 修改 Mapper 接口

UserMapper.java 中,我们已经通过注解定义了 SQL 语句。

package com.example.mapper;

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

import java.util.List;

public interface UserMapper {

    @Insert("INSERT INTO users (username, password, email) VALUES (#{username}, #{password}, #{email})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    void insertUser(User user);

    @Select("SELECT * FROM users WHERE id = #{id}")
    User selectUserById(@Param("id") int id);

    @Select("SELECT * FROM users")
    List<User> selectAllUsers();

    @Update("UPDATE users SET username = #{username}, password = #{password}, email = #{email} WHERE id = #{id}")
    void updateUser(User user);

    @Delete("DELETE FROM users WHERE id = #{id}")
    void deleteUser(@Param("id") int id);
}

2. 执行数据库操作

使用注解方式的执行与使用 XML 配置相同,只需调用 Mapper 接口的方法即可。

try (SqlSession sqlSession = MyBatisUtil.getSqlSession()) {
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

    // 创建用户
    User user = new User();
    user.setUsername("john_doe");
    user.setPassword("password123");
    user.setEmail("john.doe@example.com");
    userMapper.insertUser(user);
    sqlSession.commit(); // 提交事务
    System.out.println("User created with ID: " + user.getId());

    // 查询用户
    User retrievedUser = userMapper.selectUserById(user.getId());
    System.out.println("Retrieved User: " + retrievedUser.getUsername());

    // 更新用户
    retrievedUser.setPassword("new_password123");
    userMapper.updateUser(retrievedUser);
    sqlSession.commit();
    System.out.println("User updated.");

    // 查询所有用户
    List<User> allUsers = userMapper.selectAllUsers();
    allUsers.forEach(u -> System.out.println("User: " + u.getUsername()));

    // 删除用户
    userMapper.deleteUser(user.getId());
    sqlSession.commit();
    System.out.println("User deleted.");
}

解析

  • 使用注解配置后,SQL 语句直接嵌入在 Java 代码中,无需单独的 XML 文件。
  • 注解配置更简单,但在复杂 SQL 语句中可能显得不够灵活,特别是在涉及动态 SQL 时。

与 Spring 的集成

MyBatis 可以方便地与 Spring 集成,从而简化事务管理和数据库连接管理。以下是一个简单的 MyBatis 与 Spring 的集成示例。

1. 配置 Spring 和 MyBatis

AppConfig.java
package com.example.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "com.example")
@MapperScan("com.example.mapper") // 扫描 Mapper 接口
public class AppConfig {

    @Bean
    public DataSource dataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        dataSource.setMaximumPoolSize(10);
        return dataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:com/example/mapper/*.xml"));
        return sessionFactory.getObject();
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

解析

  • @MapperScan:用于扫描 Mapper 接口,自动生成实现类。
  • SqlSessionFactoryBean:用于创建 SqlSessionFactory 实例。
  • HikariDataSource:配置数据源,使用 HikariCP 作为连接池。

2. 使用 Spring 的方式调用 MyBatis

在 Spring 环境中,可以通过依赖注入的方式来获取 Mapper 接口实例。

UserService.java
package com.example.service;

import com.example.entity.User;
import com.example.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Transactional
    public void createUser(User user) {
        userMapper.insertUser(user);
    }

    public User getUserById(int id) {
        return userMapper.selectUserById(id);
    }

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

    @Transactional
    public void updateUser(User user) {
        userMapper.updateUser(user);
    }

    @Transactional
    public void deleteUser(int id) {
        userMapper.deleteUser(id);
    }
}

解析

  • @Service:标识业务层组件。
  • @Transactional:在方法级别或类级别启用事务管理

3. Spring Boot 集成 MyBatis 示例

如果你使用 Spring Boot,可以更加简化配置过程。以下是一个简单的 Spring Boot 集成 MyBatis 的示例。

pom.xml
<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <!-- Spring Boot MyBatis Starter -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.2</version>
    </dependency>

    <!-- MySQL Driver -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <!-- Spring Boot Test -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
</dependencies>
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

mybatis.mapper-locations=classpath:com/example/mapper/*.xml
Application.java
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

4. 使用 Spring Boot 进行操作

在 Spring Boot 环境中,操作与 Spring 的方式相似,可以直接使用依赖注入的方式来调用服务。

UserServiceTest.java
package com.example;

import com.example.entity.User;
import com.example.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void testCreateUser() {
        User user = new User();
        user.setUsername("jane_doe");
        user.setPassword("secret");
        user.setEmail("jane.doe@example.com");
        userService.createUser(user);
    }

    @Test
    public void testGetUserById() {
        User user = userService.getUserById(1);
        System.out.println("User: " + user.getUsername());
    }

    @Test
    public void testGetAllUsers() {
        List<User> users = userService.getAllUsers();
        users.forEach(user -> System.out.println("User: " + user.getUsername()));
    }

    @Test
    public void testUpdateUser() {
        User user = userService.getUserById(1);
        user.setPassword("new_secret");
        userService.updateUser(user);
    }

    @Test
    public void testDeleteUser() {
        userService.deleteUser(1);
    }
}

总结

MyBatis 是一个轻量级的持久化框架,提供了对 SQL 的良好支持和灵活性。通过本文,我们了解了如何配置和使用 MyBatis,包括:

  • 基本配置和使用
  • XML 和注解方式的配置
  • 与 Spring 的集成
  • Spring Boot 环境中的使用

MyBatis 在需要手动编写 SQL 和复杂查询的场景中非常有用,同时它也能够与 Spring 和 Spring Boot 无缝集成,从而提供更强大的数据访问解决方案。希望本文能帮助你快速上手 MyBatis,并在实际项目中发挥其作用。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值