• 【零基础入门MyBatis系列】第二篇——MyBatis入门程序


    一、基本流程

    1、使用 Navicat 创建 MySQL 数据库(powernode)的一张表(t_car)

    在这里插入图片描述
    并插入两条数据
    在这里插入图片描述
    2、在IDEA中创建一个空项目:

    • 第一步,配置JDK
    • 第二步,配置Maven的地址和本地仓库的地址
    • 第三步创建一个Maven的模块

    3、修改 pom.xml 文件

    • 确定打包方式:
    <packaging>jar</packaging>
    
    • 1
    • 添加mysql驱动和mybatis依赖
    <!--mybatis核心依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.10</version>
    </dependency>
    <!--mysql驱动依赖-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.30</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4、编写sql的映射文件,一张表对应一个 XxxMapper类 【完成对这张表操作语句的封装】

    <?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先随意写一个-->
    <mapper namespace="car">
        <!--insert sql:保存一个汽车信息-->
        <insert id="insertCar">
            insert into t_car
                (id,car_num,brand,guide_price,produce_time,car_type) 
            values
                (null,'102','丰田mirai',40.30,'2014-10-05','氢能源')
        </insert>
    </mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5、编写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="com.mysql.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/powernode"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <!--sql映射文件创建好之后,需要将该文件路径配置到这里-->
            <mapper resource="CarMapper.xml"/>
        </mappers>
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    6、编写Java程序的Mybatis代码【用一个类完成会话的创建与业务】

    package com.powernode.mybatis;
    
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.InputStream;
    
    public class MyBatisIntroductionTest {
        public static void main(String[] args) {
            // 1. 创建SqlSessionFactoryBuilder对象
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            // 2. 创建SqlSessionFactory对象
            InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
            // 3. 创建SqlSession对象
            SqlSession sqlSession = sqlSessionFactory.openSession();
            // 4. 执行sql
            int count = sqlSession.insert("insertCar"); // 这个"insertCar"必须是sql的id
            System.out.println("插入几条数据:" + count);
            // 5. 提交(mybatis默认采用的事务管理器是JDBC,默认是不提交的,需要手动提交。)
            sqlSession.commit();
            // 6. 关闭资源(只关闭是不会提交的)
            sqlSession.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 执行SQL语句是Java和数据库之间的一次会话,那么如何建立这个会话呢?
      (1)我们要创建SqlSessionFactoryBuilder类的对象,调用其build方法
      (2)build需要一个数据流作为参数,进而才能创建SqlSessionFactory的对象
    //可以采用两种方式来获取数据流
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); //mybatis内置的
    //第一种方法底层就是由第二种方法实现的
    InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatis-config.xml");
    
    • 1
    • 2
    • 3
    • 4

    (3)利用SqlSessionFactory对象去开启一个会话,用这个SqlSession的对象调用 XxxMapper.xml 中的方法,参数为方法的id,就可以执行指定的SQL语句了。

    • 执行结果刷新一下数据库就可以看到:
      在这里插入图片描述
    • 为什么第三条数据id不是 3呢?

    因为id我采用了自增的方式,在我第一次写 MyBatisIntroductionTest.java 时,没有手动提交。
    即没有写sqlSession.commit(),运行了两次,所以就出现了断码的现象

    • 难道不可以自动提交吗?

    是可以的,此处我选择的事务管理是 JDBC,JDBC事务默认是不提交的,需要手动提交。
    在这里插入图片描述

    7、入门程序完成代码【上述代码如果在会话出现异常以后不能回滚】

    package com.powernode.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;
    
    public class MyBatisCompleteCodeTest {
        public static void main(String[] args) {
            SqlSession sqlSession = null;
            try {
                // 1.创建SqlSessionFactoryBuilder对象
                SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
                // 2.创建SqlSessionFactory对象
                SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
                // 3.创建SqlSession对象
                sqlSession = sqlSessionFactory.openSession();
                // 4.执行SQL
                int count = sqlSession.insert("insertCar");
                System.out.println("更新了几条记录:" + count);
                // 5.提交
                sqlSession.commit();
            } catch (Exception e) {
                // 回滚
                if (sqlSession != null) {
                    sqlSession.rollback();
                }
                e.printStackTrace();
            } finally {
                // 6.关闭
                if (sqlSession != null) {
                    sqlSession.close();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    二、事务管理

    1、JDBC事务管理器:

    • MyBatis框架自己管理事务,采用原生的JDBC代码去管理事务
    conn.setAutoCommit(false); //开启事务
    ... 业务处理 ...
    conn.commit(); //手动提交事务
    
    • 1
    • 2
    • 3
    • 使用JDBC事务管理器的话,底层创建的事务管理器对象:JdbcTranscation对象

    在这里插入图片描述

    • 在我们调用sqlSessionFactory.openSession()方法是内部参数默认为false,如果传入了true,那么就不会开启事务

    2、MANAGED 事务管理器

    • 由其他容器负责处理事务,例如:Spring
    • 因为此时我们的项目中只有MyBatis,如果将事务管理设置为MANAGED就代表没有人来处理事务。
        <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/powernode"/>
                    <property name="username" value="root"/>
                    <property name="password" value="111111"/>
                </dataSource>
            </environment>
        </environments>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    三、单元测试

    • 我们可使用 junit 来进行测试,它是专门做单元测试的一个组件
    • 测试的过程中涉及两个概念:期望值、实际值【两者相同代表测试通过,否则就会产生报错】

    1、我们要将 junit 的依赖添加到当前项目的 pom.xml 文件中

    因为我们是通过Maven构建项目的,所以可以通过官网去查找依赖

    <!--添加junit依赖-->
    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
    	<groupId>junit</groupId>
    	<artifactId>junit</artifactId>
    	<version>4.13.2</version>
    	<scope>test</scope>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、编写单元测试类,一般都叫 XxxTest.java,每个方法都对应一个测试方法 public void test业务方法名()
    (1)业务类【完成加法和减法】

    public class MathService {
        public int sum(int num1, int num2){
            return num1 + num2;
        }
        public int sub(int num1, int num2) {
            return num1 - num2;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (2)测试类

    public class MathServiceTest{
    	@Test
    	public void testSum(){
    		//创建对象,调用我们要测试的方法
            MathService mathService = new MathService();
            //实际值与预期值
            int actual = mathService.sum(1,2);
            int expected = 3;
            //断言测试
            Assert.assertEquals(expected, actual);
    	}
    	@Test
    	public void testSub(){
    		//创建对象,调用我们要测试的方法
            MathService mathService = new MathService();
            //实际值与预期值
            int actual = mathService.sum(1,2);
            int expected = -1;
            //断言测试
            Assert.assertEquals(expected, actual);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3、如何运行测试类?

    • 在类上执行,会执行该测试类中所有的测试方法
    • 在方法上执行只执行当前的测试方法

    在这里插入图片描述

    四、集成日志

    • 我们通过引入日志框架来查看运行过程中的 sql 执行情况
    • mybatis 提供了一种标准的日志组件,需要在 mybatis-config.xml 中添加以下配置
    <settings>
      <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    看起来不是很直观,MyBatis 也集成了其他的日志组件,例如:log4j,logback等。【此处我们以logback框架为例】

    1、引入 logback 的依赖

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.11</version>
      <scope>test</scope>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、引入 logback 的核心配置文件【只能命名为 logback.xml或 logback-test.xml,只能放到根路径下】

    <?xml version="1.0" encoding="UTF-8"?>
    
    <configuration debug="false">
        <!-- 控制台输出 -->
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </encoder>
        </appender>
        <!-- 按照每天生成日志文件 -->
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--日志文件输出的文件名-->
                <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern>
                <!--日志文件保留天数-->
                <MaxHistory>30</MaxHistory>
            </rollingPolicy>
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            </encoder>
            <!--日志文件最大的大小-->
            <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
                <MaxFileSize>100MB</MaxFileSize>
            </triggeringPolicy>
        </appender>
    
        <!--mybatis log configure-->
        <logger name="com.apache.ibatis" level="TRACE"/>
        <logger name="java.sql.Connection" level="DEBUG"/>
        <logger name="java.sql.Statement" level="DEBUG"/>
        <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    
        <!-- 日志输出级别,logback日志级别包括五个:TRACE < DEBUG < INFO < WARN < ERROR -->
        <root level="DEBUG">
            <appender-ref ref="STDOUT"/>
            <appender-ref ref="FILE"/>
        </root>
    
    </configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这里插入图片描述
    3、每次获取SqlSession对象代码很繁琐,我们可以封装一个工具类

    package com.powernode.mybatis.utils;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    public class SqlSessionUtil {
        private static SqlSessionFactory sqlSessionFactory;
    
        /**
         * 类加载时初始化sqlSessionFactory对象
         */
        static {
            try {
                SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
                sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 每调用一次openSession()可获取一个新的会话,该会话支持自动提交。
         *
         * @return 新的会话对象
         */
        public static SqlSession openSession() {
            return sqlSessionFactory.openSession(true);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    如果要测试 CarMapper.xml 中的 Insert 方法,我们可以调用工具类简化为如下代码:

    @Test
    public void testInsertCar(){
        SqlSession sqlSession = SqlSessionUtil.openSession();
        // 执行SQL
        int count = sqlSession.insert("insertCar");
        System.out.println("插入了几条记录:" + count);
        sqlSession.close();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    9.2CubeMx配置SD卡FATFS系统_stm32H7系列 SD卡 FR_NO_FILESYSTEM 找不到FatFs系统的问题
    C#使用IronPython调用Python脚本实例
    #IIC 通信协议
    expect 使用手册命令详解
    【Docker】Linux网桥连接多个命名空间
    2022年亚太杯ABC题思路全解、代码、参考论文/2022年亚太地区数学建模思路全解
    haproxy负载均衡
    Java反射
    Java版人脸跟踪三部曲之二:开发设计
    苹果电脑误删除的文件怎么恢复?
  • 原文地址:https://blog.csdn.net/qq_61323055/article/details/127510557