美文网首页spring 相关
MyBatis(五): 手写Insert

MyBatis(五): 手写Insert

作者: aix91 | 来源:发表于2019-01-28 10:06 被阅读0次

1. 定义Mapper接口

public interface ExtMapper {
    @ExtInsert("insert into mybatis(name,age) values (#{user.getName},#{user.getAge})")
    void insert(@ExtParam("user") User user);

    @ExtSelect("select name,age from mybatis where name=#{name}")
    User select(@ExtParam("name") String name);
}

2. 动态代理执行Mapper接口方法

  • 自定义InvocationHandler
public class MyInvocationHandler<T> implements InvocationHandler {
    ...
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        extInsert(proxy, method, args);
        return extSelect(proxy, method, args);
    }
    ...
}
  • 自定义insert执行方法
private int extInsert(Object proxy, Method method, Object[] args) {

        //判断方法是否使用来了ExtInsert注解
        ExtInsert insertAnnotation = method.getAnnotation(ExtInsert.class);

        if (insertAnnotation != null) {
            String sql = insertAnnotation.value();

            //用于存储方法的参数名字,参数值的键值对
            Map<Object, Object> paramMap = new ConcurrentHashMap();
            getMethodParameterMap(method, args, paramMap);

            //找到sql语句中的变量名
            String[] insertParams = SQLUtils.sqlInsertParameter(sql);

            //获取变量的值
            List params = Arrays.stream(insertParams).map(param -> {
                String objName = param.split("\\.")[0].trim();
                String methodName = param.split("\\.")[1];

                Object obj = paramMap.get(objName);

                Object getValue = null;
                //使用反射,调用get方法获取属性值
                try {
                    getValue = obj.getClass().getMethod(methodName).invoke(obj);
                    return getValue;
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                return getValue;
            }).collect(Collectors.toList());

            //用问号代替sql语句中的变量
            String newSql = SQLUtils.parameQuestion(sql, insertParams);
            System.out.println(newSql);

            //执行sql语句
            int r = JDBCUtils.insert(newSql, false, params);
            return r;
        }
        return -1;
    }
  • 测试方法
public class CustomDemo {

    static public void main(String[] args) {
        InvocationHandler insertHandler = new MyInvocationHandler<>(ExtMapper.class);
        //动态代理创建Mapper对象
        ExtMapper extMapper = (ExtMapper) Proxy.newProxyInstance(ExtMapper.class.getClassLoader(),
                new Class<?>[]{ExtMapper.class}, insertHandler);
        User user = new User();
        user.setAge(13);
        user.setName("peggi");
        extMapper.insert(user);
    }
}

相关文章

网友评论

    本文标题:MyBatis(五): 手写Insert

    本文链接:https://www.haomeiwen.com/subject/wowojqtx.html