手记

Mybatis持久层框架学习入门教程

概述

Mybatis是一个优秀的持久层框架,支持自定义SQL、存储过程以及高级映射。本文将详细介绍Mybatis的环境搭建、核心概念、SQL映射文件的编写以及CRUD操作等内容。通过本文的学习,读者可以快速上手并掌握Mybatis的使用方法。

Mybatis简介与环境搭建
Mybatis概述

Mybatis是一个优秀的持久层框架,支持自定义SQL、存储过程以及高级映射。Mybatis可以配置成多种形式,如XML配置文件和注解。Mybatis提供了强大的动态SQL支持,使得编写复杂的SQL查询变得更加简单。

Mybatis通过一个易于使用的接口查询语言(SQL Maps)将Java代码与数据库查询映射起来,将Java对象与数据库记录集映射起来,通过这种映射,可以将对象逻辑与数据库查询逻辑进行分离。Mybatis提供了一个非常简单易用的API,可以将Java对象映射到数据库表中,也可以将Java对象映射到数据库查询结果中。

Mybatis的安装与配置

安装步骤

  1. 下载Mybatis的Jar包,可以从官网或者Maven仓库下载。
  2. 将Mybatis的Jar包添加到项目的类路径中。

Maven依赖配置

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

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <!-- 数据库驱动依赖,例如MySQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.23</version>
    </dependency>
</dependencies>

配置文件

Mybatis配置文件通常命名为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/test"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/>
    </mappers>
</configuration>
开发环境搭建

为了更好地学习Mybatis,我们需要搭建一个开发环境。以下是步骤:

  1. 创建一个新的Java项目。
  2. 添加Mybatis和数据库驱动依赖。
  3. 创建数据库表和数据。
  4. 创建映射文件和配置文件。
  5. 编写Java代码测试Mybatis。

创建数据库表

CREATE DATABASE test;
USE test;

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

创建映射文件

<?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.entity.User">
        SELECT id, name, age FROM user WHERE id = #{id}
    </select>
</mapper>

编写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 MybatisTest {
    public static void main(String[] args) {
        try (SqlSession session = createSqlSession()) {
            List<User> users = session.selectList("com.example.mapper.UserMapper.selectUser");
            users.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static SqlSession createSqlSession() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        return sqlSessionFactory.openSession();
    }
}

运行测试

运行以上代码,如果一切都配置正确,将输出数据库中的用户信息。

Mybatis核心概念与配置
SqlSessionFactory和SqlSession

SqlSessionFactory

SqlSessionFactory是Mybatis的核心,它负责创建SqlSession。SqlSessionFactory由SqlSessionFactoryBuilder构建,而SqlSessionFactoryBuilder通过解析Mybatis配置文件来构建SqlSessionFactory。

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

SqlSession

SqlSession用于执行数据库操作,它提供了对数据库的CRUD操作。每个线程都应该有一个独立的SqlSession实例,SqlSession实例不应被共享使用。

SqlSession session = sqlSessionFactory.openSession();

SqlSession示例

// 获取SqlSession实例
SqlSession session = sqlSessionFactory.openSession();
try {
    // 执行查询方法
    List<User> users = session.selectList("com.example.mapper.UserMapper.selectUser");
    // 输出结果
    users.forEach(user -> System.out.println(user));
} finally {
    // 释放资源
    session.close();
}
Mybatis配置文件详解

Mybatis配置文件mybatis-config.xml用于配置Mybatis的各种属性。以下是常用配置项的说明:

数据源配置

数据源配置通过<environments>标签进行配置。<environment>标签定义了一个环境,通常用于数据库环境切换。

<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/test"/>
            <property name="username" value="root"/>
            <property name="password" value="password"/>
        </dataSource>
    </environment>
</environments>

映射文件配置

通过<mappers>标签指定映射文件的位置。映射文件通常是XML格式,定义了SQL语句及其对应的Java方法。

<mappers>
    <mapper resource="com/example/mapper/UserMapper.xml"/>
</mappers>
使用Mapper接口

在Mybatis中,Mapper接口用于定义映射方法。这些方法通过注解或XML配置文件映射到SQL语句。

Mapper接口定义

public interface UserMapper {
    List<User> selectUser();
    User selectUserById(int id);
}

XML配置映射

<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectUser" resultType="com.example.entity.User">
        SELECT id, name, age FROM user
    </select>
    <select id="selectUserById" resultType="com.example.entity.User" parameterType="int">
        SELECT id, name, age FROM user WHERE id = #{id}
    </select>
</mapper>

注解配置映射

@Mapper
public interface UserMapper {
    @Select("SELECT id, name, age FROM user")
    List<User> selectUser();
    @Select("SELECT id, name, age FROM user WHERE id = #{id}")
    User selectUserById(int id);
}

代码示例

SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> users = mapper.selectUser();
    users.forEach(user -> System.out.println(user));
    User userById = mapper.selectUserById(1);
    System.out.println(userById);
} finally {
    session.close();
}
SQL映射文件的编写
编写基础的SQL映射文件

