Mybatis

博客索引

大家使用的时候都知道#{}是起到一个占位符的作用,在JDBC中也就是对应的一个预编译,也就是对应JDBC中的PreparedStatement,源码中看到示例如下:

1
2
3
4
5
6
7
8
ini复制代码
PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES

SET SALARY = ? WHERE ID = ?");

pstmt.setBigDecimal(1, 153833.00)

pstmt.setInt(2, 110592)
  1. 猜想

所以Mybatis中的#{}是怎么完成预编译的效果呢?根据这里可以猜想,应该是Mybatis中将#{}最后解析成了占位符。

  1. 验证

那就写个例子来debug看一下,我们以查询为例

1
2
3
4
5
6
7
8
9
10
11
12
13
vbnet复制代码@Data

public class A {

private Integer id;

private Integer age;

private String name;

private Date createTime;

}

Mapper如下

1
2
3
4
5
6
7
8
9
10
java复制代码
@Mapper

public interface ADAO {

@Select("SELECT * FROM A WHERE id = #{id}")

A selectA(int id);

}

测试类ADAOTest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
less复制代码
@RunWith(SpringRunner.class)

@SpringBootTest

public class ADAOTest {

@Autowired

private ADAO adao;

@Test

public void selectA() {

A a = adao.selectA(2);

System.out.println(a);

}

@Select执行原理

这里只在关键地方打上断点,org.apache.ibatis.builder.SqlSourceBuilder#parse

占位符替换.png

已经完成了占位符?的替换,接下来就是获取PreparedStatement,在org.apache.ibatis.executor.SimpleExecutor#prepareStatement中。

这里的核心步骤已经标注出来了,有兴趣的话可以打个断点看看详细流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ini复制代码
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {

Statement stmt;

Connection connection = getConnection(statementLog);

// 在这一步中进行connect.prepareStatement(sql)

stmt = handler.prepare(connection, transaction.getTimeout());

// 这一步执行执行填充参数 stmt.setInt(1,"xxx");

handler.parameterize(stmt);

return stmt;

}

最后执行查询org.apache.ibatis.executor.statement.PreparedStatementHandler#query

1
2
3
4
5
6
7
8
9
10
scss复制代码
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {

PreparedStatement ps = (PreparedStatement) statement;

ps.execute();

return resultSetHandler.<E> handleResultSets(ps);

}
  1. 总结

猜想是对的,mybatis自定义的占位符#{} 最后被替换成JDBC的占位符?

所以,其实可以总结一下,其实所有的ORM框架,底层的原理都是JDBC的标准。

所以不管是Mybatis的占位符,还是JPA中的占位符,最终的执行流程都是解析成?这个占位符,别问为什么,问这就是标准。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%