JDBC的使用
JDBC的使用方式相对比较繁琐:
public Object queryUser(int userId) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet rs = null;
try {
connection = dataSource.getConnection();
preparedStatement = connection.prepareStatement("select id, name from user where id = ?");
preparedStatement.setInt(1, userId);
rs = preparedStatement.executeQuery();
while (rs.next()) {
final int id = rs.getInt("id");
final String name = rs.getString("name");
final User user = new User();
user.setId(id);
user.setName(name);
return user;
}
return null;
} finally {
close(connection, preparedStatement, rs);
}
}
private void close(Connection connection, PreparedStatement preparedStatement, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
}
}
}
我们再定义两个类:
public class MyMappedStatement {
private String sql;
private List<Object> params;
public String getSql() {
return sql;
}
public void setSql(String sql) {
this.sql = sql;
}
public List<Object> getParams() {
return params;
}
public void setParams(List<Object> params) {
this.params = params;
}
}
public class ResultMap {
Object map(ResultSet rs) {
//省略
}
}
查询代码变成如下方式,实现了通用的查询:
public Object query(MyMappedStatement statement, MyResultMap resultMap) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet rs = null;
try {
connection = dataSource.getConnection();
preparedStatement = connection.prepareStatement(statement.getSql());
for (int i = 0; i < statement.getParams().size(); i++) {
Object p = statement.getParams().get(i);
preparedStatement.setObject(i + 1, p);
}
rs = preparedStatement.executeQuery();
return resultMap.map(rs);
} finally {
close(connection, preparedStatement, rs);
}
}
JDBC使用步骤
从上面可以看到,jdbc的使用步骤如下:
- 获取connection
- 创建PrespareStatement并绑定参数
- 执行查询/更新
- 执行结果集的映射
- 关闭资源
MyBatis的查询处理
核心概念
- MappedStatement:表示一条SQL,在xml中写的<select>/<update>或者注解写的@Select/@Update等都会在配置解析后转换成一个MappedStatement对象
- ResultMap:表示结果集到对象的映射,xml中写的<resultMap>或者注解写的@Results会转换成一个ResultMap
- Executor:MappedStatement的执行入口
领域模型划分
- 实体域:MappedStatement/ResultMap/Executor
- 服务域:Configuration(配置类)
处理步骤
MyBatis框架中封装的处理步骤大体上和前面使用JDBC是一样的,只是mybatis使用了更加抽象的方式:
![](https://img.haomeiwen.com/i18730055/b9d45eca32ec55cd.png)
从DefaultSqlSession类的selectList方法我们可以看到Executor的调用:
![](https://img.haomeiwen.com/i18730055/dd738feab1fd4875.png)
按上图的流程进去,会非常清晰的看明白整个处理过程,
创建核心处理类的过程
mybatis通过Configuration创建Executor, StatementHandler, ParameterHandler, ResultSetHandler, ResultHandler等对象,Configuration对象是配置解析之后表示 所有配置的对象,我们以Executor为例看看上述对象的创建过程:
![](https://img.haomeiwen.com/i18730055/eb6a2378f86a922c.png)
代码中有一行interceptorChain.pluginAll(executor),其作用是利用mybatis的插件创建代理对象,用于拦截核心流程:
![](https://img.haomeiwen.com/i18730055/be30a30ab9257ff2.png)
开发的mybatis插件就是通过这段代码应用在指定对象上的
mybatis插件开发见:https://mybatis.org/mybatis-3/configuration.html#plugins
网友评论