SQL映射文件结构

SQL映射文件通常定义在src/main/resources目录下,并使用mapper标签包裹。每个映射文件对应一个Mapper接口。

<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectUser" resultType="com.example.entity.User">
        SELECT id, name, age FROM user
    </select>
    <select id="selectUserById" resultType="com.example.entity.User" parameterType="int">
        SELECT id, name, age FROM user WHERE id = #{id}
    </select>
</mapper>

动态SQL编写

Mybatis提供了多种动态SQL标签,如<if>, <choose>, <when>, <otherwise>等,用于根据条件生成SQL语句。

示例

<select id="selectUserByCondition" resultType="com.example.entity.User">
    SELECT id, name, age FROM user
    <where>
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

Java代码示例

SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUserByCondition("John", 30);
    System.out.println(user);
} finally {
    session.close();
}
Mybatis的CRUD操作
基本的增删改查操作

插入操作

<insert id="insertUser" parameterType="com.example.entity.User">
    INSERT INTO user(name, age) VALUES(#{name}, #{age})
</insert>

Java代码示例

SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = new User(null, "Jane", 25);
    mapper.insertUser(user);
    session.commit();
} finally {
    session.close();
}

查询操作

<select id="selectUserById" resultType="com.example.entity.User" parameterType="int">
    SELECT id, name, age FROM user WHERE id = #{id}
</select>

Java代码示例

SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUserById(1);
    System.out.println(user);
} finally {
    session.close();
}

更新操作

<update id="updateUser" parameterType="com.example.entity.User">
    UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}
</update>

Java代码示例

SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = new User(1, "Jane Doe", 26);
    mapper.updateUser(user);
    session.commit();
} finally {
    session.close();
}

删除操作

<delete id="deleteUserById" parameterType="int">
    DELETE FROM user WHERE id = #{id}
</delete>

Java代码示例

SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    mapper.deleteUserById(1);
    session.commit();
} finally {
    session.close();
}
批量操作和事务控制

批量插入操作

<insert id="batchInsertUser" parameterType="com.example.entity.User">
    INSERT INTO user(name, age) VALUES(#{name}, #{age})
</insert>

Java代码示例

SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> users = Arrays.asList(
        new User(null, "Alice", 30),
        new User(null, "Bob", 31)
    );
    for (User user : users) {
        mapper.batchInsertUser(user);
    }
    session.commit();
} finally {
    session.close();
}

事务控制

事务控制通常在Service层进行。通过SqlSessioncommit()rollback()方法来控制事务。

示例

SqlSession session = sqlSessionFactory.openSession(true); // 自动提交事务
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = new User(null, "Alice", 30);
    mapper.insertUser(user);
    // 如果发生异常,事务将被回滚
    throw new RuntimeException("Error occurred");
} catch (Exception e) {
    session.rollback();
} finally {
    session.close();
}
结果集的映射与处理

结果集映射

Mybatis支持将查询结果映射到Java对象。通过resultType属性指定映射的目标类型。

<select id="selectUserById" resultType="com.example.entity.User" parameterType="int">
    SELECT id, name, age FROM user WHERE id = #{id}
