标签:imp except 流程图 stat pool gate mysq database word
首先是写一个 UserDao 的实现类:UserDaoImpl
这一个步骤区别于一般情况,平时我们一般不会自己写Dao的实现类,而是通过Mybatis通过动态代理的方式帮我们实现一个Dao的代理类,然后我们直接使用;
public class UserDaoImpl implements UserDao {
// 创建SqlSession的工厂对象
private SqlSessionFactory factory;
// 通过构造的方式将factory传入本实现类
public UserDaoImpl (SqlSessionFactory factory) {
this.factory = factory;
}
/**
* 查询所有
*/
@Override
public List<User> findAll() {
// 获取操控数据库的 SqlSession 对象
SqlSession session = factory.openSession();
// 调用selectList()方法来查询,dao接口全限定类名.findAll(方法名)
List<User> users = session.selectList("com.xfzhao.dao.UserDao.findAll");
// 关闭资源
session.close();
// 返回结果
return users;
}
}
<?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">
<!-- mybatis的主配置文件 -->
<configuration>
<typeAliases>
<package name="com.xfzhao.domain"/>
</typeAliases>
<!-- 配置环境 -->
<environments default="mysql">
<!-- 配置mysql的环境-->
<environment id="mysql">
<!-- 配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源(连接池) -->
<dataSource type="POOLED">
<!-- 配置连接数据库的4个基本信息 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
<mappers>
<mapper resource="com/xfzhao/dao/Userdao.xml"></mapper>
</mappers>
</configuration>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xfzhao.dao.UserDao">
<!--查询所有用户-->
<select id="findAll" resultType="com.xfzhao.domain.User">
select * from user;
</select>
</mapper>
public class mybatis {
private InputStream in;
private SqlSessionFactory factory;
private UserDao userDao;
@Before
public void init() throws IOException {
in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(in);
}
@Test
public void testFindAll() {
UserDao userDao = new UserDaoImpl(factory);
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
}
首先我们调用的是 SqlSession 的 selectList() 方法:
List<User> users = session.selectList("com.xfzhao.dao.UserDao.findAll");
因为 SqlSession 是接口,通过断点调试发现,真正的实现类的是 DefaultSqlSession
,其中有三个 selectList()
方法,最终都是走的最后一个三个参数的方法;
其中很关键的一步就是 this.executor.query(ms, this.wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
这里的 executor 是 CachingExecutor
// DefaultSqlSession 类
public <E> List<E> selectList(String statement) {
// 调用下面一个方法
return this.selectList(statement, (Object)null);
}
public <E> List<E> selectList(String statement, Object parameter) {
// 调用下面一个方法
return this.selectList(statement, parameter, RowBounds.DEFAULT);
}
// 真正执行的是这个方法
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
List var5;
try {
MappedStatement ms = this.configuration.getMappedStatement(statement);
// 走的是这里,这里的 executor 是 CachingExecutor
var5 = this.executor.query(ms, this.wrapCollection(parameter),
rowBounds, Executor.NO_RESULT_HANDLER);
} catch (Exception var9) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + var9, var9);
} finally {
ErrorContext.instance().reset();
}
return var5;
}
下面找到 CachingExecutor :
// CachingExecutor类
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
// 省略代码...
// 走的是这里,this.delegate 是 SimpleExecutor 类
return this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
然后我们去 SimpleExecutor 类中:
我们发现这个类中没有 query() 方法,只有 doQuery() 方法。于是我们就去找它的父类:BaseExecutor
public class SimpleExecutor extends BaseExecutor {...}
在 BaseExecutor 类中存在 query() 方法:而且存在两个query() 方法,我们直接看最后被调用的那一个
public <E> List<E> query(MappedStatement ms,
Object parameter, RowBounds rowBounds,
ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
//....省略其他
// 主要走的就是这一步: 执行 queryFromDatabase() 方法
list = this.queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
继续看 queryFromDatabase() 方法:
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
// ....
// 走的是这一步,执行的是抽象的 doQuery()方法
// 这里我们就知道了实际上绕了一圈还是走的是 simpleExecutor 的 doQuery() 方法
list = this.doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
// ....
}
最后我们再回去看 simpleExecutor 的 doQuery() 方法
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
Statement stmt = null;
List var9;
try {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(this.wrapper,
ms, parameter,
rowBounds,
resultHandler, boundSql);
stmt = this.prepareStatement(handler, ms.getStatementLog()); // 最后走的这一步:这里的 handler 是 RoutingStatementHandler
var9 = handler.query(stmt, resultHandler);
} finally {
this.closeStatement(stmt);
}
return var9;
}
现在来到了 RoutingStatementHandler 类中:查看它的 query() 方法:
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
// 走的这里:这里的delegate是 PrepareStatementHandler
return this.delegate.query(statement, resultHandler);
}
然后继续进入类: PrepareStatementHandler 中,查看 query() 方法:这里就是JDBC 的常规操作
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
// 到这里就很熟悉了,使用的是 prepareStatement对象
PreparedStatement ps = (PreparedStatement)statement;
// 执行的是它的 executor() 方法
ps.execute();
// 下面的步骤就是封装结果集
return this.resultSetHandler.handleResultSets(ps);
}
首先是写一个 UserDao 的实现类:UserDaoImpl
这一个步骤区别于一般情况,平时我们一般不会自己写Dao的实现类,而是通过Mybatis通过动态代理的方式帮我们实现一个Dao的代理类,然后我们直接使用;
public class UserDaoImpl implements UserDao {
// 创建SqlSession的工厂对象
private SqlSessionFactory factory;
// 通过构造的方式将factory传入本实现类
public UserDaoImpl (SqlSessionFactory factory) {
this.factory = factory;
}
/**
* 查询所有
*/
@Override
public List<User> findAll() {
// 获取操控数据库的 SqlSession 对象
SqlSession session = factory.openSession();
// 调用selectList()方法来查询,dao接口全限定类名.findAll(方法名)
List<User> users = session.selectList("com.xfzhao.dao.UserDao.findAll");
// 关闭资源
session.close();
// 返回结果
return users;
}
}
<?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">
<!-- mybatis的主配置文件 -->
<configuration>
<typeAliases>
<package name="com.xfzhao.domain"/>
</typeAliases>
<!-- 配置环境 -->
<environments default="mysql">
<!-- 配置mysql的环境-->
<environment id="mysql">
<!-- 配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源(连接池) -->
<dataSource type="POOLED">
<!-- 配置连接数据库的4个基本信息 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
<mappers>
<mapper resource="com/xfzhao/dao/Userdao.xml"></mapper>
</mappers>
</configuration>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xfzhao.dao.UserDao">
<!--查询所有用户-->
<select id="findAll" resultType="com.xfzhao.domain.User">
select * from user;
</select>
</mapper>
public class mybatis {
private InputStream in;
private SqlSessionFactory factory;
private UserDao userDao;
@Before
public void init() throws IOException {
in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
factory = builder.build(in);
}
@Test
public void testFindAll() {
UserDao userDao = new UserDaoImpl(factory);
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
}
首先我们调用的是 SqlSession 的 selectList() 方法:
List<User> users = session.selectList("com.xfzhao.dao.UserDao.findAll");
因为 SqlSession 是接口,通过断点调试发现,真正的实现类的是 DefaultSqlSession
,其中有三个 selectList()
方法,最终都是走的最后一个三个参数的方法;
其中很关键的一步就是 this.executor.query(ms, this.wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
这里的 executor 是 CachingExecutor
// DefaultSqlSession 类
public <E> List<E> selectList(String statement) {
// 调用下面一个方法
return this.selectList(statement, (Object)null);
}
public <E> List<E> selectList(String statement, Object parameter) {
// 调用下面一个方法
return this.selectList(statement, parameter, RowBounds.DEFAULT);
}
// 真正执行的是这个方法
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
List var5;
try {
MappedStatement ms = this.configuration.getMappedStatement(statement);
// 走的是这里,这里的 executor 是 CachingExecutor
var5 = this.executor.query(ms, this.wrapCollection(parameter),
rowBounds, Executor.NO_RESULT_HANDLER);
} catch (Exception var9) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + var9, var9);
} finally {
ErrorContext.instance().reset();
}
return var5;
}
下面找到 CachingExecutor :
// CachingExecutor类
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
// 省略代码...
// 走的是这里,this.delegate 是 SimpleExecutor 类
return this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
然后我们去 SimpleExecutor 类中:
我们发现这个类中没有 query() 方法,只有 doQuery() 方法。于是我们就去找它的父类:BaseExecutor
public class SimpleExecutor extends BaseExecutor {...}
在 BaseExecutor 类中存在 query() 方法:而且存在两个query() 方法,我们直接看最后被调用的那一个
public <E> List<E> query(MappedStatement ms,
Object parameter, RowBounds rowBounds,
ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
//....省略其他
// 主要走的就是这一步: 执行 queryFromDatabase() 方法
list = this.queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
继续看 queryFromDatabase() 方法:
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
// ....
// 走的是这一步,执行的是抽象的 doQuery()方法
// 这里我们就知道了实际上绕了一圈还是走的是 simpleExecutor 的 doQuery() 方法
list = this.doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
// ....
}
最后我们再回去看 simpleExecutor 的 doQuery() 方法
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
Statement stmt = null;
List var9;
try {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(this.wrapper,
ms, parameter,
rowBounds,
resultHandler, boundSql);
stmt = this.prepareStatement(handler, ms.getStatementLog()); // 最后走的这一步:这里的 handler 是 RoutingStatementHandler
var9 = handler.query(stmt, resultHandler);
} finally {
this.closeStatement(stmt);
}
return var9;
}
现在来到了 RoutingStatementHandler 类中:查看它的 query() 方法:
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
// 走的这里:这里的delegate是 PrepareStatementHandler
return this.delegate.query(statement, resultHandler);
}
然后继续进入类: PrepareStatementHandler 中,查看 query() 方法:这里就是JDBC 的常规操作
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
// 到这里就很熟悉了,使用的是 prepareStatement对象
PreparedStatement ps = (PreparedStatement)statement;
// 执行的是它的 executor() 方法
ps.execute();
// 下面的步骤就是封装结果集
return this.resultSetHandler.handleResultSets(ps);
}
Mybatis中执行 findAll() 方法的详细执行步骤
标签:imp except 流程图 stat pool gate mysq database word
原文地址:https://www.cnblogs.com/xfzhao1419/p/14616532.html