11.1 MyBatis基础(上)



本章将围绕遇到的第一个框架:MyBatis框架展开介绍,分为基础入门、进阶特性。

一、本周内容

1.1 基础入门

1.2 进阶特性

二、MyBatis框架介绍

2.1 框架的作用

Framework

1.生活场景

建筑领域中的框架:梁柱骨架

计算机硬件领域中的框架:主板结构

2.软件开发中的框架

(1)框架就是被开发者定制的应用骨架---------------------------------提高开发效率

(2)框架就是一种规则,保证开发者遵循相同方式开发程序------利于团队管理

(3)框架对基础功能都有封装,提倡“不要重复造轮子”-------------提高开发效率

(4)灵活配置的应用-----------------------------------------------------------维护性好

3.大名鼎鼎的SSM框架

2.2 MyBatis框架

1.特点

(1)优秀的持久层的框架

(2)通过XML,将SQL语句与程序解耦,利于维护

(3)简单高效,是JDBC的延申

MyBatis框架的底层仍是JDBC,只不过进行了封装和拓展

持久:

就是将内存中的数据,保存到数据库中,防止重启后数据丢失

2.官方文档

2.3 MyBatis框架的开发流程:六步

分六步:

(1)引入MyBatis依赖

(2)创建核心配置文件

(3)创建实体(Entity)类(也叫域对象,POJO简单对象)

(4)创建Mapper映射文件

(5)初始化SessionFactory(也叫会话工厂)

(6)利用SqlSession对象操作数据

三、单元测试、JUnit4

3.1 单元测试

1.必要性

所有类对外体现的行为,都是一个一个的方法。但是,如何确保开发的方法能够按照预期,正常运行且没有错误呢?

以前:在main主方法中调用检查-----低级

现在:应该用测试用例方式------------推荐

2.测试用例

测试用例就是专门用于测试方法(功能)的方法

3.单元测试工具

Java中最著名的单元测试工具:JUnit4,主流IDE内置支持

3.2 工具JUnit4的使用方法

(1)逐个引入JUnit包,或基于Maven管理依赖

(2)编写测试用例,验证目标方法是否正确运行

(3)在测试用例上增加@Test注解,开始单元测试

3.3 案例演示

1.引入JUnit包的方式

官网下载JUnit包

将JUnit包及其依赖包(共两个),复制到工程中,并引入到工程依赖:

快捷键Ctrl+N,查找验证下:

上述比较麻烦,因为如果依赖一多还得一个一个的下载、引入。

2.基于Maven管理依赖的方式

创建Maven工程:

实现Enable Auto-import:

在刚自动生成的配置文件pom.xml中:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.imooc</groupId>
    <artifactId>maven-junit4</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--1.增加阿里云镜像-->
    <repositories>
        <repository>
            <id>aliyun</id>
            <name>aliyun</name>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>
    </repositories>

    <!--2.增加单元测试工具junit4依赖-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

以上是增加依赖的两种方式。推荐使用第二种方式。

3.模仿一个真实应用:

  • 在源代码Calculator.java中:
public class Calculator {
    // 加法运算
    public int add(int a, int b) {
        return a + b;
    }

    // 减法运算
    public int subtract(int a, int b) {
        return a - b;
    }

    // 乘法运算
    public int multiply(int a, int b) {
        return a * b;
    }

    // 除法运算
    public int divide(int a, int b) {
        return a / b;
    }
}
  • 编写加法的测试用例:

​ 在测试代码CalcualtorTest.java中:

public class CalcualtorTest {

    private Calculator cal = new Calculator();
    // 测试用例的方法名,命名习惯:
    // 1.与原方法保持一致
    // 2.在原方法前,增加test前缀
    @Test
    public void testAdd() {
        int result = cal.add(1, 2);
        System.out.println(result);
    }
}
  • 对单个测试用例方法进行校验:选中被测试的方法名,右键,运行即可:

4.对类下所有的测试用例进行校验:

选中被测试的类名,右键,运行即可:

在测试代码CalcualtorTest.java中:

public class CalcualtorTest {

    private Calculator cal = new Calculator();
    @Test
    public void testAdd() {
        int result = cal.add(1, 2);
        System.out.println(result);
    }

    @Test
    public void testSubtract() {
        int result = cal.subtract(1, 2);
        System.out.println(result);
    }

    @Test
    public void testMultiply() {
        int result = cal.multiply(1, 2);
        System.out.println(result);
    }

    @Test
    public void testDivide() {
        int result = cal.divide(1, 2);        // 1/2 = 0 ? 因为被除数、除数都是整型,会自动向下求整
        System.out.println(result);
    }
}

上述测试用例成功执行。

5.成功执行不等于正确执行

比如除法中1/2=0的例子,确实执行成功,但是执行的结果不对啊。

改正:

  • 在源代码Calculator.java中:
package com.imooc.junit;

public class Calculator {
    // 除法运算
    public float divide(int a, int b) {
        return (a*1f) / b;                    // 让被除数变为浮点数
    }
}
  • 在测试代码CalcualtorTest.java中:
public class CalcualtorTest {

    private Calculator cal = new Calculator();
    @Test
    public void testDivide() {
        float result = cal.divide(1, 2);
        System.out.println(result);
    }
}
--->
0.5                // 商对,运行正确

由此可见:

