纯手写mybatis源码

纯手写mybatis源码_第1张图片

entity:

package com.itmayiedu.entity;

public class User {

	private Integer id;
	private String userName;
	private Integer userAge;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public Integer getUserAge() {
		return userAge;
	}

	public void setUserAge(Integer userAge) {
		this.userAge = userAge;
	}

	public Integer getId() {
		return id;
	}

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

}

mapper

package com.itmayiedu.mapper;

import java.util.List;

import com.itmayiedu.entity.User;
import com.itmayiedu.orm.annotation.ExtInsert;
import com.itmayiedu.orm.annotation.ExtParam;
import com.itmayiedu.orm.annotation.ExtSelect;

public interface UserMapper {

	@ExtInsert("insert into user(userName,userAge) values(#{userName},#{userAge})")
	public int insertUser(@ExtParam("userName") String userName, @ExtParam("userAge") Integer userAge);

	@ExtSelect("select * from User where userName=#{userName} and userAge=#{userAge} ")
	User selectUser(@ExtParam("userName") String name, @ExtParam("userAge") Integer userAge);

}

纯手写mybatis源码_第2张图片
纯手写mybatis源码_第3张图片

package com.itmayiedu.orm.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义插入注解 
* 作者: 每特教育-余胜军
* 联系方式:QQ644064779|WWW.itmayiedu.com
*/ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ExtInsert { String value(); }
package com.itmayiedu.orm.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义参数注解
* 作者: 每特教育-余胜军
* 联系方式:QQ644064779|WWW.itmayiedu.com
*/ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface ExtParam { String value(); }
package com.itmayiedu.orm.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExtSelect {

	String value();

}

纯手写mybatis源码_第4张图片

package com.itmayiedu.orm.mybatis.aop;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import com.itmayiedu.orm.annotation.ExtInsert;
import com.itmayiedu.orm.annotation.ExtParam;
import com.itmayiedu.orm.annotation.ExtSelect;
import com.itmayiedu.orm.utils.JDBCUtils;
import com.itmayiedu.utils.SQLUtils;

