如何自己实现MyBatis框架,探究其中原理

通过本章节的学习,对mybatis的一级缓存,mapper接口没有实现类底层是如何处理的 xml的处理 有所了解

1.自定义实体类

public class Admin implements Serializable{

	private String id;
	
	private String aname;
	
	private String password;
	
	private String phone;
	
	public Admin(){
		
	}

	public Admin(String id, String aname, String password, String phone) {
		super();
		this.id = id;
		this.aname = aname;
		this.password = password;
		this.phone = phone;
	}

	public String getId() {
		return id;
	}

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

	public String getAname() {
		return aname;
	}

2.自定义mapper接口

public interface AdminMapper {

	public List<Admin> queryAll();
	
}

3.jdbc工具类

JDBC工具类大家都很熟悉,我没有太优化
public class JDBCUtil {

	private static Connection con = null;
	
	private static PreparedStatement ps = null;
	
	private static ResultSet rs = null;
	
	static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
			String url = "jdbc:mysql://127.0.0.1:3306/stu?useUnicode=true&characterEncoding=utf-8";
			String name = "root";
			String pwd = "";
			con = DriverManager.getConnection(url,name,pwd);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static Connection getCon(){
		return con;
	}
	
	
	
}

4.自定义AdminMapper.xml配置文件

本次只是演示无参的select,有参的 需要的可以再写出来

<?xml version="1.0" encoding="UTF-8" ?>
<mapper namespace="com.mapper.AdminMapper">
	<select id="queryAll">
		select id,aname,apwd,phone from tb_admin
	</select>
	<select id="queryById">
		select id,aname,apwd,phone from tb_admin where id = #{id}
	</select>
</mapper>

5.xml解析工具类

public class XMLParser {

	public static Map<String,String> getSqlMap(){
		Map<String,String> map = new HashMap<String, String>();
		
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document doc = builder.parse("E:/AdminMapper.xml");
			NodeList list = doc.getElementsByTagName("select");
			for(int i = 0 ;i<list.getLength();i++){
				Element e = (Element) list.item(i);
				String id = e.getAttribute("id");
				String sql = e.getTextContent().trim();
				map.put(id, sql);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}
	
	public static void main(String[] args) {
		getSqlMap();
	}
	
}

6.代理类

public class MapperProxy implements InvocationHandler{

	//类似于sqlsession 缓存
	private static Map<String,Object> cachedmap = new HashMap<String, Object>();
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		//定义要返回的结果
		
		List<Admin> alist = (List<Admin>) cachedmap.get(method.getName());
		if(alist != null && alist.size()>0){
			System.out.println("第二次进来 从缓存获取");
			return alist;
		}else{
			
			List<Admin> list = new ArrayList<>();
			
			//System.out.println(method.getName());
			String methodName = method.getName();
			//1.解析xml
			Map<String,String> map = XMLParser.getSqlMap();
			String sql = map.get(methodName);
			
			System.out.println("第一次进来 :");
			System.out.println(sql);
			
			//2.执行sql
			Connection con = JDBCUtil.getCon();
			PreparedStatement ps = con.prepareStatement(sql);
			ResultSet rs = ps.executeQuery();
			while(rs.next()){
				String id = rs.getString("id");
				String aname = rs.getString("aname");
				String apwd = rs.getString("apwd");
				String phone = rs.getString("phone");
				
				Admin admin = new Admin(id, aname, apwd, phone);
				list.add(admin);
			}
			
			cachedmap.put(methodName, list);
			
			rs.close();
			ps.close();
			con.close();
			return list;
		}
		
		
		
	}
	
	//我们肯定要得到代理的对象<T>泛型  
	//inter 就是对应的要处理的接口
	public static <T> T getMapper(Class<T> inter){
		ClassLoader classloader = inter.getClassLoader();//拿到接口的 类加载器
		
		Class<T>[] inters = new Class[]{inter};//只是转成数组的格式
		
		MapperProxy proxy = new MapperProxy();
		
		//classloader加载器  inters需要的接口  proxy要处理的方法
		return (T) Proxy.newProxyInstance(classloader, inters, proxy);
	}
}

7.测试类

public class Test {

	public static void main(String[] args) {
		
		//返回的就是 处理接口的代理类
		AdminMapper adminMapper = MapperProxy.getMapper(AdminMapper.class);
		List<Admin> list1 = adminMapper.queryAll();//回调invoke方法
		System.out.println(list1.size());
		
		//相同的查询不会再执行sql了,从缓存了获取
		List<Admin> list2 = adminMapper.queryAll();//回调invoke方法
		System.out.println(list2.size());
	}
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤独地卜师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值