一. 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语句,修改数据。
归纳成一个图就是:
谢谢!!!