为了账号安全,请及时绑定邮箱和手机立即绑定

MyBatis入门:从零开始的简单教程

标签:
Java SSM 数据库

本文提供了从零开始的MyBatis入门教程,涵盖了环境搭建、数据库操作、缓存机制及优化技巧等内容。通过详细示例和配置说明,帮助读者快速掌握MyBatis入门知识。文章还包括了常见问题的解决方法和调试技巧,旨在提升开发效率。

MyBatis入门:从零开始的简单教程
MyBatis简介与环境搭建

MyBatis是什么

MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解进行配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。

MyBatis的核心概念

MyBatis 的核心是一个 SqlSession 对象,它提供了在数据库中执行 SQL 命令所需的所有方法。SqlSession 的实例可以通过 SqlSessionFactory 的实例获取。SqlSessionFactory 的实例是通过调用静态工厂方法 SqlSessionFactoryBuilderbuild 方法获取的。以下是 MyBatis 最核心的一些概念:

  1. SqlSessionFactoryBuilder:构建 SqlSessionFactory 的实例。
  2. SqlSessionFactory:使用 SqlSessionFactoryBuilderbuild 方法创建。提供了 SqlSession 的实例。
  3. SqlSession:执行 SQL 语句的会话对象,它是线程不安全的,可以获取映射器接口的实例。
  4. SqlSession 接口的实例:提供了执行 SQL 语句所需的方法,例如 selectOneselectListinsertupdatedelete
  5. Mapper 接口:映射器接口定义了 SQL 语句的签名,通常不必实现这些接口。
  6. Mapper XML 文件:映射器 XML 文件定义了 SQL 语句及其参数和结果映射。
  7. Configuration:MyBatis 的配置对象,里面包含了 MyBatis 的全局配置信息。

开发环境搭建

安装Java环境

确保你已经安装了 Java 环境。可以通过在命令行中输入 java -version 来检查是否安装成功。如果没有安装 Java,可以访问 Oracle 官方网站下载并安装最新版本的 JDK。

Maven依赖配置

在你的 Maven 项目中添加 MyBatis 依赖。在 pom.xml 文件中添加以下依赖:

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
    </dependency>
</dependencies>

配置MyBatis

创建 mybatis-config.xml 配置文件,用于配置 MyBatis 的全局配置。以下是一个简单的配置文件示例:

<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/mydb"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

配置文件中定义了数据源连接信息和 Mapper XML 文件的位置。

实战第一步:使用MyBatis进行数据库操作

第一个MyBatis程序

下面是一个简单的示例,演示如何使用 MyBatis 访问数据库并获取结果集。

创建数据库表和数据

首先,创建一个名为 user 的数据库表,并插入一些数据:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

INSERT INTO `user` VALUES (1, 'zhangsan', '123456');
INSERT INTO `user` VALUES (2, 'lisi', 'abcdef');

创建Mapper接口和XML文件

创建一个 Mapper 接口:

package com.example.mapper;

import com.example.entity.User;
import java.util.List;

public interface UserMapper {
    List<User> selectAllUsers();
}

创建对应的 XML 文件 UserMapper.xml

<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectAllUsers" resultType="com.example.entity.User">
        SELECT * FROM user
    </select>
</mapper>

编写Java代码

