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

Mybatis持久层框架资料详解与入门教程

标签:
Java SSM 数据库
概述

MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,简化了数据库操作。本文将详细介绍MyBatis持久层框架,涵盖安装配置、核心概念、高级特性和基本使用,提供详细的代码示例和配置步骤,帮助读者更好地理解和使用MyBatis。

Mybatis简介与安装配置
Mybatis是什么

MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射。它避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口与数据库表进行映射,将Java方法与SQL语句绑定,提供了一种灵活且强大的持久层解决方案。其主要优势包括:

  • 简化SQL操作:MyBatis简化了数据库操作,尤其是对复杂SQL的支持,使开发者可以更加专注于SQL逻辑的编写。
  • 灵活的映射:支持自定义的SQL映射,能够更好地和数据库交互,支持存储过程和复杂查询。
  • 轻量级框架:相比Spring Data JPA等其他ORM框架,MyBatis的配置更简单,学习成本低。
  • 优秀的性能:MyBatis直接操作数据库,省去了一层ORM映射,性能更优。
  • 强大的动态SQL:支持动态SQL的使用,减少与数据库交互时的代码冗余。
  • 与Spring无缝集成:MyBatis可以很容易地与Spring框架集成,方便进行面向切面编程。
Mybatis环境搭建与配置

MyBatis环境搭建包括以下步骤:

  1. 创建Maven项目
  2. 引入MyBatis及数据库驱动依赖
  3. 创建数据库表和数据
  4. 创建MyBatis核心配置文件
  5. 创建Mapper接口和Mapper XML文件
  6. 编写测试用例

创建Maven项目

使用Maven创建一个新的Java项目。在项目的pom.xml文件中添加MyBatis和数据库驱动的依赖:

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.23</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.7.0</version>
        <scope>test</scope>
    </dependency>
</dependencies>

创建数据库表和数据

创建一个简单的数据库表,例如一个用户表user

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

向表中插入一些数据:

INSERT INTO `user` (`username`, `password`) VALUES ('admin', '123456');
INSERT INTO `user` (`username`, `password`) VALUES ('user1', 'password1');
INSERT INTO `user` (`username`, `password`) VALUES ('user2', 'password2');

创建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/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>
    <typeAliases>
        <typeAlias type="com.example.model.User" alias="User"/>
    </typeAliases>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

创建Mapper接口和Mapper XML文件

定义一个Java接口UserMapper,该接口包含数据库操作的定义:

package com.example.mapper;

import com.example.model.User;

public interface UserMapper {
    User selectUser(String username);
    void insertUser(User user);
    void updateUser(User user);
    void deleteUser(int id);
}

针对该接口编写一个XML映射文件UserMapper.xml,在该文件中定义SQL语句:

<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectUser" resultType="com.example.model.User">
        SELECT * FROM user WHERE username = #{username}
    </select>

    <insert id="insertUser">
        INSERT INTO user (username, password) VALUES (#{username}, #{password})
    </insert>

    <update id="updateUser">
        UPDATE user SET password = #{password} WHERE id = #{id}
    </update>

    <delete id="deleteUser">
        DELETE FROM user WHERE id = #{id}
    </delete>
</mapper>

编写测试用例

编写测试用例以验证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 org.junit.jupiter.api.Test;

import java.io.InputStream;
import java.util.List;

public class MyBatisTest {
    @Test
    public void testMyBatis() throws Exception {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            List<User> users = mapper.selectAllUsers();
            for (User user : users) {
                System.out.println(user);
            }
        }
    }
}
Mybatis核心概念
SqlSession和SqlSessionFactory

SqlSession是MyBatis提供的持久层操作对象,它封装了数据库连接、执行SQL语句等操作。SqlSessionFactory是SqlSession的工厂类,使用SqlSessionFactory来创建SqlSession对象。SqlSessionFactory通过解析数据库配置文件(如mybatis-config.xml)初始化,并创建SqlSession对象。创建SqlSessionFactory的代码如下:

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession对象用于执行数据库操作,如增删改查等。SqlSession在使用完毕后需要关闭,以释放数据库资源:

