• MyBatis的简介和核心的组件(映射器、执行器、SqlSession及其工厂)


    Java知识点总结:想看的可以从这里进入

    1、简介


    1.1、原始JDBC

    在以前我们都是使用原始的JDBC,但是这种连接会造成创建、释放频繁造成系统资源的浪费从而影响性能,当sql变化时需要去改变Java代码,不符合开闭的原则,在查询时要手动将结果集封装到实体,插入时手动的提取实体到占位符,增加了代码量。

    • 导入相关的 jar 包 或者依赖;
    • 加载驱动,获取Connection
    • 准备SQL语句,获取执行sql语句的Statement对象;
    • 通过Statement对象执行SQL,返回结果到ResultSet对象;
    • 使用ResultSet读取数据,然后通过代码转化为具体的对象;
    • 释放资源
    public List<User> selectAllUser(){
     	//原始的JDBC手动创建连接
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/库名?useUnicode=true&&characterEncoding=utf-8&serverTimezone=Asia/Shanghai";
            String root = "root";
            String password = "密码";
            conn = DriverManager.getConnection(url,root,password);
            ps = conn.prepareStatement("select * from `user`");
            rs = ps.executeQuery();
            List<User> list = new ArrayList<>();
            while (rs.next()){
                //获取数据
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                //添加到集合中
                list.add(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                conn.close();
                ps.close();
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }   
    }
    
    • 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

    1.2、SpringJDBC

    SpringJDBC是对原始JDBC做了封装,它将原始的JDBC的步骤做了封装,我们只需要完成相关配置,就可以直接连接数据库,在操作中只需要关注JdbcTemplate 对象即可。

    
    <context:property-placeholder location="classpath:database.properties"/>
    
    
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        
        <property name="initialSize" value="${jdbc.initialSize}"/>
        
        <property name="minIdle" value="${jdbc.minIdle}"/>
        
        <property name="maxActive" value="${jdbc.maxActive}"/>
        
        <property name="maxWait" value="${jdbc.maxWait}"/>
    bean>
    
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    @Resource
    private JdbcTemplate jdbcTemplate;
    @Test
    public void jdbcTest(){
        String sql = "select * from `user`";
        List<User> users = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
        users.forEach(System.out::println);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    1.3、MyBatis

    原始的JDBC操作繁琐,每次执行SQL时每次都需要获取:Connection、PreparedStatement、ResultSet 这些数据库资源,然后就需要大量的try、catch、finally语句捕捉异常、关闭数据库资源。而SpringJDBC虽然对JDBC做了封装,大大的简化了操作流程,但是它的操作还是直接在业务层面的,这样会导致耦合性较强,且有sql注入的危险。所以就产生了第三方的框架,比如MyBatis。官网

    MyBatis 是 apache的一个开源项目iBatis,2010年6月这个项目由Apache Software Foundation迁移到了Google Code后,正式更名为MyBatis。代码于2013年11月迁移到Github。

    它是一种半自动的对象关系映射(ORM)框架,它在Java对象和数据库的表之间建立映射关系(类对应表,属性对应字段),内部封装了JDBC相关操作,所以不用再去关注注册驱动、获取连接、执行 SQL、释放资源等操作,极大简化了持久层开发工作。其中SQL语句需要我们自己编写,虽然相对于自动的映射框架来说,增加了不少代码量,但是它有较高的灵活性,可以根据需要,自由地对SQL进行定制。

    什么是ORM?即Object Relation Mapping,对象关系映射。对象指的是Java对象,关系指的是数据库中的关系模型,对象关系映射,指的就是在Java对象和数据库的关系模型之间建立一种对应关系,就是数据库的表对应Java类,数据库字段对应Java属性,数据的一条数据对应Java一个对象。

    全自动的ORM不需要编写SQL语句,只需要定义好映射关系,就可以直接进行CRUD操作了。而半自动的ORM,需要手动编写SQL语句。虽然这种半自动的ORM在操作上会麻烦很多,但是相对的它也更加灵活,可以根据需要,自由地对SQL进行定制。

    MyBatis 是通过 XML 或注解配置Statement对象,并通过Java对象和 Statement中的SQL进行映射生成最终执行的SQL语句,最后由MyBatis框架执行SQL并将结果映射成Java对象并返回。

    在MyBatis 中有三个基本要素:

    • 核心组件(核心的类和接口)
    • MyBatis核心配置文件(mybatis-config.xml)
    • SQL映射器(mapper.xml)

    MyBatis还有一种增强的工具版本 Mybatis-Plus,它是在Mybatis的基础上做了一些增强,在不改变MyBatis的基础上,简化了开发。

    Mybatis的使用过程:

    • 添加mybatis的依赖

      
      <dependency>
          <groupId>mysqlgroupId>
          <artifactId>mysql-connector-javaartifactId>
          <version>8.0.25version>
      dependency>
      
      <dependency>
          <groupId>org.mybatisgroupId>
          <artifactId>mybatisartifactId>
          <version>3.5.7version>
      dependency>
      
      <dependency>
        <groupId>org.junit.jupitergroupId>
        <artifactId>junit-jupiter-apiartifactId>
        <version>5.9.1version>
        <scope>testscope>
      dependency>
      
      <dependency>
          <groupId>org.apache.logging.log4jgroupId>
          <artifactId>log4j-coreartifactId>
          <version>2.20.0version>
      dependency>
      
      • 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
    • MyBatis 默认使用 log4j 输出日志信息,所以可以配置日志文件 log4j.properties

      ### 设置日志级别和输出位置 ###
      log4j.rootLogger=DEBUG,console,logFile
      log4j.additivity.org.apache=true
      
      # 输出到控制台(console)
      log4j.appender.console=org.apache.log4j.ConsoleAppender
      # 输出级别最低为DEBUG
      log4j.appender.console.Threshold=DEBUG		
      # 表示所有消息都会被立即输出
      log4j.appender.console.ImmediateFlush=true
      #输出日志到控制台的方式
      log4j.appender.console.Target= System.out
      # 灵活布局输出日志
      log4j.appender.console.layout=org.apache.log4j.PatternLayout
      #设定以怎样的格式显示消息。
      log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] -%m%n
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • 创建mybatis-config.xml配置文件

    • 编写,加载映射文件mapper.xml

    • 加载配置文件,创建SqlSessionFactory工厂,获取SqlSession

    • 调用mapper映射文件中的SQL语句来执行CRUD操作

    • 返回结果集的映射

    2、核心组件


    2.1、组件介绍

    mybatis的核心组件主要有4部分

    • SqlSessionFactoryBuilder(构造器):它的作用仅仅用来生成 SqlSessionFactory,创建成功后就失去作用,所以用在生成 SqlSessionFactory 的方法中作为局部变量使用,用完即可回收。

      它通过内部的build(InputStream inputStream, String environment, Properties properties) 创建SqlSessionFactory,使用流读取配置文件。

    • SqlSessionFactory:相当于数据库的连接池,主要是用 openSession() 创建SqlSession接口,所以需要存在MyBatis的整个应用中。一般是创建一个单例模式,生命周期等同MyBatis的生命周期

    • SqlSession:相当于Connection对象,用于业务请求,用完关闭。存在于一次业务请求中,处理完请求后使用close方法关闭。

    • SQL Mapper(映射器):Mapper是通过SqlSession获取的,所以Mapper的生命周期小于SqlSession,它相当于一个请求中的业务处理。

    2.2、SqlSessionFactory

    SqlSessionFactory是 Mybatis的核心组件,每个MyBatis都是以一个SqlSessionFactory实例为中心,而它的作用就是生产SqlSession。

    使用MyBatis需要配置 SqlSessionFactory 对象,通常使用 SqlSessionFactoryBuilder 的 build() 方法,SqlSessionFactory作为一个工厂接口,唯一的作用就是用来创建SqlSession的,所以我们一般会用单例模式来处理它。而一般选用通过XML配置的方式来生成 SqlSessionFactory。

    • 创建database.properties文件

      jdbc.driver=com.mysql.cj.jdbc.Driver
      jdbc.url=jdbc:mysql://localhost:3306/库名?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
      jdbc.username=root
      jdbc.password=密码
      
      • 1
      • 2
      • 3
      • 4
    • 创建一个映射器文件

      
      DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      
      <mapper namespace="com.yu.mybatis.mapper.UserMapper">
            
            <resultMap id="BaseResultMap" type="com.yu.mybatis.entity.User">
                  <id column="user_id" jdbcType="INTEGER" property="userId" />
                  <result column="username" jdbcType="VARCHAR" property="username" />
                  <result column="password" jdbcType="VARCHAR" property="password" />
                  <result column="deleted" jdbcType="BIT" property="deleted" />
            resultMap>
          
            <sql id="Base_Column_List">
              	user_id, username, `password`, deleted
            sql>
          
            <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
                  select 
                  <include refid="Base_Column_List" />
                  from `user`
                  where user_id = #{userId,jdbcType=INTEGER}
            select>
      mapper>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
    • XML配置数据库连接

      
      DOCTYPE configuration
              PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
              "http://mybatis.org/dtd/mybatis-3-config.dtd">
      
      <configuration>
      	
          <properties resource="database.properties"/>
      
          
          <environments default="development">
              <environment id="development">
                  
                  <transactionManager type="JDBC"/>
                  <dataSource type="POOLED">
                      <property name="driver" value="${jdbc.driver}"/>
                      <property name="url" value="${jdbc.url}"/>
                      <property name="username" value="${jdbc.username}"/>
                      <property name="password" value="${jdbc.password}"/>
                  dataSource>
              environment>
          environments>
      
          
          <mappers>
              <mapper resource="mapping/UserMapper.xml"/>
          mappers>
      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
    • 创建一个帮助类,读取 xml 配置文件,生成SqlSessionFactory

      public class SqlSessionUtil {
          private static SqlSessionFactory factory = null;
          static {
              try {
                  InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
                  factory = new SqlSessionFactoryBuilder().build(in);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          public static SqlSessionFactory getFactory(){
              return factory;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

    2.3、SqlSession

    SqlSession是MyBatis的核心接口,其有两个实现类:其中DefaultSqlSession是单线程,SqlSessionManager是多线程。

    它就相当于Connection对象,代表一个连接数据库的资源,每次需要获取和关闭。它提供了面向数据库执行 SQL 命令所需的所有方法,可以通过 SqlSession 实例直接运行已映射的 SQL 语句。

    //SqlSession的获取,
    //通过SqlSession对象所操作的sql都必须手动提交或回滚事务
    SqlSession sqlSession = SqlSessionUtil.getFactory().openSession();
    //此时通过SqlSession对象所操作的sql都会自动提交
    SqlSession sqlSession = SqlSessionUtil.getFactory().openSession(true);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    SqlSession执行SQL的两种方式

    • 直接发送SQL给数据库,利用XML映射器

      String statement=“XML映射文件的namespace属性值(Mapper接口全限定名) + XML映射文件方法的id名(mapper接口的方法名)”
      Object parameter:插入所需的参数,通常是对象或者Map
      RowBounds rowBounds:用于分页,它的两个属性: offset指查询的当前页数; limit指当前页显示多少条数据。
      String mapKey:执查询结果会被封装成一个Map集合返回,key就是参数mapKey传入的列名,value 是封装的对象。
      ResultHandler handler:ResultHandler对象用来处理查询返回的复杂结果集,通常用于多表查询。

      public interface SqlSession extends Closeable {
      
        /**查询方法,查询结果只有一条数据时才使用。*/
        <T> T selectOne(String statement);
        <T> T selectOne(String statement, Object parameter);
      
        /**查询方法,返回执行SQL话句查询结果的泛型对象的集合。。*/
        <E> List<E> selectList(String statement);
        <E> List<E> selectList(String statement, Object parameter);
        <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
      
        /**查询方法,根据结果对象中的一个属性将结果列表转换为 Map */
        <K, V> Map<K, V> selectMap(String statement, String mapKey);
        <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
        <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
      
        /**Cursor 提供与 List 相同的结果,只是它使用 Iterator 懒惰地获取数据。*/
        <T> Cursor<T> selectCursor(String statement);
        <T> Cursor<T> selectCursor(String statement, Object parameter);
        <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);
      
        /**使用ResultHandler检索从语句键和参数映射的单行。 */
        void select(String statement, Object parameter, ResultHandler handler);
        void select(String statement, ResultHandler handler);
        void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
      
        /**插入方法,返回执行SQL语句所影响的行数。。*/
        int insert(String statement);
        int insert(String statement, Object parameter);
      
        /**执行更新语句。将返回受影响的行数 */
        int update(String statement);
        int update(String statement, Object parameter);
      
        /**执行删除语句。将返回受影响的行数。*/
        int delete(String statement);
        int delete(String statement, Object parameter);
      
        /**提交事务。 */
        void commit();
        void commit(boolean force);
      
        /**回滚事务 */
        void rollback();
        void rollback(boolean force);
      
        /**刷新批处理语句*/
        List<BatchResult> flushStatements();
      
        /**关闭会话 */
        @Override
        void close();
      
        /**清除本地会话缓存。*/
        void clearCache();
      
        /**检索当前配置。 */
        Configuration getConfiguration();
      
        /**检索映射器*/
        <T> T getMapper(Class<T> type);
      
        /**检索内部数据库连接 */
        Connection getConnection();
      }
      
      
      • 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
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66

      image-20230304142316789

    • 获取Mapper接口,操作SQL(建议使用)

      sqlSession.getMapper(***Mapper.class);	//创建的Mapper接口
      
      • 1

      在使用Mybatis时,会根据映射文件创建相应的mapper接口,可以用接口的方法

      public interface UserMapper {
          User selectByPrimaryKey(Integer userId);
      }
      
      • 1
      • 2
      • 3
      
      <mapper namespace="com.yu.mybatis.mapper.UserMapper">
          
        <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
          
          select 
          <include refid="Base_Column_List" />
          from `user`
          where user_id = #{userId,jdbcType=INTEGER}
        select>
      mapper>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      image-20230304142719906

    2.4、映射器

    MyBatis中最重要也是最复杂的组件,MyBatis是由一个Mapper接口,和一个XML映射文件(注解),对应以前的dao接口和一个dao实现类,它主要的作用是:

    • 描述映射规则
    • 提供SQL语句
    • 配置缓存
    • 提供动态SQL
    2.4.1 接口和XML映射

    在MyBatis中数据的一张表,分别对应一个实体类,一个Mapper接口、和一个XML的映射文件。

    在IDEA中可以引入插件MyBatisCodeHelperPro,使用插件辅助创建所需的类。

    image-20210716120801177 image-20210716120411230
    • 实体类:根据数据表对应的实体类会自动创建好,并生成get和det方法。

      image-20220918163654592
    • mapper:接口,编写查询所有的方法,如果映射的路径正确,点击创建,会自动在xml文件中创建好

      image-20220918163038319
    • mapping:mapper的实现类,xml形式配置。

      它的映射规则是:

      先通过 mapper namespace=“com.yu.mapper.UserMapper” 映射到对应的接口

      然后通过select、update、delete、inser这些标签的 id 属性值映射得到接口对应的方法上

      再通过 resultMap、parameterType这两个属性可以将获得的结果集,映射到对应的实体类上进行自动装配。

      
      DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      
      <mapper namespace="com.yu.mapper.UserMapper">
      
          
          <resultMap id="BaseResultMap" type="com.yu.pojo.User">
              <id column="user_id" jdbcType="INTEGER" property="userId" />
              <result column="username" jdbcType="VARCHAR" property="username" />
              <result column="password" jdbcType="VARCHAR" property="password" />
              <result column="deleted" jdbcType="BIT" property="deleted" />
          resultMap>
      
          
          <sql id="Base_Column_List">
              user_id, username, `password`, deleted
          sql>
      
          
          <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
              
              select 
              <include refid="Base_Column_List" />
              from `user`
              where user_id = #{userId,jdbcType=INTEGER}
          select>
      
          
          <insert id="insert" keyColumn="user_id" keyProperty="userId" parameterType="com.yu.pojo.User" useGeneratedKeys="true">
              
              insert into `user` (username, `password`, deleted)
              values (#{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{deleted,jdbcType=BIT})
          insert>
      
          
          <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
              delete from `user`
              where user_id = #{userId,jdbcType=INTEGER}
          delete>
      
          
          <update id="updateByPrimaryKeySelective" parameterType="com.yu.pojo.User">
              update `user`
              <set>
                  <if test="username != null">
                      username = #{username,jdbcType=VARCHAR},
                  if>
                  <if test="password != null">
                      `password` = #{password,jdbcType=VARCHAR},
                  if>
                  <if test="deleted != null">
                      deleted = #{deleted,jdbcType=BIT},
                  if>
              set>
              where user_id = #{userId,jdbcType=INTEGER}
          update>
      mapper>
      
      • 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
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
    2.4.2 发送SQL

    通过SqlSession可以获取Mapper接口,它对比SqlSession发送的SQL语句,有很高的可读性,因为SqlSession需要使用自己的方法通过SQL的id属性去匹配相应的SQL,而Mapper则是直接使用自己定义的方法。

    public class SqlSessionTest {
        @Test
        public void test(){
            SqlSession sqlSession = SqlSessionUtil.getFactoryBean().openSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            User user = mapper.selectByPrimaryKey(1);
            sqlSession.commit();
            System.out.println(user.getUsername());
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    配置的日志打印的信息:

    image-20220918163428829

    查到了数据

    image-20220918163507889

    2.4.3、注解的形式

    映射器中也有相应的注解来代替XML映射文件,来实现SQL语句,如果和XML同时定义,XML会覆盖掉注解.

    public interface UserMapper {
        @Select("select user_id, username, `password`, deleted from `user` where user_id =#{userId}")
        User selectByPrimaryKey(Integer userId);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    上面的这条注解语句可以代替下面这个:

    <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        
        select 
        <include refid="Base_Column_List" />
        from `user`
        where user_id = #{userId,jdbcType=INTEGER}
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    虽然注解的形式要简单很多,但是很多的 sql语句的复杂性是很高的,这种复杂的sql语句放在XML文件中更适合,而且他还可能牵扯到一些动态 SQL等问题,所以还是推荐使用XML的方式。

    2.5、执行器

    MyBatis整体操作无非就是:连接数据库、编译生成SQL语句、执行SQL、获取数据进行封装等几个步骤,其中执行器 Executor就是用来执行SQL语句的,存在于SqlSession中。

    image-20220918170024484

    MyBatis有三种基本的执行器:

    1. 简单执行器SimpleExecutor:每次执行update或select都会开启一个statement对象,用完立刻关闭statement对象
    2. 可重用执行器ReuseExecutor:执行update或select前,以sql作为key查找Statement对象,存在就使用不存在就创建,用完后不关闭,放置在Map中供下一次使用。(重复使用)
    3. 批量执行器BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。
    public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? defaultExecutorType : executorType;
        executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
        Executor executor;
        if (ExecutorType.BATCH == executorType) {
            executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
            executor = new ReuseExecutor(this, transaction);
        } else {
            executor = new SimpleExecutor(this, transaction);
        }
        if (cacheEnabled) {
            executor = new CachingExecutor(executor);
        }
        executor = (Executor) interceptorChain.pluginAll(executor);
        return executor;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2.6、mybatis流程

    image-20220717165229940
    1. 读取MyBatis的核心配置文件:读取配置数据库的连接、属性、类别名、映射器等信息。
    2. 加载映射文件:Mapping.xml映射文件,用来配置操作数据库的SQL语句,可以通过xml和注解获取
    3. 构造会话工厂获取SqlSessionFactory:通过SqlSessionFactoryBuilder对象构建
    4. 创建会话对象SqlSession:包含了执行SQL的一些方法
    5. Executor执行器:mybatis的核心,用来SQL语句的生成和查询缓存的维护
    6. Statement对象:对SQL语句的封装,一个对象对应XML文件中的一个sql语句标签。
    7. 输入参数映射:传递参数,进行预编译处理
    8. 封装结果集:将SQL语句产生的数据进行封装
  • 相关阅读:
    21.4 CSS 盒子模型
    合并二叉树
    LeetCode刷题笔记【33】:动态规划专题-5(最后一块石头的重量 II、目标和、一和零)
    CSRF攻击
    Go学习之路:并发(DAY 3)
    1011 World Cup Betting
    安卓常见设计模式------装饰器模式(Kotlin版)
    ckplayer播放线上视频问题
    如何编辑图片合成图片?让我们来看看这些合成方法
    博客性能优化笔记 | 99分
  • 原文地址:https://blog.csdn.net/yuandfeng/article/details/126921826