mybatis源码-执行器

  作者:记性不好的阁主



执行查询:


1、简单执行器SimpleExecutor:


private static void simpleExecutorTest() throws SQLException, IOException {

String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
Configuration configuration = sqlSessionFactory.getConfiguration();
Connection connection = DriverManager.getConnection(
"jdbc:mysql://ip:3306/mybatis?serverTimezone=UTC","user","pwd"
);
JdbcTransaction jdbcTransaction = new JdbcTransaction(connection);
SimpleExecutor executor = new SimpleExecutor(configuration, jdbcTransaction);
MappedStatement ms = configuration.getMappedStatement("com.laoxu.mybatis.mapper.PersonMapper.getPersonById");
List<Object> objects = executor.doQuery(
ms,
"20210420172645864088a2a1ba11eb886d525400146075",
RowBounds.DEFAULT,
SimpleExecutor.NO_RESULT_HANDLER,
ms.getBoundSql("20210420172645864088a2a1ba11eb886d525400146075")
);
System.out.println(objects);

}




再一模一样的查询一次


private static void simpleExecutorTest() throws SQLException, IOException {

String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
Configuration configuration = sqlSessionFactory.getConfiguration();
Connection connection = DriverManager.getConnection(
"jdbc:mysql://ip:3306/mybatis?serverTimezone=UTC","user","pwd"
);
JdbcTransaction jdbcTransaction = new JdbcTransaction(connection);
SimpleExecutor executor = new SimpleExecutor(configuration, jdbcTransaction);
MappedStatement ms = configuration.getMappedStatement("com.laoxu.mybatis.mapper.PersonMapper.getPersonById");
List<Object> objects = executor.doQuery(
ms,
"20210420172645864088a2a1ba11eb886d525400146075",
RowBounds.DEFAULT,
SimpleExecutor.NO_RESULT_HANDLER,
ms.getBoundSql("20210420172645864088a2a1ba11eb886d525400146075")
);
executor.doQuery(
ms,
"20210420172645864088a2a1ba11eb886d525400146075",
RowBounds.DEFAULT,
SimpleExecutor.NO_RESULT_HANDLER,
ms.getBoundSql("20210420172645864088a2a1ba11eb886d525400146075")
);
System.out.println(objects);

}


==>  Preparing: select * from person where id = ?
==> Parameters: 20210420172645864088a2a1ba11eb886d525400146075(String)
<==    Columns: id, name, sex, age, create_time
<==        Row: 20210420172645864088a2a1ba11eb886d525400146075, 李四, 1, 20, 2021-04-20 17:26:45
<==      Total: 1
==>  Preparing: select * from person where id = ?
==> Parameters: 20210420172645864088a2a1ba11eb886d525400146075(String)
<==    Columns: id, name, sex, age, create_time
<==        Row: 20210420172645864088a2a1ba11eb886d525400146075, 李四, 1, 20, 2021-04-20 17:26:45
<==      Total: 1
[Person{id='20210420172645864088a2a1ba11eb886d525400146075', name='李四', sex='1', age='20', createTime='2021-04-20 17:26:45'}]





2、可重用执行器ReuseExecutor


private static void reuseExecutorTest() throws SQLException, IOException {

String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
Configuration configuration = sqlSessionFactory.getConfiguration();
Connection connection = DriverManager.getConnection(
"jdbc:mysql://www.aimaboge.com:3306/mybatis?serverTimezone=UTC","root","password"
);
JdbcTransaction jdbcTransaction = new JdbcTransaction(connection);
ReuseExecutor executor = new ReuseExecutor(configuration, jdbcTransaction);
MappedStatement ms = configuration.getMappedStatement("com.laoxu.mybatis.mapper.PersonMapper.getPersonById");
List<Object> objects = executor.doQuery(
ms,
"20210420172645864088a2a1ba11eb886d525400146075",
RowBounds.DEFAULT,
SimpleExecutor.NO_RESULT_HANDLER,
ms.getBoundSql("20210420172645864088a2a1ba11eb886d525400146075")
);
executor.doQuery(
ms,
"20210420172645864088a2a1ba11eb886d525400146075",
RowBounds.DEFAULT,
SimpleExecutor.NO_RESULT_HANDLER,
ms.getBoundSql("20210420172645864088a2a1ba11eb886d525400146075")
);
System.out.println(objects);

}