try (SqlSession session = sqlSessionFactory.openSession()) {
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> users = mapper.selectAllUsers();
    for (User user : users) {
        System.out.println(user);
    }
}
Mapper接口与Mapper XML文件

Mapper接口是MyBatis的业务映射接口,它定义了数据库操作的Java接口。Mapper XML文件则定义了具体的SQL语句,这些SQL语句与Mapper接口中的方法一一对应。Mapper XML文件中定义了SQL语句的ID(即Mapper接口中的方法名),以及SQL语句本身。

Mapper接口示例

定义一个用户操作的Mapper接口:

public interface UserMapper {
    User selectUser(int id);
    void insertUser(User user);
    void updateUser(User user);
    void deleteUser(int id);
}

Mapper XML文件示例

为Mapper接口编写对应的Mapper XML文件:

<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectUser" resultType="com.example.model.User">
        SELECT * FROM user WHERE id = #{id}
    </select>

    <insert id="insertUser">
        INSERT INTO user (id, username, password) VALUES (#{id}, #{username}, #{password})
    </insert>

    <update id="updateUser">
        UPDATE user SET password = #{password} WHERE id = #{id}
    </update>

    <delete id="deleteUser">
        DELETE FROM user WHERE id = #{id}
    </delete>
</mapper>
Pojo对象与结果映射

Pojo对象即普通的JavaBean对象,用于封装数据库中的数据。MyBatis通过结果映射将查询结果映射到Pojo对象上。结果映射定义了数据库字段与Pojo对象属性之间的对应关系。结果映射可以在XML配置文件中定义,也可以在注解中定义。

Pojo对象示例

定义一个User Pojo对象:

public class User {
    private int id;
    private String username;
    private String password;
    // 省略getters和setters
}

结果映射示例

在Mapper XML文件中定义结果映射:

<mapper namespace="com.example.mapper.UserMapper">
    <resultMap id="UserResultMap" type="com.example.model.User">
        <id column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
    </resultMap>

    <select id="selectUser" resultMap="UserResultMap">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>
Mybatis的基本使用
CRUD操作的实现

CRUD操作指的是数据库的基本操作:创建(Create)、读取(Read)、更新(Update)和删除(Delete)。

创建(Insert)

定义插入用户的方法:

public interface UserMapper {
    void insertUser(User user);
}

在Mapper XML文件中定义对应的插入SQL:

<insert id="insertUser">
    INSERT INTO user (id, username, password) VALUES (#{id}, #{username}, #{password})
</insert>

读取(Select)

定义查询用户的方法:

public interface UserMapper {
    User selectUser(int id);
}

在Mapper XML文件中定义对应的查询SQL:

<select id="selectUser" resultType="com.example.model.User">
    SELECT * FROM user WHERE id = #{id}
</select>

更新(Update)

定义更新用户的方法:

public interface UserMapper {
    void updateUser(User user);
}

在Mapper XML文件中定义对应的更新SQL:

<update id="updateUser">
    UPDATE user SET username = #{username}, password = #{password} WHERE id = #{id}
</update>

删除(Delete)

定义删除用户的方法:

public interface UserMapper {
    void deleteUser(int id);
}

在Mapper XML文件中定义对应的删除SQL:

<delete id="deleteUser">
    DELETE FROM user WHERE id = #{id}
</delete>
参数传递与结果映射

MyBatis支持多种方式传递参数,包括基本类型、集合以及复杂对象。同时,MyBatis也支持在Mapper XML文件中定义结果映射,将查询结果映射到合适的Pojo对象上。

参数传递示例

定义一个查询用户的方法,该方法接受一个用户名参数:

public interface UserMapper {
    User selectUserByUsername(String username);
}

在Mapper XML文件中定义对应的查询SQL,使用#{username}来接收参数:

<select id="selectUserByUsername" resultType="com.example.model.User">
    SELECT * FROM user WHERE username = #{username}
</select>

结果映射示例

定义一个查询用户的方法,该方法返回多个用户对象的列表:

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

在Mapper XML文件中定义对应的查询SQL,并使用resultMap来映射查询结果:

<resultMap id="UserResultMap" type="com.example.model.User">
    <id column="id" property="id"/>
   .
    <result column="password" property="password"/>
</resultMap>

<select id="selectAllUsers" resultMap="UserResultMap">
    SELECT * FROM user
</select>
动态SQL的编写

动态SQL是在运行时根据条件生成SQL语句的能力。MyBatis提供了多种标签来支持动态SQL,如<if><choose><when><otherwise>等。

动态SQL示例

定义一个查询用户的方法,该方法根据传入的参数来决定查询条件:

public interface UserMapper {
    List<User> selectUsersByCondition(@Param("id") Integer id, @Param("username") String username);
}

在Mapper XML文件中使用<if>标签来实现动态SQL:

<select id="selectUsersByCondition" resultType="com.example.model.User">
    SELECT * FROM user
    <where>
        <if test="id != null">
            AND id = #{id}
        </if>
        <if test="username != null">
            AND username = #{username}
        </if>
    </where>
</select>
Mybatis的高级特性
分步查询与延迟加载

分步查询允许将查询分解成多个步骤执行,以减少数据库操作的复杂性。延迟加载则允许在需要时才加载某些数据,以提高性能。

分步查询示例

定义一个查询用户及其订单的方法:

public interface UserMapper {
    User selectUserWithOrders(int id);
}

在Mapper XML文件中定义多步查询:

<resultMap id="UserWithOrdersResultMap" type="com.example.model.User">
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="password" property="password"/>
    <collection property="orders" column="id" ofType="com.example.model.Order" select="selectOrderById"/>
</resultMap>

<select id="selectUserWithOrders" resultMap="UserWithOrdersResultMap">
    SELECT * FROM user WHERE id = #{id}
</select>

<select id="selectOrderById" resultType="com.example.model.Order">
    SELECT * FROM order WHERE user_id = #{id}
</select>
一级缓存与二级缓存

缓存机制可以提高查询性能,减少数据库的访问次数。MyBatis提供了一级缓存和二级缓存两种缓存机制。

一级缓存

一级缓存是SqlSession级别的缓存,当执行任何查询时,MyBatis会将查询结果缓存到SqlSession中。如果再次执行相同的查询,MyBatis会直接从缓存中返回结果,而不会执行查询。

二级缓存

二级缓存是Mapper级别的缓存,可以跨多个SqlSession共享。如果多个SqlSession执行相同的查询,二级缓存可以避免重复查询数据库。

开启二级缓存

mybatis-config.xml配置文件中开启二级缓存,并在每个Mapper XML文件中启用缓存:

<cache/>

缓存示例

定义一个查询用户的方法:

public interface UserMapper {
    User selectUser(int id);
}

在Mapper XML文件中启用缓存:

<cache/>
<select id="selectUser" resultType="com.example.model.User">
    SELECT * FROM user WHERE id = #{id}
</select>
插件开发与使用

MyBatis提供了插件开发接口,可以用于拦截数据库操作,例如日志记录、性能监控等。

插件开发示例

定义一个插件类,该插件会拦截所有的SQL执行,并在执行前添加日志记录:

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;

import java.util.Properties;

@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class MyPlugin implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取执行的SQL信息
        Object target = invocation.getTarget();
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        BoundSql boundSql = mappedStatement.getBoundSql(invocation.getArgs()[1]);
        String sql = mappedStatement.getSql();
        // 打印日志
        System.out.println("Executing SQL: " + sql);
        // 执行原方法
        return invocation.proceed();
    }

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

    @Override
    public void setProperties(Properties properties) {
        // 设置插件属性
    }
}

