1.宏观认识mybatis
mybatis是apache下一个开源的持久层框架,其可以自主编写sql语句、灵活性更高。
2.mybatis执行流程(基于mybatis 3.2)
通过SqlSessionFactoryBuilder(建造者模式)创建SqlSessionFactory(接口)对象
//SqlSessionFactoryBuilder的build方法
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
//底层通过XPath技术进行解析
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 e) {
// Intentionally ignore. Prefer previous error.
}
}
}
public SqlSessionFactory build(Configuration config) {
//返回SqlSessionFactory的默认实现类
return new DefaultSqlSessionFactory(config);
}
通过SqlSessionFactory(工厂模式)生成SqlSession对象(会话对象)
//SqlSessionFactory 中创建SqlSession的核心方法
//参数ExecutorType 执行器执行方式(枚举类型)
//参数TransactionIsolationLevel 事务隔离级别(枚举类型)
//参数autoCommit 是否自动提交
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
//获取配置文件中的environment标签对象(包括数据源、事务管理器等)
final Environment environment = configuration.getEnvironment();
//获取事务工厂对象
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//创建真实的事务对象
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//根据执行器类型创建不同的执行器对象(Excutor的实现类有多种)
//同时封装了事务对象
final Executor executor = configuration.newExecutor(tx, execType, autoCommit);
//通过配置文件对象和执行器创建SqlSession的实现类对象
return new DefaultSqlSession(configuration, executor);
} catch (Exception e) {
//出现异常时应关闭开启的事务
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
使用生成的SqlSession对象执行sql语句
//以查询为例
//参数statement 为sql语句的id
//参数parameter sql语句所需要的参数
//参数rowBounds 显示的行数
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
try {
//mapper.xml映射文件的封装对象
MappedStatement ms = configuration.getMappedStatement(statement);
//通过执行器执行查询(内部通过StatementHandler执行 本质是一个拦截器执行链)
List<E> result = executor.<E>query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
return result;
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
private final Logger logger=LoggerFactory.getLogger(DaoTest.class);
@Test
public void test(){
String resource="mybatis/sqlMapConfig.xml";
try {
//读取mybatis核心配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory工厂对象
SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
logger.debug("mybatis初始化成功");
//获取SqlSession对象
SqlSession session = sessionFactory.openSession();
//创建mapper对象(dao对象)
UserMapper mapper = session.getMapper(UserMapper.class);
User user=new User();
mapper.registerUserByPhone(user);
//事务提交
session.commit();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭SqlSession对象
session.close();
}
}