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

这篇文章的开头,写给我的兄弟: 在程序的世界,只有实践才会得到自己想要的答案。 再高明的计算机,再高明的工具,都无法将空的代码执行成最美的秘密。

上一章简单介绍了MyBatis的Mapper 代理的增删改查操作(三),如果没有看过,请观看上一章

一. 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 接口。
用一张图表示就是:
在这里插入图片描述

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

二. 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 还没有使用。
在这里插入图片描述

有两个方式 创建SqlSessionFactory ,一种是配置文件的方式,另外一种是代码的方式, 即Configuration 类,
org.apache.ibatis.session.Configuration
在这里插入图片描述
在这里插入图片描述
后面还有很多, 定义了大量的 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));
	}

在这里插入图片描述正常的查询了出来, 代码创建是没有错的。
但是代码创建时,是硬编码写入,并且别名和映射文件都是写入的,每次都要进行修改。
建议,使用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, 目前用的是 前者。
在这里插入图片描述

五. 生命周期

五.一 SqlSessionFactoryBuilder 方法局部

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

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

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

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

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

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

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

五.四 SqlMapper SqlSession事务方法之内

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

归纳成一个图就是:

在这里插入图片描述

谢谢!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两个蝴蝶飞

你的鼓励,是老蝴蝶更努力写作的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值