对勾和叉号,不是执行成败的唯一依据。而是要看,程序执行结果与预期执行结果是否相符。

比如:下面虽然出现叉号,但是执行结果是满足预期的:

3.4 快速生成测试用例的结构

1.步骤如下:

成功的快速生成了某个类的所有测试用例:

具体的细节,自己填充就好

2.同时运行多个测试类

同理,如果想运行整个工程下所有的测试用例,那就选中工程名,右键,运行即可。

四、MyBatis基本使用

4.1 MyBatis环境配置

1.语法

约定俗成,用mybatis-config.xml来保存关于数据库的环境配置信息

用标签<environment>,包含数据库驱动、URL、用户名、密码

2.准备:基于Maven管理依赖:

将MyBatis依赖加入:

将JDBC驱动类加入:

3.准备:导入演示用的数据库、数据表:

便捷工具,可作为MySql客户端来使用:这是IDEA内置的数据库客户端,支持MySql。

第一次要下载驱动,然后点击测试连接,连接成功之后,OK。

加载已有的建库脚本:

即可成功导入演示用的数据库、数据表。

当然,还可以在这里的控制台,写SQL语句:

由此可见,

IDEA内置的数据库客户端,不仅书写命令比MySQL自带的命令行,有智能提示,方便的多。而且,这与IDEA整合在一起,不用下载很多软件。

4.编写数据库的环境配置信息

将数据库驱动、URL、用户名、密码放进来。

在配置文件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="dev">
        <!--开发环境-->
        <environment id="dev">
            <!--采用JDBC方式对数据库事务进行commit/rollback-->
            <transactionManager type="JDBC"></transactionManager>
            <!--采用连接池方式管理数据库连接-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/babytun?useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="1234abcd"/>
            </dataSource>
        </environment>

        <!--(线上)生产环境-->
        <environment id="prd">
            <!--采用JDBC方式对数据库事务进行commit/rollback-->
            <transactionManager type="JDBC"></transactionManager>
            <!--采用连接池方式管理数据库连接-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://192.168.1.155:3306/babytun?useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="1234abcd"/>
            </dataSource>
        </environment>
        
    </environments>
</configuration>

4.2 创建SqlSessionFactory、SqlSession对象

1.SqlSessionFactory

(1)是MyBatis中最重要的一个全局对象,核心对象

(2)作为工厂方法,用于初始化MyBatis,创建SqlSession对象

(3)在应用中全局唯一

2.SqlSession对象

(1)使用JDBC的方式,与数据库交互

(2)提供了数据表CRUD对应方法

可以把SqlSession对象,视为一个扩展过的Connection数据库连接对象

3.加入单元测试的依赖组件

4.初始化SessionFactory加载成功:

// 单元测试类
public class MyBatisTestor {

    // 单元测试用例
    @Test
    public void testSqlSessionFactory() throws IOException {
            // 利用Reader加载classpath下的mybatis-config.xml核心配置文件
        Reader reader = Resources.getResourceAsReader("mybatis-config.xml");    // reader就包含了xml的文本信息
            // 初始化SqlSessionFactory,同时解析mybatis-config.xml文件
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);      //用的是构造者模式
        System.out.println("SessionFactory加载成功");

        SqlSession sqlSession = null;
        try {
            // 创建sqlSession对象,sqlSession是JDBC的扩展类,用于与数据交互
            sqlSession = sqlSessionFactory.openSession();
            // 创建数据库连接(测试用)
            Connection conn = sqlSession.getConnection();
            System.out.println(conn);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (sqlSession != null) {
                // 如果type="POOLED",代表使用连接池,close则是将连接回收到连接池中
                // 如果type="UNPOOLED",代表直连,close则会调用Connection.close方法关闭连接
                sqlSession.close();
            }
        }
    }
}

4.3 MyBatisUtils工具类

保证SqlSessionFactory类全局唯一

之前创建的,只是局限在一个实例方法中:如下:

现在,将其设为全局唯一:

在类MyBatisUtils.java中:

/**
 * 该类用于创建全局唯一的SqlSessionFactory对象
 */
public class MyBatisUtils {
    // static:静态,表示只属于类,不属于实例化对象
    private static SqlSessionFactory sqlSessionFactory = null;

    // 用于初始化静态对象
    static {
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ExceptionInInitializerError(e);           //把异常抛出去
        }
    }

    // 对于工具类,通常都用static修饰,类名.方法名,方便直接调用
    public static SqlSession openSession() {                   // 打开会话
        return sqlSessionFactory.openSession();
    }

    // 对于工具类,通常都用static修饰,类名.方法名,方便直接调用
    public static void closeSession(SqlSession sqlSession) {    // 关闭会话
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}
// 单元测试类
public class MyBatisTestor {

    // 单元测试用例
    @Test
    public void testMyBatisUtils(){
        SqlSession sqlSession = null;
        try {
            sqlSession = MyBatisUtils.openSession();            // 直接调用上述类方法,打开Session
            Connection connection = sqlSession.getConnection();
            System.out.println(connection);
        } catch (Exception e) {
            throw e;
        }finally {
            MyBatisUtils.closeSession(sqlSession);              // 直接调用上述类方法,关闭Session
        }
    }
}

成功创建了全局唯一的SqlSessionFactory:

声明:Jerry's Blog|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 11.1 MyBatis基础(上)


Follow excellence, and success will chase you.