编程知识 cdmana.com

Alipay two faces: Mybatis interface, Mapper, why not overload it? I've been forced to

Dynamic proxy functions : Callback through interceptor method , To the goal target Methods to enhance .

The implication is to enhance the goal target Method . The above sentence is true , But don't think it's the truth , Little imagine , Dynamic agency and the hegemony of breaking the flow , Company target target No science fiction model .
notes : This paper assumes that , Readers understand the principle of dynamic agent , If you don't understand target The meaning of , It is difficult to understand this article , It is recommended to understand dynamic proxy first .

1. Customize JDK Automatic mapper based on dynamic proxy Mapper

So let's define a pojo.

public class User {
  private Integer id;
  private String name;
  private int age;

  public User(Integer id, String name, int age) {
    this.id = id;
    this.name = name;
    this.age = age;
  }
  // getter setter
} 

Define another interface UserMapper.java.

public interface UserMapper {
  public User getUserById(Integer id);  
} 

Next, let's look at how to use dynamic proxy to break the flow , Implement instantiation interface and call interface method to return data .

Customize a InvocationHandler.

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MapperProxy implements InvocationHandler {

  @SuppressWarnings("unchecked")
  public <T> T newInstance(Class<T> clz) {
    return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[] { clz }, this);
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (Object.class.equals(method.getDeclaringClass())) {
      try {
        //  Such as hashCode()、toString()、equals() Other methods , take target Point to current object this
        return method.invoke(this, args);
      } catch (Throwable t) {
      }
    }
    //  a big army 
    return new User((Integer) args[0], "zhangsan", 18);
  }
} 

In the above code target, In execution Object.java The internal method is ,target Was pointed to this,target Has become a puppet 、 Symbolize 、 Place holder . When you're trying to stop the flow , No more target.
Write a test code :

public static void main(String[] args) {
  MapperProxy proxy = new MapperProxy();

  UserMapper mapper = proxy.newInstance(UserMapper.class);
  User user = mapper.getUserById(1001);

  System.out.println("ID:" + user.getId());
  System.out.println("Name:" + user.getName());
  System.out.println("Age:" + user.getAge());

  System.out.println(mapper.toString());
} 

output:

ID:1001
Name:zhangsan
Age:18
x.y.MapperProxy@6bc7c054 

This is Mybatis Auto mapper Mapper The underlying implementation principle of .

Some readers may be tempted to ask : How do you write code like a beginner ? There is no structure , And lack of beauty .

You must declare , As an experienced master , Can write programs like beginners do , That must be the best of the best . This can make beginners feel kind , comfortable , According to their own Style, Let them or they , I feel that the code written by Daniel is just like this , I even wrote better than these big bulls , From then on, I was full of confidence , High enthusiasm , Think of the gap with Daniel , Only three minutes left .

2.Mybatis Auto mapper Mapper Source code analysis

First write a test class :

public static void main(String[] args) {
    SqlSession sqlSession = MybatisSqlSessionFactory.openSession();
    try {
      StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
      List<Student> students = studentMapper.findAllStudents();
      for (Student student : students) {
        System.out.println(student);
      }
    } finally {
      sqlSession.close();
    }
  } 

Mapper It looks like this :

public interface StudentMapper {
  List<Student> findAllStudents();
  Student findStudentById(Integer id);
  void insertStudent(Student student);
} 

org.apache.ibatis.binding.MapperProxy.java Part of the source code .

public class MapperProxy<T> implements InvocationHandler, Serializable {

  private static final long serialVersionUID = -6424540398559729838L;
  private final SqlSession sqlSession;
  private final Class<T> mapperInterface;
  private final Map<Method, MapperMethod> methodCache;

  public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
    this.sqlSession = sqlSession;
    this.mapperInterface = mapperInterface;
    this.methodCache = methodCache;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if (Object.class.equals(method.getDeclaringClass())) {
      try {
        return method.invoke(this, args);
      } catch (Throwable t) {
        throw ExceptionUtil.unwrapThrowable(t);
      }
    }
    //  a big army 
    final MapperMethod mapperMethod = cachedMapperMethod(method);
    return mapperMethod.execute(sqlSession, args);
  }
  // ... 

org.apache.ibatis.binding.MapperProxyFactory.java Part of the source code .

public class MapperProxyFactory<T> {

  private final Class<T> mapperInterface;

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  } 

This is Mybatis Using dynamic proxy to break the flow .

3. Interface Mapper Methods within can overload (overLoad) Do you ?( important )

It's like this :

public User getUserById(Integer id);
public User getUserById(Integer id, String name); 

Answer: You can't .

reason : When the current is broken ,Mybatis Use package+Mapper+method All names are limited to key, Go to xml Looking for the only sql To perform the . similar :key=x.y.UserMapper.getUserById, that , Overloading methods can lead to conflicts . about Mapper Interface ,Mybatis Method overloading is prohibited (overLoad).

notes : When studying , Is the source code of the first study , Understand the principle . When blogging , Then explain the principle first , Read the source code again . The order is just the opposite , I hope readers don't have any doubts about it , Think I'm strong enough to know .

author : Zu Dajun
source :my.oschina.net/zudajun/blog/666223
 Insert picture description here

Welcome to my WeChat official account. 「 Manon break through 」, Share Python、Java、 big data 、 machine learning 、 Artificial intelligence and other technologies , Pay attention to the improvement of code farming technology • Breakthrough in the workplace • Mind leaps ,20 ten thousand + The first station of manong's growth and charging , Grow up with you who have dreams

版权声明
本文为[Manong's breakthrough]所创,转载请带上原文链接,感谢

Scroll to Top