</select>

结果集处理

Mybatis支持复杂的结果集处理,如嵌套结果集、结果集构造等。

示例

<resultMap id="UserResultMap" type="com.example.entity.User">
    <id property="id" column="user_id"/>
    <result property="name" column="user_name"/>
    <result property="age" column="user_age"/>
</resultMap>

<select id="selectUserById" resultMap="UserResultMap">
    SELECT user_id, user_name, user_age FROM user WHERE id = #{id}
</select>

Java代码示例

SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUserById(1);
    System.out.println(user);
} finally {
    session.close();
}
Mybatis的高级特性和插件
分页处理

分页插件集成

Mybatis支持通过插件的形式集成第三方分页插件,如PageHelper。

示例

<!-- mybatis配置文件 -->
<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <property name="helperDialect" value="mysql"/>
        <property name="reasonable" value="true"/>
    </plugin>
</plugins>

Java代码示例

SqlSession session = sqlSessionFactory.openSession();
try {
    PageHelper.startPage(1, 10); // 分页
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> users = mapper.selectAllUsers();
    PageInfo<User> pageInfo = new PageInfo<>(users);
    System.out.println(pageInfo);
} finally {
    session.close();
}
二级缓存

二级缓存配置

Mybatis支持基于缓存的查询结果集重用,可以通过配置实现二级缓存。

示例

<cache/>

Java代码示例

SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUserById(1);
    System.out.println(user);
    // 重新获取相同的对象,此时将使用缓存
    User userCache = mapper.selectUserById(1);
    System.out.println(userCache);
} finally {
    session.close();
}
插件开发

插件开发步骤

  1. 创建插件类,实现Interceptor接口。
  2. 配置插件,使用<plugins>标签在配置文件中注册插件。
  3. 在插件类中拦截Mybatis的SQL执行过程,执行自定义逻辑。

示例

public class MybatisPlugin implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 在SQL执行前后添加逻辑
        System.out.println("Before SQL execution");
        Object result = invocation.proceed();
        System.out.println("After SQL execution");
        return result;
    }

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

    @Override
    public void setProperties(Properties properties) {
        // 配置属性
    }
}

配置插件

<plugins>
    <plugin interceptor="com.example.plugin.MybatisPlugin"/>
</plugins>
与Spring框架的集成

集成步骤

  1. 在Spring配置文件中配置Mybatis的SqlSessionFactory。
  2. 使用SqlSessionFactory创建SqlSessionTemplate,供Spring管理。
  3. 在Service层注入SqlSessionTemplate,执行数据库操作。

示例

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg>
        <ref bean="sqlSessionFactory"/>
    </constructor-arg>
</bean>

Java代码示例

@Service
public class UserService {
    private final SqlSessionTemplate sqlSessionTemplate;