然后在mybatis-config.xml配置文件中配置插件:

<plugins>
    <plugin interceptor="com.example.plugin.MyPlugin"/>
</plugins>
Mybatis的事务管理
事务概述与配置

事务是数据库操作中的一个重要概念,它保证了数据的一致性和完整性。MyBatis支持自动提交和手动提交两种事务管理方式。

自动提交

MyBatis默认使用自动提交模式,即每个SQL操作都会自动提交到数据库。

手动提交

可以通过SqlSession的commitrollback方法来手动控制事务的提交和回滚。

配置自动提交

mybatis-config.xml配置文件中,设置<settings>标签来配置自动提交:

<settings>
    <setting name="defaultAutoCommit" value="false"/>
</settings>

手动提交示例

在代码中手动管理事务:

try (SqlSession session = sqlSessionFactory.openSession(false)) {
    UserMapper mapper = session.getMapper(UserMapper.class);
    mapper.insertUser(new User());
    mapper.updateUser(new User());
    session.commit();
} catch (Exception e) {
    e.printStackTrace();
    try (SqlSession session = sqlSessionFactory.openSession(false)) {
        session.rollback();
    }
}
Spring整合Mybatis事务管理

Spring框架提供了强大的事务管理功能,可以与MyBatis无缝集成,实现更灵活的事务控制。

