美文网首页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