    @Autowired
    public UserService(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    public User selectUserById(int id) {
        return sqlSessionTemplate.selectOne("com.example.mapper.UserMapper.selectUserById", id);
    }
}
实践案例与常见问题解答
实战案例分析

示例案例

案例描述

假设我们需要实现一个简单的博客系统,用户可以注册、登录、发布文章、评论文章。

数据库设计

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=utf8;

CREATE TABLE `article` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `content` text NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `comment` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `article_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `content` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Mybatis配置和代码实现

<!-- 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/blog"/>
        <property name="username" value="root"/>
        <property name="password" value="password"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="com/example/mapper/UserMapper.xml"/>
    <mapper resource="com/example/mapper/ArticleMapper.xml"/>
    <mapper resource="com/example/mapper/CommentMapper.xml"/>
  </mappers>
</configuration>
<!-- UserMapper -->
<mapper namespace="com.example.mapper.UserMapper">
  <select id="selectUserByUsername" resultType="com.example.entity.User">
    SELECT id, username, password FROM user WHERE username = #{username}
  </select>
</mapper>
public interface UserMapper {
  @Select("SELECT id, username, password FROM user WHERE username = #{username}")
  User selectUserByUsername(String username);
}
<!-- ArticleMapper -->
<mapper namespace="com.example.mapper.ArticleMapper">
  <insert id="insertArticle" parameterType="com.example.entity.Article">
    INSERT INTO article(user_id, title, content) VALUES(#{userId}, #{title}, #{content})
  </insert>
</mapper>
public interface ArticleMapper {
  @Insert("INSERT INTO article(user_id, title, content) VALUES(#{userId}, #{title}, #{content})")
  void insertArticle(Article article);
}
<!-- CommentMapper -->
<mapper namespace="com.example.mapper.CommentMapper">
  <insert id="insertComment" parameterType="com.example.entity.Comment">
    INSERT INTO comment(article_id, user_id, content) VALUES(#{articleId}, #{userId}, #{content})
  </insert>
</mapper>
public interface CommentMapper {
  @Insert("INSERT INTO comment(article_id, user_id, content) VALUES(#{articleId}, #{userId}, #{content})")
  void insertComment(Comment comment);
}

Java代码实现

@Service
public class UserService {
    private final SqlSessionTemplate sqlSessionTemplate;

    @Autowired
    public UserService(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    public User selectUserByUsername(String username) {
        return sqlSessionTemplate.selectOne("com.example.mapper.UserMapper.selectUserByUsername", username);
    }
}

@Service
public class ArticleService {
    private final SqlSessionTemplate sqlSessionTemplate;

    @Autowired
    public ArticleService(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    public void insertArticle(Article article) {
        sqlSessionTemplate.insert("com.example.mapper.ArticleMapper.insertArticle", article);
    }
}

@Service
public class CommentService {
    private final SqlSessionTemplate sqlSessionTemplate;

    @Autowired
    public CommentService(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    public void insertComment(Comment comment) {
        sqlSessionTemplate.insert("com.example.mapper.CommentMapper.insertComment", comment);
    }
}
常见问题与解决方法

常见问题

  1. 查询结果为空。
  2. 数据库连接失败。
  3. SQL映射文件配置错误。
  4. 事务管理问题。
  5. 插件配置问题。

解决方法

  1. 查询结果为空:检查SQL语句是否正确,数据库中是否有数据,映射文件是否正确配置。
  2. 数据库连接失败:检查数据库连接信息是否正确,数据库是否启动。
  3. SQL映射文件配置错误:检查映射文件路径、SQL语句是否正确。
  4. 事务管理问题:确保在Service层中合理使用事务管理,如SqlSessioncommit()rollback()方法。
  5. 插件配置问题:检查插件类是否实现Interceptor接口,配置文件中是否正确注册插件。
性能优化技巧

优化方法

  1. 使用缓存:合理使用Mybatis的缓存机制,减少数据库访问次数。
  2. 分页插件:使用分页插件,实现高效分页查询。
  3. 批量操作:使用批量操作减少数据库交互次数。
  4. 数据库索引:合理设计数据库索引,提高查询性能。
  5. SQL优化:优化SQL语句,避免全表扫描。

示例代码

// 使用缓存
SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    User user = mapper.selectUserById(1);
    System.out.println(user);
    // 重新获取相同的对象,此时将使用缓存
    User userCache = mapper.selectUserById(1);
    System.out.println(userCache);
} finally {
    session.close();
}
// 使用分页插件
SqlSession session = sqlSessionFactory.openSession();
try {
    PageHelper.startPage(1, 10); // 分页
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> users = mapper.selectAllUsers();
    PageInfo<User> pageInfo = new PageInfo<>(users);
    System.out.println(pageInfo);
} finally {
    session.close();
}
// 批量操作
SqlSession session = sqlSessionFactory.openSession();
try {
    UserMapper mapper = session.getMapper(UserMapper.class);
    List<User> users = Arrays.asList(
        new User(null, "Alice", 30),
        new User(null, "Bob", 31)
    );
    for (User user : users) {
        mapper.insertUser(user);
    }
    session.commit();
} finally {
    session.close();
}

通过以上介绍,希望读者能够对Mybatis有一个全面的认识和了解,并在实际开发中灵活应用。

0人推荐
随时随地看视频
慕课网APP