编写 Java 代码来使用 MyBatis 进行数据库操作:

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MyBatisExample {
    public static void main(String[] args) {
        try {
            // 读取配置文件
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            // 获取SqlSession
            try (SqlSession session = sqlSessionFactory.openSession()) {
                // 使用Mapper接口
                UserMapper mapper = session.getMapper(UserMapper.class);
                List<User> users = mapper.selectAllUsers();

                // 输出结果
                for (User user : users) {
                    System.out.println(user);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

配置数据库连接

mybatis-config.xml 文件中,配置数据库连接信息。确保数据源配置正确:

<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/mydb"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

SQL映射文件

映射文件定义了 SQL 语句及其参数和结果映射。例如,UserMapper.xml 文件中定义了 selectAllUsers 方法对应的 SQL 语句。

<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectAllUsers" resultType="com.example.entity.User">
        SELECT * FROM user
    </select>
</mapper>

resultType 属性指定了返回结果的 Java 类型。

MyBatis映射器与注解详解

映射文件基础

映射文件结构

映射文件主要由以下几部分组成:

  1. namespace:定义命名空间,通常为 Mapper 接口的全限定名。
  2. select、insert、update、delete:这些元素定义了 SQL 语句及其参数映射和结果映射。

示例

以下是一个完整的 Mapper XML 文件示例:

<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectAllUsers" resultType="com.example.entity.User">
        SELECT * FROM user
    </select>
    <insert id="insertUser">
        INSERT INTO user (username, password) VALUES (#{username}, #{password})
    </insert>
    <update id="updateUser">
        UPDATE user SET username = #{username}, password = #{password} WHERE id = #{id}
    </update>
    <delete id="deleteUser">
        DELETE FROM user WHERE id = #{id}
    </delete>
</mapper>

使用注解进行数据库操作

注解介绍

MyBatis 支持使用注解来定义 SQL 语句,如 @Select@Insert@Update@Delete。注解方法的名称可以与 SQL 语句的 ID 对应。

示例

创建一个 Mapper 接口,并使用注解定义 SQL 语句:

package com.example.mapper;

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

public interface UserMapper {
    @Select("SELECT * FROM user")
    List<User> selectAllUsers();

    @Insert("INSERT INTO user (username, password) VALUES (#{username}, #{password})")
    void insertUser(User user);

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

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

动态SQL的使用

动态SQL概述

动态 SQL 允许在运行时根据条件生成 SQL 语句,提高了 SQL 的灵活性和可维护性。MyBatis 提供了 <if><choose><when><otherwise><trim><where><set><foreach> 等标签来实现动态 SQL。

示例

以下是一个使用 <if> 标签的示例,根据条件生成不同的 SQL 语句:

<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectUserByCondition" resultType="com.example.entity.User">
        SELECT * FROM user
        <where>
            <if test="username != null">
                AND username = #{username}
            </if>
            <if test="password != null">
                AND password = #{password}
            </if>
        </where>
    </select>
</mapper>

使用<foreach>标签循环生成SQL语句

<foreach> 标签用于生成循环 SQL 语句,常用于处理集合类型的参数。

<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectUserByIds" resultType="com.example.entity.User">
        SELECT * FROM user
        WHERE id IN
        <foreach item="item" index="index" collection="ids" open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>
</mapper>
MyBatis与Spring集成入门

Spring与MyBatis集成的重要性

Spring 与 MyBatis 的集成可以简化数据库操作,提高开发效率。Spring 提供了事务管理、配置管理、依赖注入等功能,这些功能可以与 MyBatis 结合使用,实现更强大的开发功能。通过 Spring 的配置方式,可以将 MyBatis 的配置信息整合到 Spring 的配置文件中,实现统一的管理和配置。

配置Spring与MyBatis集成

配置MyBatis的SessionFactory

在 Spring 的配置文件中,定义 SqlSessionFactory 的 Bean,如下所示:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>

配置数据源

定义数据源 Bean:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
    <property name="username" value="root"/>
    <property name="password" value="password"/>
</bean>

配置Mapper接口的扫描

通过 MapperScannerConfigurer,可以自动扫描并注册 Mapper 接口:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.example.mapper"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

编写第一个Spring整合MyBatis应用

创建Spring配置文件

创建 Spring 配置文件 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.example"/>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
        <property name="username" value="root"/>
        <property name="password" value="password"/>
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.example.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>

编写Java代码

编写 Java 代码,注入 Mapper 接口并调用方法:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.example.mapper.UserMapper;
import com.example.entity.User;

public class SpringMyBatisExample {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper userMapper = context.getBean(UserMapper.class);

        User user = userMapper.selectUserById(1);
        System.out.println(user);
    }
}

该示例展示了如何通过 Spring 配置 MyBatis,并在 Java 代码中注入 Mapper 接口。

MyBatis缓存机制

一级缓存工作原理

一级缓存简介

MyBatis 的一级缓存是 SqlSession 级别的缓存,缓存位于 SqlSession 中。同一个 SqlSession 中执行相同的 SQL 语句,结果会被缓存。一级缓存默认是开启的,在同一个 SqlSession 中,相同的 SQL 语句只会执行一次,后续的 SQL 语句直接从缓存中获取结果。一级缓存的生命周期与 SqlSession 的生命周期一致。

一级缓存失效场景

以下场景会清空一级缓存:

  1. 执行 commit 操作。
  2. 执行 rollback 操作。
  3. 执行 clearCache 方法。
  4. 创建新的 SqlSession

示例

SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);

User user1 = mapper.selectUserById(1);
sqlSession.clearCache();
User user2 = mapper.selectUserById(1);

// user1 和 user2 不同,因为清空了缓存
System.out.println(user1 == user2);

二级缓存工作原理

二级缓存简介

MyBatis 的二级缓存是 Mapper 级别的缓存,缓存位于所有 SqlSession 中,只要 Mapper 的 cacheEnabled 属性设置为 true,二级缓存就会启用。二级缓存默认是关闭的,可以通过配置文件或注解启用。

配置方式

在 Mapper XML 文件中启用二级缓存:

<mapper namespace="com.example.mapper.UserMapper">
    <cache/>
    <select id="selectAllUsers" resultType="com.example.entity.User">
        SELECT * FROM user
    </select>
</mapper>

或者在 Mapper 接口中启用二级缓存:

@CacheNamespace(flushCacheAtExecute=false, useCacheForCursors=false)
public interface UserMapper {
    @Select("SELECT * FROM user")
    List<User> selectAllUsers();
}

二级缓存失效场景

以下场景会清空二级缓存:

  1. 执行 commit 操作。
  2. 执行 rollback 操作。
  3. 执行 clearCache 方法。
  4. 改变配置文件中的二级缓存配置。

示例

SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);

User user1 = mapper1.selectUserById(1);

sqlSession1.close();

SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);

User user2 = mapper2.selectUserById(1);

// user1 和 user2 相同,因为使用了二级缓存
System.out.println(user1 == user2);

如何有效使用缓存

缓存策略

为了最大化地利用缓存,可以采取以下策略:

  1. 合理使用一级缓存:在同一个事务中,尽量重用同一 SqlSession 实例。
  2. 启用二级缓存:对于读取操作频繁的数据,可以通过配置文件或注解启用二级缓存。
  3. 合理设置缓存过期时间:对于缓存数据,可以设置缓存过期时间,避免缓存中的数据过于陈旧。
  4. 监控缓存命中率:通过 MyBatis 插件或第三方工具监控缓存命中率,及时调整缓存策略。
  5. 缓存与数据一致性:确保缓存中的数据与数据库中的数据保持一致,可以通过事务管理等方式实现。

示例

配置 MyBatis 插件来监控缓存命中率:

<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

    <plugins>
        <plugin interceptor="com.example.interceptor.CacheMonitorInterceptor">
            <property name="logger" value="mybatis.cache"/>
        </plugin>
    </plugins>
</configuration>

编写 MyBatis 插件来监控缓存命中率:

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.transaction.Transaction;

import org.apache.ibatis.executor.CachingExecutor;

public class CacheMonitorInterceptor implements org.apache.ibatis.plugin.Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArguments();
        Object result = invocation.proceed();

        Executor executor = (Executor) args[0];
        MappedStatement mappedStatement = (MappedStatement) args[1];
        Object parameter = args[2];
        BoundSql boundSql = mappedStatement.getBoundSql(parameter);

        if (executor instanceof CachingExecutor) {
            CachingExecutor cachingExecutor = (CachingExecutor) executor;
            boolean hit = cachingExecutor.hasCacheHit(mappedStatement, boundSql.getSql());
            Logger logger = LoggerFactory.getLogger("mybatis.cache");
            logger.info("Cache hit: {}", hit);
        }

        return result;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }
}
常见问题与调试技巧

常见错误及解决方法

错误1:ClassNotFoundException

问题描述:找不到指定的类或接口。

解决方法

  1. 检查项目依赖是否正确引入。
  2. 检查类路径是否正确。

错误2:SqlSessionFactoryBuilderException

问题描述:创建 SqlSessionFactory 时出现问题。

解决方法

  1. 检查 mybatis-config.xml 文件内容是否正确。
  2. 确保资源路径正确。

错误3:MapperException

问题描述:Mapper 接口或 XML 文件配置错误。

解决方法

  1. 检查 Mapper 接口和 XML 文件是否一致。
  2. 检查 XML 文件中的 SQL 语句是否正确。

错误4:IOException

问题描述:读取配置文件时出现异常。

解决方法

  1. 确保配置文件路径正确。
  2. 确保文件路径和文件名一致。

MyBatis调试技巧

使用MyBatis日志

MyBatis 支持多种日志框架,如 SLF4J、Log4j 等。可以通过配置文件启用日志输出,便于调试:

<configuration>
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
</configuration>

使用MyBatis插件

MyBatis 插件可以用于拦截 SQL 执行过程,方便调试和监控:

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

public class DebugInterceptor implements org.apache.ibatis.plugin.Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArguments();
        Object result = invocation.proceed();

        Executor executor = (Executor) args[0];
        MappedStatement mappedStatement = (MappedStatement) args[1];
        Object parameter = args[2];
        BoundSql boundSql = mappedStatement.getBoundSql(parameter);

        Logger logger = LoggerFactory.getLogger("mybatis.debug");
        logger.info("Executing SQL: {}", boundSql.getSql());

        return result;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }
}