配置Spring事务管理

在Spring配置文件中,使用<tx:annotation-driven>标签开启基于注解的事务管理,并配置<bean>标签来定义事务管理器:

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

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

使用注解管理事务

在需要事务管理的方法上使用@Transactional注解:

import org.springframework.transaction.annotation.Transactional;

public class UserService {
    @Autowired
    private UserMapper userMapper;

    @Transactional
    public void addUser(User user) {
        userMapper.insertUser(user);
    }
}
事务异常处理

当事务处理过程中发生异常时,需要捕获并处理这些异常,以确保事务的正确性。

异常处理示例

定义一个事务处理方法,并在该方法中捕获异常:

public void addUser(User user) throws Exception {
    try {
        userMapper.insertUser(user);
    } catch (Exception e) {
        throw new RuntimeException("Failed to add user", e);
    }
}
Mybatis的优化与调试
性能优化技巧

性能优化是提高系统运行效率的重要手段,MyBatis提供了多种优化手段,包括缓存、批处理、预编译等。

缓存

通过开启一级缓存和二级缓存,可以减少数据库查询次数,提高系统性能。

批处理

当需要执行大量插入或更新操作时,可以使用批处理技术,以减少数据库交互次数。

预编译

通过预编译SQL语句,可以减少数据库解析SQL的时间,提高执行效率。

批处理示例

定义一个插入用户的批处理方法:

public void batchInsertUsers(List<User> users) {
    try (SqlSession session = sqlSessionFactory.openSession()) {
        UserMapper mapper = session.getMapper(UserMapper.class);
        for (User user : users) {
            mapper.insertUser(user);
        }
        session.commit();
    }
}
常见问题与调试方法

调试是解决程序问题的重要手段,MyBatis提供了多种调试工具和方法来帮助定位问题。

日志输出

通过配置日志输出,可以在控制台或日志文件中查看详细的SQL执行信息。

日志配置示例

mybatis-config.xml配置文件中配置日志输出:

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

异常捕获

通过捕获和分析异常信息,可以快速定位程序中的问题所在。

异常捕获示例

捕获并处理数据库操作异常:

try (SqlSession session = sqlSessionFactory.openSession()) {
    UserMapper mapper = session.getMapper(UserMapper.class);
    mapper.insertUser(new User());
} catch (Exception e) {
    e.printStackTrace();
}
日志配置与查看

MyBatis提供了多种日志框架的支持,如Log4j、SLF4J等,可以配置日志输出以帮助调试。

配置Log4j日志

log4j.properties配置文件中配置日志输出:

log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

配置SLF4J日志

logback.xml配置文件中配置日志输出:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

通过这些配置,可以详细查看MyBatis的执行信息,从而更好地进行调试和优化。

点击查看更多内容
TA 点赞

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

评论

作者其他优质文章

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

100积分直接送

付费专栏免费学

大额优惠券免费领

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

举报

0/150
提交
取消