MyBatis的几个重要类和生命周期(四)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MyBatis的几个重要类和生命周期(四)

一. MyBatis 在创建的过程中,所使用到的重要类


在创建Mapper 的过程中,所使用到的工具类 SqlSessionFactoryUtils 。


package com.yjl.util;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
/**
 @author:两个蝴蝶飞
 @date: 2019年6月15日 上午11:13:26
 @Description 类的相关描述
*/
public class SqlSessionFactoryUtils {
  /*创建SqlSession的工厂 SqlSessionFactory对象*/
  private static SqlSessionFactory sqlSessionFactory=null;
  private SqlSessionFactoryUtils(){
  }
  /**
   * 单例模式 获取实例
   * @author 两个蝴蝶飞
   * @return
   */
  public static SqlSessionFactory getInstance(){
    synchronized(SqlSessionFactoryUtils.class){
      if(sqlSessionFactory==null){
        InputStream input=null;
        // Mybatis 核心配置文件名
        String resource_name="SqlMapConfig.xml";
        try {
          input=Resources.getResourceAsStream(resource_name);
          sqlSessionFactory=new SqlSessionFactoryBuilder().build(input);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    return sqlSessionFactory;
  }
  /**
   * 
   * @author 两个蝴蝶飞
   * @return 获取当前的Session
   */
  public static SqlSession getSession(){
    if(sqlSessionFactory==null){
      getInstance();
    }
    return sqlSessionFactory.openSession();
  }
}


在创建的过程中,使用到了 SqlSessionFactoryBuilder 类,SqlSessionFactory 接口,SqlSession 接口,SqlMapper 接口。


用一张图表示就是:


20190620200737627.png


下面,简单讲解一下,这几个类的使用。


二. SqlSessionFactoryBuilder


通过调用. builder(资源文件inputstream) 来达到创建SqlSessionFactory 工厂.


package org.apache.ibatis.session;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Properties;
import javax.security.auth.login.Configuration;
public class SqlSessionFactoryBuilder {
//调用字符流创建 SqlSessionFactory 工厂。
  public SqlSessionFactory build(Reader reader) {
    return build(reader, null, null);
  }
  public SqlSessionFactory build(Reader reader, String environment) {
    return build(reader, environment, null);
  }
  public SqlSessionFactory build(Reader reader, Properties properties) {
    return build(reader, null, properties);
  }
  public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        reader.close();
      } catch (IOException localIOException1) {
      }
    }
  }
  // 调用字节流 创建SqlSessionFactory 工厂
  public SqlSessionFactory build(InputStream inputStream) {
    return build(inputStream, null, null);
  }
  public SqlSessionFactory build(InputStream inputStream, String environment) {
    return build(inputStream, environment, null);
  }
  public SqlSessionFactory build(InputStream inputStream, Properties properties) {
    return build(inputStream, null, properties);
  }
  public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        inputStream.close();
      } catch (IOException localIOException1) {
      }
    }
  }
  // 采用代码形式,构建Configuration 对象,来创建工厂。
  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }
}


SqlSessionFactoryBuilder 会根据配置信息或者代码来生成SqlSessionFactory 。


提供了三种方式, 字符流,字节流, 和代码Configuration 类三种形式来创建SqlSessionFactory 类。


三. SqlSessionFactory 类


package org.apache.ibatis.session;
import java.sql.Connection;
public abstract interface SqlSessionFactory
{
//打开openSession()
  public abstract SqlSession openSession();
  public abstract SqlSession openSession(boolean paramBoolean);
  //根据连接创建
  public abstract SqlSession openSession(Connection paramConnection);
  //根据事务
  public abstract SqlSession openSession(TransactionIsolationLevel paramTransactionIsolationLevel);
  public abstract SqlSession openSession(ExecutorType paramExecutorType);
  public abstract SqlSession openSession(ExecutorType paramExecutorType, boolean paramBoolean);
  public abstract SqlSession openSession(ExecutorType paramExecutorType, TransactionIsolationLevel paramTransactionIsolationLevel);
  public abstract SqlSession openSession(ExecutorType paramExecutorType, Connection paramConnection);
  //获取代码配置的Configuration 对象信息
  public abstract Configuration getConfiguration();
}


主要用于创建SqlSession 接口。 用 openSession() 方法即可。


有两个实现类: DefaultSqlSessionFactory 和SqlSessionManager。 目前用前者, SqlSessionManager 还没有使用。


20190624185036865.png


有两个方式 创建SqlSessionFactory ,一种是配置文件的方式,另外一种是代码的方式, 即Configuration 类,

org.apache.ibatis.session.Configuration


20190624185639804.png


20190624185730775.png


