手写一个MyBatis框架
MyBatis框架分析手写简单的MyBatis框架ConfigurationSqlSessionExecutorExecutorImpl
手写完整的MyBatis框架ExecutorExecutorImpl
MyBatis框架分析
MyBatis框架结构图: MyBatis框架组件调用关系图: MyBatis框架运行时序图:
手写简单的MyBatis框架
根据框架组件调用关系图开发Mybatis框架代码
一个组件实体就对应一个实体类
Configuration
public class Configuration {
public <T> T
getMapper(Class
<T> clazz
, SqlSession sqlSession
) {
return <T> Proxy
.newProxyInstance(this.getClass().getClassLoader(), new Class[]{clazz
}, new MapperProxy(sqlSession
));
}
}
SqlSession
public class SqlSession {
private Configuration configuration
;
private Executor executor
;
public SqlSession(Configuration configuration
, Executor executor
) {
this.configuration
= configuration
;
this.executor
= executor
;
}
public <T> getMapper(class<T> calzz
) {
return configuration
.getMapper(calzz
, this);
}
public <T> T
selectOne(String statement
, String parameter
) {
return executor
.query(statement
, parameter
);
}
}
Executor
public interface Executor {
<T> T
query(String statement
, String parameter
);
}
ExecutorImpl
public class ExecutorImpl implements Executor {
@Override
public <T> T
query(String statement
, String parameter
) {
Connection connection
= null
;
PreparedStatement preparedStatement
= null
;
try {
Class
.forName("com.mysql.cj.jdbc.Driver");
connection
= DriverManager
.getConnection("jdbc:mysql://127.0.0.1:3306/db?useUnicode=true&characterEncoding=utf-8");
String sql
= String
.format(statement
, Integer
.parseInt(parameter
));
PreparedStatement ps
= connection
.prepareStatement(sql
);
ResultSet rs
= ps
.executeQuery();
while (rs
.hasNext()) {
test
= new Test();
test
.setId(rs
.getInt(1));
test
.setNum(rs
.getInt(2));
test
.setName(rs
.getString(3));
}
} catch (ClassNotFoundException e
) {
e
.printStackTrace();
} finally {
try {
if (null
!= connection
) {
connection
.close();
}
} catch (SQLException e
) {
e
.printStackTrace();
}
}
return (T
)test
;
}
}
手写完整的MyBatis框架
简单的MyBatis框架中的Executor采用JDBC实现,采用了硬编码的方式,一次只能操作一张表:
...
while (rs
.hasNext()) {
test
= new Test();
test
.setId(rs
.getInt(1));
test
.setNum(rs
.getInt(2));
test
.setName(rs
.getString(3));
}
...
Executor
ExecutorImpl
public class ExecutorImpl implements Executor {
private Configuration configuration
;
public ExecutorImpl(Configuration configuration
) {
this.configuration
= configuration
;
}
public Configuration
getConfiguration() {
return configuration
;
}
public void setConfiguration(Configuration configuration
) {
this.configuration
= configuration
;
}
public <E> E
query(MapperRegistry
.MapperData
, Object parameter
) throws Exception
{
StatementHandler handler
= new StatementHandler(configuration
);
return (E
) handler
.query(mapperData
, parameter
);
}
}