==>  Preparing: select * from person where id = ?
==> Parameters: 20210420172645864088a2a1ba11eb886d525400146075(String)
<==    Columns: id, name, sex, age, create_time
<==        Row: 20210420172645864088a2a1ba11eb886d525400146075, 李四, 1, 20, 2021-04-20 17:26:45
<==      Total: 1
==> Parameters: 20210420172645864088a2a1ba11eb886d525400146075(String)
<==    Columns: id, name, sex, age, create_time
<==        Row: 20210420172645864088a2a1ba11eb886d525400146075, 李四, 1, 20, 2021-04-20 17:26:45
<==      Total: 1
[Person{id='20210420172645864088a2a1ba11eb886d525400146075', name='李四', sex='1', age='20', createTime='2021-04-20 17:26:45'}]


重用执行器如果sql一样,那么只预编译一次


3、批处理执行器BatchExecutor


只针对修改操作,对于查询操作与简单执行器SimpleExecutor无异




private static void batchExecutorTest() throws SQLException, IOException {

String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
Configuration configuration = sqlSessionFactory.getConfiguration();
Connection connection = DriverManager.getConnection(
"jdbc:mysql://ip:3306/mybatis?serverTimezone=UTC","user","pwd"
);
JdbcTransaction jdbcTransaction = new JdbcTransaction(connection);
BatchExecutor executor = new BatchExecutor(configuration, jdbcTransaction);
MappedStatement ms = configuration.getMappedStatement("com.laoxu.mybatis.mapper.PersonMapper.updatePersonNameById");
Map<String, String> param = new HashMap<>();
param.put("name", "王五");
param.put("id", "20210420172645864088a2a1ba11eb886d525400146075");
executor.doUpdate(ms, param);
executor.doUpdate(ms, param);

}



==>  Preparing: update set name = ? from person where id = ?
==> Parameters: 王五(String), 20210420172645864088a2a1ba11eb886d525400146075(String)
==> Parameters: 王五(String), 20210420172645864088a2a1ba11eb886d525400146075(String)


对于修改操作只预编译了一次




执行后,查看数据库未发生更新,是因为没有批处理刷新,需执行executor.doFlushStatements(false);进行刷新


private static void batchExecutorTest() throws SQLException, IOException {

String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
Configuration configuration = sqlSessionFactory.getConfiguration();
Connection connection = DriverManager.getConnection(
"jdbc:mysql://ip:3306/mybatis?serverTimezone=UTC","user","pwd"
);
JdbcTransaction jdbcTransaction = new JdbcTransaction(connection);
BatchExecutor executor = new BatchExecutor(configuration, jdbcTransaction);
MappedStatement ms = configuration.getMappedStatement("com.laoxu.mybatis.mapper.PersonMapper.updatePersonNameById");
Map<String, String> param = new HashMap<>();
param.put("name", "王五");
param.put("id", "20210420172645864088a2a1ba11eb886d525400146075");
executor.doUpdate(ms, param);
executor.doUpdate(ms, param);
executor.doFlushStatements(false);
}


再次查看数据库,可以看到已经更新





4、基础执行器BaseExecutor


private static void baseExecutorTest() throws SQLException, IOException {

String resource = "mapper/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
Configuration configuration = sqlSessionFactory.getConfiguration();
Connection connection = DriverManager.getConnection(
"jdbc:mysql://ip:3306/mybatis?serverTimezone=UTC","user","pwd"
);
JdbcTransaction jdbcTransaction = new JdbcTransaction(connection);
BaseExecutor executor = new SimpleExecutor(configuration, jdbcTransaction);
MappedStatement ms = configuration.getMappedStatement("com.laoxu.mybatis.mapper.PersonMapper.getPersonById");
executor.query(ms, "20210420172645864088a2a1ba11eb886d525400146075", RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);
executor.query(ms, "20210420172645864088a2a1ba11eb886d525400146075", RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);

}


只预编译了一次,只查询了一次,这就是走了一级缓存


==>  Preparing: select * from person where id = ?
==> Parameters: 20210420172645864088a2a1ba11eb886d525400146075(String)
<==    Columns: id, name, sex, age, create_time
<==        Row: 20210420172645864088a2a1ba11eb886d525400146075, 李四, 1, 20, 2021-04-20 17:26:45
<==      Total: 1


第一次查询进行创建缓存的key:



执行query查询方法:



尝试获取缓存,如果没有获取到就置null


list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;


如果为null那么直接查询数据库:



可以看到查询数据库方法中进行了缓存:


localCache.putObject(key, EXECUTION_PLACEHOLDER);


当下次查询的时候,直接查询缓存返回


总结:




涉及到的模式:






相关推荐

评论 抢沙发

表情

分类选择