MyBatis dynamic proxy running

1. The operation process of mybatis

We know that when using mybatis, generally an interface corresponds to an xml file, so how does our mybatis call the method in xml through this interface?

Let me briefly talk about the workflow of mybatis

1. When the project starts, read all the xml information according to the xml file path and store it in the map. The key of the map can be defined as the class name + method name.

2. Write the proxy class. The proxy class is responsible for reading the corresponding sql configuration according to the proxied class name + method name, and then splicing and parsing the complete sql according to the input parameters, and then handing it over to jdbc for execution, and finally converting the returned data into The object of the interface return value is returned.

3. Read all the dao objects that need to be proxied according to the dao package path, and use the proxy class written in the second item above to create a proxy class for each dao in a loop.

2. Code execution

1. Write the interface class

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

2. Write proxy class

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. Test class

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