MyBatis 详解(二)

发布于 2021-07-24  143 次阅读


准备工作

之前在 JavaWeb 基础(一) 中就说过要做啥准备工作,这里就不再次说明了。要新建一个不基于模板的 maven 项目,并添加下面的依赖。

<dependencies>
    <!--MySQL 数据库连接依赖-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.49</version>
    </dependency>
    <!--MyBatis 依赖-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    <!--单元测试依赖-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

第一个 MyBatis 程序

创建名为 mybatis 的数据库和名为 user 的数据库表并插入数据

CREATE DATABASE `mybatis`;
USE `mybatis`;
CREATE TABLE `user`(
`id` INT(20) NOT NULL PRIMARY KEY,
`name` VARCHAR(30) DEFAULT NULL,
`pwd` VARCHAR(30) DEFAULT NULL 
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user`(`id`,`name`,`pwd`) VALUES
(1,'Guest997',123456),
(2,'GUEST997',123456),
(3,'guest997',123456);

编写 MyBatis 核心配置文件

获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)。

<?xml version="1.0" encoding="UTF-8" ?>
<!--mybatis-config.xml-->
<!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="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

编写 MyBatis 工具类

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。(这一步其实就是帮我们连接和断开连接数据库,以及创建 SqlSession 对象方便我们执行 sql 语句)

package ml.guest997.util;

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;

public class MyBatisUtil {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

编写代码

POJO 层

package ml.guest997.pojo;

public class User {

    private int id;
    private String name;
    private String pwd;

    public User() {
    }

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public long getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", pwd='" + pwd + '\'' +
                '}';
    }
}

Mapper 层(相当于之前的 Dao 层)

注意:接口不能直接运行。但 MyBatis 运用了动态代理技术使得接口能运行起来。

package ml.guest997.mapper;

import ml.guest997.pojo.User;
import java.util.List;

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

注意:UserMapper.xml 自动实例化了 UserMapper 接口。(XML 文件名不一定要与接口类名相同,但是为了区别,建议是设置成一样的)sql 语句结尾不要写分号,因为有可能在后面需要拼接 sql 语句。

<?xml version="1.0" encoding="UTF-8" ?>
<!--UserMapper.xml-->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--必须指定命名空间,用于接口绑定-->
<mapper namespace="ml.guest997.mapper.UserMapper">
    <!--下面的参数设置必须与接口中的一一对应。id 就是接口中的方法名,而 resultType 是 sql 语句执行后的返回类型;如果返回的是对象类型,类属性名和数据库字段名必须相同。只有 select 语句有 resultType 属性-->
    <select id="getUserList" resultType="ml.guest997.pojo.User">
        select * from mybatis.user
    </select>
</mapper>

测试

maven 由于约定大于配置,配置文件如果不放在 resources 目录下,会无法被导出或者生效。在 pom.xml 文件中添加下面的代码即可解决这个问题。

<!--解决配置文件无法导出或生效的问题-->
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
                <include>**/*.properties</include>
            </includes>
        </resource>

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

由于 UserMapper.xml 文件中配置了操作数据库的 sql 语句,所以需要在 MyBatis 核心配置文件中添加下面的代码引入 UserMapper.xml 文件。

<!--每一个 Mapper.xml 文件都要在 MyBatis 核心配置文件中注册-->
<mappers>
    <mapper resource="ml/guest997/mapper/UserMapper.xml"/>
</mappers>

编写测试方法

package ml.guest997.mapper;

import ml.guest997.pojo.User;
import ml.guest997.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;

public class UserMapperTest {
    @Test
    public void getUserList(){
        //获取 SqlSession 对象
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        //通过 SqlSession 对象的 getMapper 方法获取一个 Mapper 接口后,就可以调用它的方法了。而 sql 语句是在 MyBatis 核心配置文件加载映射文件时就读取出来了,在需要时再传给 SqlSession 对象。
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.getUserList();
        for (User user : userList) {
            System.out.println(user);
        }
        sqlSession.close();
    }
}
/*结果为
User{id=1, name='Guest997', pwd='123456'}
User{id=2, name='GUEST997', pwd='123456'}
User{id=3, name='guest997', pwd='123456'}
*/