使用IDEA插件

使用 IDEA 插件如 MyBatis Plus 插件,可以方便地在 IDE 中调试 MyBatis 代码。

性能优化基础

优化数据库查询

  1. 减少查询字段:只查询需要的字段,减少数据传输。
  2. 使用索引:为常用查询字段添加索引。
  3. 优化 SQL 语句:避免使用过多的子查询和嵌套查询。

优化MyBatis配置

  1. 开启缓存:合理使用一级缓存和二级缓存。
  2. 批量执行:使用批量插入、更新和删除操作。
  3. 异步提交:使用异步事务提交减少等待时间。

使用连接池

使用连接池如 C3P0、DBCP 等,可以有效地管理数据库连接,减少连接的创建和销毁。

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
    <property name="username" value="root"/>
    <property name="password" value="password"/>
    <property name="initialSize" value="5"/>
    <property name="maxActive" value="20"/>
</bean>

使用MyBatis插件

MyBatis 插件可以用于拦截 SQL 执行过程,根据需求进行优化,例如参数化查询、分页查询等。


import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

public class OptimizationInterceptor implements org.apache.ibatis.plugin.Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArguments();
        Object result = invocation.proceed();

        Executor executor = (Executor) args[0];
        MappedStatement mappedStatement = (MappedStatement) args[1];
        Object parameter = args[2];
        BoundSql boundSql = mappedStatement.getBoundSql(parameter);

        // 根据需求进行优化
        if (executor instanceof CachingExecutor) {
            CachingExecutor cachingExecutor = (CachingExecutor) executor;
            cachingExecutor.optimizeQuery(mappedStatement, boundSql.getSql());
        }

        return result;
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }
}
``

以上是 MyBatis 入门教程的内容,通过本教程,你可以了解 MyBatis 的基本概念、如何进行数据库操作、如何使用缓存机制以及如何进行调试和性能优化。希望这个教程能帮助你更好地掌握 MyBatis 技术。
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消