1.1、环境准备

1、搭建实验数据库

-- 创建数据库
CREATE DATABASE `mybatis`;

-- 使用数据库
USE `mybatis`;

-- 创建用户表
CREATE TABLE `user`(
	`id` INT(15) NOT NULL PRIMARY KEY AUTO_INCREMENT,
	`username` VARCHAR(16) NOT NULL COMMENT '用户名',
	`password` VARCHAR(32) NOT NULL COMMENT '密码',
	`sex` CHAR(6) DEFAULT NULL COMMENT '性别',
  	`birthday` DATETIME DEFAULT NULL COMMENT '生日',
  	`address` VARCHAR(256) DEFAULT NULL COMMENT '地址'
)ENGINE INNODB DEFAULT CHARSET=utf8;

-- 插入测试数据
INSERT INTO `user`(`id`, `username`, `password`, `sex`, `birthday`, `address`) VALUES
(1, '陌玥雪', 'm123456', '女', '1998-09-14 15:21:50', '贵阳市-南明区'),
(2, '苏瑞韩', 's653249', '男', '2000-03-22 19:39:22', '贵阳市-云岩区'),
(3, '林念彤', 'l758973', '女', '1999-10-01 08:33:38', '遵义市-汇川区'),
(4, '尹心蕾', 'y358977', '女', '2005-12-09 13:45:26', '遵义市-播州区'),
(5, '温宇漠', 'w658948', '男', '2003-06-13 17:44:25', '贵阳市-花溪区')

在这里插入图片描述

2、新建项目

  • 新建一个普通的Maven项目
  • 导入Maven依赖
<!-- 导入依赖 -->
<dependencies>
    <!-- 导入Mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.5</version>
    </dependency>
    <!-- 导入MySQL驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.20</version>
    </dependency>
    <!-- 导入junit单元测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
</dependencies>

1.2、编写代码

1、在resources目录下创建Mybatis的核心配置文件SqlMapConfig.xml

  • 编写Mybatis的核心配置文件SqlMapConfig.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">
<!-- Mybatis的核心配置文件 -->
<configuration>
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql环境 -->
        <environment id="mysql">
            <!-- 配置事务类型 -->
            <transactionManager type="JDBC"/>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=ture&amp;characterEncoding=UTF-8&amp;serverTimezone=GMT%2B8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 每一个Mapper.xml配置文件都需要在Mybatis的核心配置文件中注册 -->
    <mappers>
        <mapper resource="com/mybatis/dao/UserMapper.xml"/>
    </mappers>
</configuration>
  • 注意事项

    • 数据库名称、用户名、密码改为自己的;
    • 指定Mapper.xml映射配置文件的位置,映射配置文件指的是每个Dao/Mapper接口的独立的配置文件;
    • Mapper.xml映射配置文件为1.2.5创建的UserMapper.xml文件。

2、创建并编写Mybatis工具类(用于获取 SqlSession 的实例)

public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            // 1、读取配置文件,生成字节输入流
            InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
            // 2、获取SqlSessionFactory
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从 SqlSessionFactory中获取 SqlSession 的实例
     * SqlSession 提供了在数据库执行 SQL 命令所需的所有方法
     * @return
     */
    public static SqlSession getSqlSession() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }
}

3、创建并编写实体类

/**
 * 用户实体类
 */
public class User {
    private Integer id;
    private String username;
    private String password;
    private String sex;
    private Date birthday;
    private String address;

    public User() {
    }

    public User(Integer id, String username, String password, String sex, Date birthday, String address) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.sex = sex;
        this.birthday = birthday;
        this.address = address;
    }

    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 getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + birthday +
                ", address='" + address + '\'' +
                '}';
    }
}

4、创建并编写UserDao接口类

/**
 * 用户持久层
 */
public interface UserDao {
    /**
     * 查询所有用户信息
     * @return
     */
    List<User> findAll();
}

