mybatis interface programming principle

As we all know, mybatis implements interface programming, which simplifies the writing of our Dao layer. By defining an interface and an XMl file, the database sql can be executed. So how is it realistic? In fact, it uses the dynamic proxy of java.
Let's talk about the dynamic proxy mode first:
proxy mode: enhance the original function
1. Static proxy: Composition--->1. Abstract interface 2. Target object 3. Proxy object
Redefine a class to inherit this interface and define A reference to this interface, used to refer to the target object and call the original method
public abstract class AbstractObject {
    public abstract void operation();
}

target role
public class RealObject extends AbstractObject {
    @Override
    public void operation() {
        // some operations
        System.out.println("Some operations");
    }
}

Proxy Object Role
public class ProxyObject extends AbstractObject{
    RealObject realObject = new RealObject();
    @Override
    public void operation() {
        // You can do related operations before calling the target object
        System.out.println("before");        
        realObject.operation();        
        // You can do related operations after calling the target object
        System.out.println("after");
    }
}

client
public class Client {
    public static void main(String[] args) {
        AbstractObject obj = new ProxyObject();
        obj.operation();
    }

}

Second, dynamic proxy: each class has a virtual class proxy class, which only exists in memory
public class ProxyDemo {
	public static void main(String[] args) {
		//target
		final Dao demoDao = new DemoDao ();
		//The proxy object of the proxy class of the interface Dao
		Dao dao = (Dao)Proxy.newProxyInstance(ProxyDemo.class.getClassLoader(),
					new Class[]{Dao.class}, //Specify the proxy interface
					new InvocationHandler() {//Intercept all methods of the proxy object.

				@Override //proxy represents which method the proxy object itself method calls and which method object is referenced  
				//args The parameters of the calling method are encapsulated into objects and loaded into arrays
				public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
					//System.out.println(method.getName()+"    "+Arrays.toString(args));
					//1. Enhanced functionality
					System.out.println("-----There is a method to enter, the intercepted method is-----");
					//2. Call the original method of the target object
					//method.invoke(demoDao, args);
					return null;
				}
			});
			//System.out.println(dao); The tostring method is intercepted and always returns null
			//System.out.println(dao.getClass());
			//dao.add(10, 20);
			dao.equals("abc");
	
	}
}

The following explains how mybatis uses dynamic proxy to realize interface programming. First, only the interface is defined in mybatis. If you need to call the method in the interface, you must have a real class object, and use the dynamic proxy to create the implementation class object:
   MapperProxy implements InvocationHandler overrides the invoke() method in the class --> Proxy.newProxyInstance(class loader, interface.class array, MapperProxy object)-->sql Session.getMapper(interface.class) == Proxy.newProxyInstance()--> IMessage imessage = Proxy.newProxyInstance()
imessage.queryMessageList == MapperProxy.invoke();

According to the above process, Proxy.newProxyInstance() creates a proxy object, which can be regarded as the implementation class object of the interface, and MapperProxy intercepts the proxy object All the methods of the proxy object, that is to say, whatever method the proxy object executes will enter the invoke() method, which has an implementation class object.

Let 's talk about the methods in the proxy object execution interface. Why can the sql configured in xml be executed? This involves The rules of interface programming are now, and that's why these rules are set.
Loading mybatis configuration information configuratioon also loads Mapper's xml information --> because the full name of the interface. Method name = namespace.id --> so there is such code in MapperProxy.invoke(): sqlSession.selectList(namespace.id ,parameter) Decide whether to use selectOne or selectList according to the return value type

In this way, when we use the proxy object to call the method in the interface, the sqlSession.selectList method will be executed in the Mapper.invoke() method, that is, imessage.queryMessageList(parameter) = sqlSession.selectList(namespace.id, parameter), also Just execute the sql in our xml, which is why our namespace must be the fully qualified name of the interface, and the id of the sql must be the same as the method name in the interface.


                       

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326464094&siteId=291194637