MyBatis动态代理运行

一、mybatis的运行流程

我们知道使用mybatis的时候,一般是一个接口对应一个xml文件,那么我们的mybatis是怎样通过这个接口来调用并且xml当中的方法的呢?

下面我么简单的说一下mybatis的工作流程

1.项目启动时根据xml文件路径读取所有的xml信息,到map中存储,map的key可以定义为类名+方法名。

2.编写代理类,代理类负责根据被代理的类名+方法名,读取对应的sql配置,然后根据入参,拼接解析出完整sql,然后交给jdbc去执行,最后将返回数据转换成接口返回值的对象做返回。

3.根据dao的包路径读取所有的需要代理的dao对象,利用上面第二条写的代理类来循环为每个dao创建代理类。

二、代码执行

1.编写接口类

public interface UserDao { public List<User> findAll(); }

2.编写代理类

public class MybatisProxy implements InvocationHandler {

    private final static String URL = "jdbc:mysql://localhost:3306/student";
    private final static String ROOT = "root";
    private final static String PASSWORD = "2020";
    private final static Map<String,String> XML_MAP_SQL = new HashMap<String, String>();

    //加载被代理的对象,这里我们需要读取xml配置文件
    static {
        //这里我们模拟读取xml文件当中的方法名和sql语句
        XML_MAP_SQL.put("findAll","select * from user");
    }

    // 要求代理对象要完成的功能
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String name =  method.getName();
        // 从map中读取
        String sql = MybatisProxy.XML_MAP_SQL.get(name);
        // 执行目标类当中的方法,在这里我们使用jdbc实现
        search(sql);
        return null;
    }

    // jdbc执行的方法
    public void search(String sql) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");  //加载驱动
        Connection connection = (Connection) DriverManager.getConnection(URL,ROOT,PASSWORD);  //建立和保持数据库的连接
        Statement statment = (Statement) connection.createStatement();  //创建statment
        ResultSet set = statment.executeQuery(sql);

        while (set.next()) {
            System.out.print(set.getString("id")+" ");
            System.out.print(set.getString("name")+" " );
            System.out.print(set.getString("phone")+" " );
            System.out.println("  ");
        }
        statment.close();
        connection.close();
    }

    //该方法并不是固定的,但是内部的Proxy类的创建是核心
    public Object getProxyInstance(Class clazz) {
        // TODO Auto-generated method stub
        return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, this);
    }
}

3.测试类

public class Test {
    public static void main(String[] args) {
        MybatisProxy mybatisProxy = new MybatisProxy();
        UserDao userDao = (UserDao) mybatisProxy.getProxyInstance(UserDao.class);
        userDao.findAll();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_53818758/article/details/130377283