5、创建并编写UserMapper.xml配置文件(选择以下两种方式其中一种即可)

  • 方式一:

    • 在resources目录下建一个与java目录下同包名的目录结构com/mybatis/dao,在其新建的dao包下新建一个UserMapper.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">
      <!-- namespace属性绑定一个对应的Dao/Mapper接口 -->
      <mapper namespace="com.mybatis.dao.UserDao">
          <!-- 查询所有用户信息,id为Dao/Mapper接口里的具体方法名 -->
          <select id="findAll" resultType="com.mybatis.pojo.User">
              select * from user
          </select>
      </mapper>
      
  • 方式二:

    • 在UserDao的同级包中新建一个UserMapper.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">
      <!-- namespace属性绑定一个对应的Dao/Mapper接口 -->
      <mapper namespace="com.mybatis.dao.UserDao">
          <!-- 查询所有用户信息,id为Dao/Mapper接口里的具体方法名 -->
          <select id="findAll" resultType="com.mybatis.pojo.User">
              select * from user
          </select>
      </mapper>
      
    • Maven静态资源过滤问题:在pom.xml中加入如下配置

      <!-- 在build中配置resource,防止资源导出失败问题 -->
      <build>
          <resources>
              <resource>
                  <directory>src/main/java</directory>
                  <includes>
                      <include>**/*.properties</include>
                      <include>**/*.xml</include>
                  </includes>
                  <filtering>false</filtering>
              </resource>
              <resource>
                  <directory>src/main/resources</directory>
                  <includes>
                      <include>**/*.properties</include>
                      <include>**/*.xml</include>
                  </includes>
                  <filtering>false</filtering>
              </resource>
          </resources>
      </build>
      
  • 注意事项:

    • Mapper.xm配置文件的mapper标签的namespace属性的取值为是Dao/Mapper接口的全限定类名;
    • Mapper.xm配置文件的操作配置标签(select、insert、delete、update)的id属性的取值为Dao/Mapper接口的具体方法名
    • Mapper.xm配置文件的操作配置标签(select、insert、delete、update)的resultType属性为实体类的全限定类名;
    • 方式二需解决Maven静态资源过滤问题,方式一不用。

1.3、测试

  • 使用junit单元测试

  • UserDaoTest单元测试类

    public class UserDaoTest {
    
        @Test
        public void findAll() {
            // 1、获取SqlSession对象
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            // 2、获取UserDao的代理对象
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            // 3、执行查询方法
            List<User> users = userDao.findAll();
            // 4、打印查询结果
            for(User user: users) {
                System.out.println(user);
            }
            // 5、释放资源
            sqlSession.close();
        }
    }
    
  • 执行结果

    在这里插入图片描述

1.4、为什么获取到 SqlSessionFactory 对象后不需要手动关闭 inputStream 输入流?

  • 源码分析:

    • 读取配置文件,生成字节输入流

      InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
      
    • 调用 SqlSessionFactoryBuilder 对象的 build(inputStream) 方法;

      sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      
    • 由build(InputStream inputStream)方法的返回值可以看出继续调用build((InputStream)inputStream, (String)null, (Properties)null);

      public SqlSessionFactory build(InputStream inputStream) {
              return this.build((InputStream)inputStream, (String)null, (Properties)null);
          }
      
    • 由build(InputStream inputStream, String environment, Properties properties)方法可以看出在 finally 代码块中已经将inputStream 输入流关闭掉;

      public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
              SqlSessionFactory var5;
              try {
                  XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
                  var5 = this.build(parser.parse());
              } catch (Exception var14) {
                  throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
              } finally {
                  ErrorContext.instance().reset();
      
                  try {
                      inputStream.close();
                  } catch (IOException var13) {
                  }
      
              }
      
              return var5;
          }
      
    • 所以我们不需要自己手动关闭 inputStream 输入流。

Q.E.D.


Keep going, believe in yourself, and never give up.