手写MyBatis1.0框架

本文通过手写MyBatis1.0框架,解析其核心组件MSqlSession、MapperProxy及Executor的实现,重点讨论了如何利用Executor进行数据库操作。同时,文章指出MyBatis运用了代理模式,但不同于常规的代理实现类,而是代理接口。通过测试代码展示了XML配置的使用,并提供了相关实体类和启动类。
摘要由CSDN通过智能技术生成

在这里插入图片描述
我们要先了解需求和MyBatis实现的大体框架
在这里插入图片描述
代码:
MSqlSession代码:也是mybatis的核心,具有承上启下的作用

/**
 * 
 */
package com.matao.mybatis.sqlsession;

import java.lang.reflect.Proxy;

import com.matao.mybatis.config.MConfiguration;
import com.matao.mybatis.excuter.Executer;
import com.matao.mybatis.excuter.SimpleExecuter;
import com.matao.mybatis.mapper.MapperProxy;

public class MSqlSession {
	private MConfiguration configuration;
	private Executer<?> executer = new SimpleExecuter();
	
	
	public MConfiguration getConfiguration() {
		return configuration;
	}
	
	
/*	//构造方法
	public MSqlSession(MConfiguration configuration, Executer executer) {
		super();
		this.configuration = configuration;
		this.executer = executer;
	}*/
	//得到mapper对象
	
	public MSqlSession() {
		super();
		// TODO Auto-generated constructor stub
	}


	@SuppressWarnings("unchecked")
	public <T> T getMapper(Class<T> clazz){
		return (T) Proxy.newProxyInstance(clazz.getClassLoader(),
				new Class[]{clazz}, new MapperProxy<T>(this,clazz));
	}
	//实现查询方法
	@SuppressWarnings("unchecked")
	public <T> T selectOne(String statement,Object parameter){
		
		return (T) executer.query(statement, parameter);
	}

}

代理类 MapperProxy代码:

/**
 * 
 */
package com.matao.mybatis.mapper;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import com.matao.mybatis.sqlsession.MSqlSession;

/**
 * @author MT
 * @param <T>
 *
 */
public class MapperProxy<T> implements InvocationHandler{

	private final MSqlSession mSqlSession;
	private final Class<T> mapperInterface;
	/**
	 * @param <T>
	 * @param mSqlSession
	 * @param clazz
	 */
	public  MapperProxy(MSqlSession mSqlSession, Class<T> clazz) {
		this.mSqlSession = mSqlSession;
		this.mapperInterface = clazz;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		if (method.getDeclaringClass().getName().equals(TestMapperXml.nameSpace)) {
			String sql = TestMapperXml.methodSqlMapping.get(method.getName());
			System.out.println(sql);
			return mSqlSession.selectOne(sql, String.valueOf(args[0]));
		}
		return null;
	}

}

executer类代码:

/**
 * 
 */
package com.matao.mybatis.excuter;

/**
 * @author MT
 * @param <T>
 *
 */
public interface Executer<T> {

	/**
	 * @param statement
	 * @param parameter
	 * @return
	 */
	T query(String statement, Object parameter);

}

SimpleExecuter 代码:我们要知道mybatis操作数据库主要是executer进行操作

/**
 * 
 */
package com.matao.mybatis.excuter;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.matao.mybatis.Test;

/**
 * @author MT
 * @param <E>
 *
 */
public class SimpleExecuter<E> implements Executer{
	String driver = "com.mysql.jdbc.Driver";
	String username = "root";
	String password = "123456";
	String url = "jdbc:mysql://localhost:3310/test";

	
	@Override
	public  E query(String sql, Object parameter) {
		
		try {
			Connection conn = getConnection();
			
			PreparedStatement psStatement;
			
			psStatement = conn.prepareCall(String.format(sql, Integer.parseInt(String.valueOf(parameter))));
			ResultSet rs = psStatement.executeQuery();
			Test test = new Test();
			while(rs.next()){
				test.setId(rs.getInt(1));
				test.setAge(rs.getInt(2));
			}
			return (E) test;
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		return null;
	}

	/**
	 * @return
	 */
	private Connection getConnection() {
		Connection conn =null;
		try {
			Class.forName(driver);
			conn = DriverManager.getConnection(url, username, password);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}

}

测试代码:TestMapperXml 也就是我们用的xml用配的代码

/**
 * 
 */
package com.matao.mybatis.mapper;

import java.util.HashMap;
import java.util.Map;

/**
 * @author MT
 *
 */
public class TestMapperXml {
	public  static final String nameSpace = "com.matao.mybatis.mapper.TestMapper";
	public  static final Map<String, String> methodSqlMapping = new HashMap<String, String>();
	
	static{
		methodSqlMapping.put("selectByPrimaryKey", "select id,age from test where id = %d");
	}

}

TestMapper 代码:

/**
 * 
 */
package com.matao.mybatis.mapper;

import com.matao.mybatis.Test;

/**
 * @author MT
 *
 */
public interface TestMapper {
	Test selectByPrimaryKey(Integer userid);

}

实体类:

/**
 * 
 */
package com.matao.mybatis;

/**
 * @author MT
 *
 */
public class Test {
	private int id;
	private int age;
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Test [id=" + id + ", age=" + age + "]";
	}

}

启动类:

/**
 * 
 */
package com.matao.mybatis;

import com.matao.mybatis.mapper.TestMapper;
import com.matao.mybatis.sqlsession.MSqlSession;

/**
 * @author MT
 *
 */
public class BootStrap {
	public static void main(String[] args) {
		MSqlSession sqlSession = new MSqlSession();
		TestMapper mapper = sqlSession.getMapper(TestMapper.class);
		Test test = mapper.selectByPrimaryKey(1);
		System.out.println(test);
	}

}

结果:
在这里插入图片描述
在这里插入图片描述
总结;1.0很基础,但我们要了解mybatis也用jdbc查询数据库,里面也用了代理模式,具体代理模式是有实现类的,代理的是接口的实现模式,而mybatis比较有趣的一点就是代理模式没有代理实现类。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值