手写一个MyBatis框架

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;

	/**
	 * 通过构造函数建立Configuration以及Executor和SqlSession的关系
	 */
	public SqlSession(Configuration configuration, Executor executor) {
		this.configuration = configuration;
		this.executor = executor;
	}

	/**
	 * getMapper
	 * @param clazz
	 */
	 public <T> getMapper(class<T> calzz) {
	 	return configuration.getMapper(calzz, this);
	 }

	/**
	 * selectOne
	 *  
	 * @param statement SQL语句
	 * @param parameter SQL参数
	 * @return <T> T 查询结果
	 */
	 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
		 */
		 StatementHandler handler = new StatementHandler(configuration);
		 return (E) handler.query(mapperData, parameter);
	}
}

猜你喜欢

转载自blog.csdn.net/JewaveOxford/article/details/107058064