/**
 * 使用反射动态代理技术 拦截接口防范 作者: 每特教育-余胜军
* 联系方式:QQ644064779|WWW.itmayiedu.com
*/ public class MyInvocationHandlerMbatis implements InvocationHandler { private Object object; public MyInvocationHandlerMbatis(Object object) { this.object = object; } // proxy 代理对象 method拦截方法 args方法上的参数值 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("使用动态代理技术拦截接口方法开始"); // 使用白话问翻译,@ExtInsert封装过程 // 1. 判断方法上是否存在@ExtInsert ExtInsert extInsert = method.getDeclaredAnnotation(ExtInsert.class); if (extInsert != null) { return extInsert(extInsert, proxy, method, args); } // 2.查询的思路 // 1. 判断方法上是否存 在注解 ExtSelect extSelect = method.getDeclaredAnnotation(ExtSelect.class); if (extSelect != null) { // 2. 获取注解上查询的SQL语句 String selectSQL = extSelect.value(); // 3. 获取方法上的参数,绑定在一起 ConcurrentHashMap paramsMap = paramsMap(proxy, method, args); // 4. 参数替换?传递方式 List sqlSelectParameter = SQLUtils.sqlSelectParameter(selectSQL); // 5.传递参数 List sqlParams = new ArrayList<>(); for (String parameterName : sqlSelectParameter) { Object parameterValue = paramsMap.get(parameterName); sqlParams.add(parameterValue); } // 6.将sql语句替换成? String newSql = SQLUtils.parameQuestion(selectSQL, sqlSelectParameter); System.out.println("newSQL:" + newSql + ",sqlParams:" + sqlParams.toString()); // 5.调用jdbc代码底层执行sql语句 // 6.使用反射机制实例对象### 获取方法返回的类型,进行实例化 // 思路: // 1.使用反射机制获取方法的类型 // 2.判断是否有结果集,如果有结果集,在进行初始化 // 3.使用反射机制,给对象赋值 ResultSet res = JDBCUtils.query(newSql, sqlParams); // 判断是否存在值 if (!res.next()) { return null; } // 下标往上移动移位 res.previous(); // 使用反射机制获取方法的类型 Class returnType = method.getReturnType(); Object object = returnType.newInstance(); while (res.next()) { // 获取当前所有的属性 Field[] declaredFields = returnType.getDeclaredFields(); for (Field field : declaredFields) { String fieldName = field.getName(); Object fieldValue = res.getObject(fieldName); field.setAccessible(true); field.set(object, fieldValue); } // for (String parameteName : sqlSelectParameter) { // // 获取参数值 // Object resultValue = res.getObject(parameteName); // // 使用java的反射值赋值 // Field field = returnType.getDeclaredField(parameteName); // // 私有方法允许访问 // field.setAccessible(true); // field.set(object, resultValue); // } } return object; } return null; } private Object extInsert(ExtInsert extInsert, Object proxy, Method method, Object[] args) { // 方法上存在@ExtInsert,获取他的SQL语句 // 2. 获取SQL语句,获取注解Insert语句 String insertSql = extInsert.value(); // System.out.println("insertSql:" + insertSql); // 3. 获取方法的参数和SQL参数进行匹配 // 定一个一个Map集合 KEY为@ExtParamValue,Value 结果为参数值 ConcurrentHashMap paramsMap = paramsMap(proxy, method, args); // 存放sql执行的参数---参数绑定过程 String[] sqlInsertParameter = SQLUtils.sqlInsertParameter(insertSql); List sqlParams = sqlParams(sqlInsertParameter, paramsMap); // 4. 根据参数替换参数变为? String newSQL = SQLUtils.parameQuestion(insertSql, sqlInsertParameter); System.out.println("newSQL:" + newSQL + ",sqlParams:" + sqlParams.toString()); // 5. 调用jdbc底层代码执行语句 return JDBCUtils.insert(newSQL, false, sqlParams); } private List sqlParams(String[] sqlInsertParameter, ConcurrentHashMap paramsMap) { List sqlParams = new ArrayList<>(); for (String paramName : sqlInsertParameter) { Object paramValue = paramsMap.get(paramName); sqlParams.add(paramValue); } return sqlParams; } private ConcurrentHashMap paramsMap(Object proxy, Method method, Object[] args) { ConcurrentHashMap paramsMap = new ConcurrentHashMap<>(); // 获取方法上的参数 Parameter[] parameters = method.getParameters(); for (int i = 0; i < parameters.length; i++) { Parameter parameter = parameters[i]; ExtParam extParam = parameter.getDeclaredAnnotation(ExtParam.class); if (extParam != null) { // 参数名称 String paramName = extParam.value(); Object paramValue = args[i]; // System.out.println(paramName + "," + paramValue); paramsMap.put(paramName, paramValue); } } return paramsMap; } public Object extInsertSQL() { return object; } }
package com.itmayiedu.orm.mybatis.aop;

import com.itmayiedu.entity.User;
import com.itmayiedu.mapper.UserMapper;
import com.itmayiedu.sql.SqlSession;

public class Test0003 {

	public static void main(String[] args) {
		// 使用动态代理技术虚拟调用方法
		UserMapper userMapper = SqlSession.getMapper(UserMapper.class);
		User selectUser = userMapper.selectUser("张三", 644064);
		System.out.println(
				"结果:" + selectUser.getUserName() + "," + selectUser.getUserAge() + ",id:" + selectUser.getId());
		// // 先走拦截invoke
		// int insertUserResult = userMapper.insertUser("张三", 644064);
		// System.out.println("insertUserResult:" + insertUserResult);
	}

}

纯手写mybatis源码_第5张图片

package com.itmayiedu.sql;

import java.lang.reflect.Proxy;

import com.itmayiedu.orm.mybatis.aop.MyInvocationHandlerMbatis;

public class SqlSession {

	// 加载Mapper接口
	public static  T getMapper(Class classz) {
		return (T) Proxy.newProxyInstance(classz.getClassLoader(), new Class[] { classz },
				new MyInvocationHandlerMbatis(classz));
	}

}

你可能感兴趣的:(mybatis)