MyBatis 3

环境

  • JDK 1.8
  • MySQL 8.0
  • Maven 3.6.3
  • IntelliJ IDEA 2020

知识

  • JDBC
  • MySQL
  • Java基础
  • Maven
  • JUnit

1、简介

1.1、什么是MyBatis

【MyBatis】一、简介及入门_sql

  • 基于Java的持久层框架
  • 支持自定义 SQL、存储过程以及高级映射;
  • 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作;
  • 可以通过简单的 XML 或注解来配置和映射原生类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  • 本是apache的一个开源项目iBatis,2010年由apache software foundation 迁移到了google code,改名为MyBatis 。2013年11月迁移到Github。

获得MyBatis

1.2、持久化

数据持久化

  • 包括和数据库相关的各种操作(保存、更新、删除、加载、查询)
  • 内存中的数据模型存储模型之间的相互转换;

优点

  1. 代码重用性强:即使更换数据库,只需要更改配置文件,不必重写程序代码。

  2. 代码可读性强:在代码中不会有大量的SQL语言,提高程序的可读性。

  3. 缓存:持久化技术可以自动优化,以减少对数据库的访问量,提高程序运行效率。

持久层

  • 完成持久化工作的代码块。

1.3、为什么需要MyBatis

  • 简单易学,没有任何第三方依赖;
  • 灵活:SQL写在xml里,便于统一管理和优化;
  • SQL和代码分离,提高了可维护性;
  • 提供映射标签,支持对象与数据库的ORM字段关系映射;
  • 提供对象关系映射标签,支持对象关系组建维护;
  • 提供xml标签,支持编写动态sql。

2、入门:第一个MyBatis

2.1、搭建环境

创建数据库

【MyBatis】一、简介及入门_xml_02

搭建项目

  1. 新建一个不带模板的Maven项目;
  2. 删除src目录,将该工程作为项目的父工程;
  3. 导入Maven依赖:
<dependencies>

    <!-- 数据库连接 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.23</version>
    </dependency>
    <!-- MyBatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <!--JUnit-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

</dependencies>

2.2、创建模块

在父工程下新建Module,作为父工程的子模块。

MyBatis配置文件

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="数据库驱动"/>
        <property name="url" value="数据库URL?参数"/>
        <property name="username" value="用户名"/>
        <property name="password" value="密码"/>
      </dataSource>
    </environment>
  </environments>
  <!-- 如果Mapper.xml等配置文件不在resources目录下,需要注册,注意用/分隔 -->
  <mappers>
	<mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

MyBatis工具类

  • 用于构建SqlSessionFactory,从而创建构建SqlSession实例。

  • SqlSession相当于JDBC中的PreparedStatement,提供了数据库执行 SQL 命令所需的方法。

注意sqlSessionFactory提升作用域后,如果静态代码块中的sqlSessionFactory重新声明,最高级作用域(代码块外面的)的sqlSessionFactory没有赋值,会报NPE。

public class MyBatisUtils {

    static SqlSessionFactory sqlSessionFactory;
    
    // 从XML中构建SqlSessionFactory
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            // 错误写法,报NPE: SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {	
            e.printStackTrace();
        }
    }

    /**
     * 获取SqlSession实例
     *
     * @return SqlSession实例
     */
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}*
     * @return SqlSession实例
     */
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

2.3、编写代码

实体类

ORM原则

/**
 * ID:数据库字段自动生成,无需手动设置
 */
private Long id;
/**
 * 名称
 */
private String name;
/**
 * 密码
 */
private String password;

DAO

  • 通常用Mapper表示,UserMapper即原来的UserDAO
public interface UserMapper {
    /**
     * 查询所有用户
     *
     * @return 用户列表
     */
    List<User> listUsers();
}

DAO实现

  • 使用Mapper.xml配置文件,代替原来的DAOImpl

  • 通常与接口放在一起,写完要去MyBatis配置文件中注册。

<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 映射:接口绑定,相当于实现接口 -->
<mapper namespace="indi.jaywee.dao.UserMapper">
    <!--
    相当于重写方法
    id:重写的方法名;
    resultType:返回结果类型,全类名
    -->
    <select id="listUsers" resultType="indi.jaywee.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

2.4、JUnit测试

public class UserMapperTest {
    @Test
    public void testListUsers(){
        // 获取SqlSession实例
        SqlSession sqlSession = MyBatisUtils.getSqlSession();

        // 获取Mapper
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        // 执行方法
        List<User> users = mapper.listUsers();

        for (User user : users) {
            System.out.println(user);
        }

        // 关闭连接
        sqlSession.close();
    }
}

2.5、常见报错

java.lang.NullPointerException at indi.jaywee.utils.MyBatisUtils.getSqlSession

  • 错误:sqlSessionFactory是空值,调用getSqlSession()自然就会报空指针。
  • 解决:查看工具类MyBatisUtils的静态代码中的SqlSessionFactory,将声明去掉。
static SqlSessionFactory sqlSessionFactory;

// 从XML中构建SqlSessionFactory
static {
    try {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 错误写法:SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

java.io.IOException: Could not find resource resources/mybatis-config.xml

  • 错误:找不到MyBatis的配置文件,说明工具类中的resource路径有误。

  • 解决:查看工具类MyBatisUtils中的resource变量值,修改为正确路径。

org.apache.ibatis.binding.BindingException: Type interface indi.jaywee.dao.UserMapper is not known to the MapperRegistry.

  • 错误:Mapper没有注册。
  • 解决:在MyBatis的配置文件中注册,注意路径之间是用/分隔,否则也会报错。
<mappers>
	<mapper resource="indi/jaywee/dao/UserMapper.xml"></mapper>
</mappers>

java.lang.ExceptionInInitializerError

  • 错误:初始化失败,找不到Mapper.xml配置文件。

  • 说明:

    1. 标准的Maven项目都有resources目录来存放资源配置文件。Maven项目构建编译时,默认只会把resources目录下的资源配置文件导出到target目录中,而不会将其他目录下的资源配置文件导出。
    2. 在实际项目中,可能会把资源配置文件放在resources以外的位置。如MyBatis框架中一般把Mapper.xml和接口类放在一起。这些资源配置文件不会被导出到target文件夹,导致资源配置文件读取失败。
  • 解决:在项目的pom.xml中设置过滤,最好在每个新建的Maven项目都设置。

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

无效的2字节、3字节等问题

  • 编码问题:IDEA默认使用GBK对资源配置文件编码,而以上使用到的xml文件都是以UTF-8编码。在这个情况下,如果在xml文件中使用了中文注释会报此异常。
  • 解决:将IDEA的资源配置文件的字符编码集设为UTF-8。
  • 注意:跟修改Maven一样,只要是IDEA中修改设置,需要在进入项目前的小窗口设置,同时在进入项目后的设置中确认是否修改成功。

【MyBatis】一、简介及入门_配置文件_03


在完成项目模块的搭建之后,实体类工具类MyBatis配置文件一般不用变动,只需在Mapper接口和对应的Mapper.xml配置文件中编写代码。