后面还有很多, 定义了大量的 setter 和getter 方法,来设置和获取配置的信息。 与xml 配置的属性是一样的。 Configuration 对象存储在整个Mybatis 运行的生命周期内,以便重复的读取和运用。


三.一 xml 配置文件的方式创建SqlSessionFactory


就是前三章所用的形式。


<?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>
  <!-- 配置别名 -->
  <typeAliases>
    <typeAlias type="com.yjl.pojo.User" alias="user"/>
  </typeAliases>
  <!-- 开发环境  development -->
  <environments default="development">
    <environment id="development">
      <!-- 事务管理 -->
      <transactionManager type="JDBC"></transactionManager>
      <!-- 数据源 ,为pooled 连接池 -->
      <dataSource type="pooled">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8"/>
        <property name="username" value="root"/>
        <property name="password" value="abc123"/>
      </dataSource> 
    </environment>
  </environments>
  <mappers>
    <!-- 引入文件资源 -->
    <mapper resource="com/yjl/mapper/UserMapper.xml"/>
  </mappers>
</configuration>


三.二 代码样式创建SqlSessionFactory


package com.yjl.util;
import javax.sql.DataSource;
import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import com.yjl.mapper.UserMapper;
import com.yjl.pojo.User;
/**
 @author:两个蝴蝶飞
 @date: 2019年6月15日 上午11:13:26
 @Description 类的相关描述
*/
public class SqlSessionFactoryUtils {
  /*创建SqlSession的工厂 SqlSessionFactory对象*/
  private static SqlSessionFactory sqlSessionFactory=null;
  private SqlSessionFactoryUtils(){
  }
  /**
   * 单例模式 获取实例
   * @author 两个蝴蝶飞
   * @return
   */
  public static SqlSessionFactory getInstance(){
    synchronized(SqlSessionFactoryUtils.class){
      if(sqlSessionFactory==null){
        try {
          String driver = "com.mysql.jdbc.Driver";
          String url = "jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8";
          String username="root";
          String password="abc123";
          //设置数据库的数据源
          DataSource dataSource =new PooledDataSource(driver,url,username,password);
          //事务为jdbc处理
          TransactionFactory transactionFactory =  new JdbcTransactionFactory();
          //环境为development 环境
          Environment environment = new Environment("development", transactionFactory, dataSource);
          //创建Configuration
          Configuration configuration = new Configuration(environment);
          //设置别名
          configuration.getTypeAliasRegistry().registerAlias("user",User.class);
          //配置文件 UserMapper
          configuration.addMapper(UserMapper.class);
          //创建SqlSessionFactory
          sqlSessionFactory=new SqlSessionFactoryBuilder().build(configuration);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    return sqlSessionFactory;
  }
  /**
   * 
   * @author 两个蝴蝶飞
   * @return 获取当前的Session
   */
  public static SqlSession getSession(){
    if(sqlSessionFactory==null){
      getInstance();
    }
    return sqlSessionFactory.openSession();
  }
}


测试方法


@Test
  public void findAllTest(){
    SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
    UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
    List<User> allList=userMapper.findAll();
    allList.forEach(n ->System.out.println(n));
  }


20190624191111190.png


正常的查询了出来, 代码创建是没有错的。


但是代码创建时,是硬编码写入,并且别名和映射文件都是写入的,每次都要进行修改。


建议,使用XML 配置的方式。


四. SqlSession 接口


package org.apache.ibatis.session;
import java.io.Closeable;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.BatchResult;
public abstract interface SqlSession
  extends Closeable
{
// 查询单个对象
  public abstract <T> T selectOne(String paramString);
  public abstract <T> T selectOne(String paramString, Object paramObject);
  //查询多个集合对象
  public abstract <E> List<E> selectList(String paramString);
  public abstract <E> List<E> selectList(String paramString, Object paramObject);
  public abstract <E> List<E> selectList(String paramString, Object paramObject, RowBounds paramRowBounds);
  // 查询Map 形式
  public abstract <K, V> Map<K, V> selectMap(String paramString1, String paramString2);
  public abstract <K, V> Map<K, V> selectMap(String paramString1, Object paramObject, String paramString2);
  public abstract <K, V> Map<K, V> selectMap(String paramString1, Object paramObject, String paramString2, RowBounds paramRowBounds);
  // 查询光标
  public abstract <T> Cursor<T> selectCursor(String paramString);
  public abstract <T> Cursor<T> selectCursor(String paramString, Object paramObject);
  public abstract <T> Cursor<T> selectCursor(String paramString, Object paramObject, RowBounds paramRowBounds);
  // 利用ResultHandler 处理来理查询
  public abstract void select(String paramString, Object paramObject, ResultHandler paramResultHandler);
  public abstract void select(String paramString, ResultHandler paramResultHandler);
  public abstract void select(String paramString, Object paramObject, RowBounds paramRowBounds, ResultHandler paramResultHandler);
  //插入-
  public abstract int insert(String paramString);
  public abstract int insert(String paramString, Object paramObject);
  //更新
  public abstract int update(String paramString);
  public abstract int update(String paramString, Object paramObject);
  //删除 
  public abstract int delete(String paramString);
  public abstract int delete(String paramString, Object paramObject);
 //事务提交
  public abstract void commit();
  public abstract void commit(boolean paramBoolean);
  //事务回滚
  public abstract void rollback();
  public abstract void rollback(boolean paramBoolean);
  public abstract List<BatchResult> flushStatements();
  //关闭 SqlSession
  public abstract void close();
  //清理缓存
  public abstract void clearCache();
  //获取Configuration 对象
  public abstract Configuration getConfiguration();
  //获取SqlMapper
  public abstract <T> T getMapper(Class<T> paramClass);
  //获取Connection 连接对象
  public abstract Connection getConnection();
}


SqlSession 相当于JDBC 时的 Connection 对象,用于 查询 (selectOne,selectList,selectMap,select), 插入(insert),删除(delete),修改(update), 也用于获取SqlMapper 接口。


SqlSession 有两个实现类, DefaultSqlSession,SqlSessionManager, 目前用的是 前者。


20190624191738535.png


五. 生命周期


五.一 SqlSessionFactoryBuilder 方法局部


它的作用是一个构建器,一旦构建了SqlSessionFactory,它的作用就完结了,失去了存在的意义,必须废除,将其回收。所以它只存在于方法的局部。


五.二 SqlSessionFactory 整个MyBatis 生命周期中


责任是唯一的,就是创建SqlSession. 是单例模式


五.三 Configuration 整个MyBatis 生命周期中


用于 注册 别名,处理器,映射文件等。


五.三 SqlSession 数据库处理事务的过程中


是一个线程不安全的对象, 用finally 来close() 关闭连接 。


五.四 SqlMapper SqlSession事务方法之内


是一个接口,没有任何实现类,作用就是 发送SQL语句,返回结果 ,或者是执行sql语句,修改数据。


归纳成一个图就是:


2019062419294067.png


谢谢!!!

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6月前
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
Mybatis+mysql动态分页查询数据案例——测试类HouseDaoMybatisImplTest)
|
6月前
Mybatis+mysql动态分页查询数据案例——条件类(HouseCondition)
Mybatis+mysql动态分页查询数据案例——条件类(HouseCondition)
|
6月前
Mybatis+mysql动态分页查询数据案例——房屋信息的实现类(HouseDaoMybatisImpl)
Mybatis+mysql动态分页查询数据案例——房屋信息的实现类(HouseDaoMybatisImpl)
|
XML Java 数据库连接
Mybatis使用generator逆向工程生成器生成entity、mapper、.xml模版类
今天将表建好了,但是一个一个的建实体类、Mapper接口、Mapper.xml文件就十分的麻烦,所以我就想到了MyBatis逆向,今天就操作一把!这里我们采用maven来进行操作。
270 0
|
4月前
|
Java 数据库连接 mybatis
SpringBoot配置Mybatis注意事项,mappers层下的name命名空间,要落实到Dao的video类,resultType要落到bean,配置好mybatis的对应依赖。
SpringBoot配置Mybatis注意事项,mappers层下的name命名空间,要落实到Dao的video类,resultType要落到bean,配置好mybatis的对应依赖。
|
6月前
|
存储 缓存 Java
探秘MyBatis缓存原理:Cache接口与实现类源码分析
探秘MyBatis缓存原理:Cache接口与实现类源码分析
100 2
探秘MyBatis缓存原理:Cache接口与实现类源码分析
|
5月前
|
Java 数据库连接 mybatis
为什么Mybatis Mapper不需要实现类?
在学习Java动态代理之前,我想让大家先思考这样几个问题。 • JDK动态代理为什么不能对类进行代理? • Mybatis Mapper接口为什么不需要实现类? 如果你还不知道上述问题的答案,那么这篇文章一定能消除你心中的疑惑。
|
XML Java 数据库连接
优雅地使用Mybatis逆向工程生成类
优雅地使用Mybatis逆向工程生成类
94 1
|
6月前
ssm(Spring+Spring mvc+mybatis)Service层实现类——DeptServiceImpl
ssm(Spring+Spring mvc+mybatis)Service层实现类——DeptServiceImpl
|
6月前
ssm(Spring+Spring mvc+mybatis)Dao层实现类——DeptDaoImpl
ssm(Spring+Spring mvc+mybatis)Dao层实现类——DeptDaoImpl